@oyolincc/create 0.2.1 → 0.3.0
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/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -1
- package/templates/hono-fullstack/.agents/skills/ask-matt/PHASE-BOUNDARIES.md +55 -0
- package/templates/hono-fullstack/.agents/skills/ask-matt/SKILL.md +90 -0
- package/templates/hono-fullstack/.agents/skills/ask-matt/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/code-review/SKILL.md +87 -0
- package/templates/hono-fullstack/.agents/skills/code-review/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/codebase-design/DEEPENING.md +37 -0
- package/templates/hono-fullstack/.agents/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/templates/hono-fullstack/.agents/skills/codebase-design/SKILL.md +114 -0
- package/templates/hono-fullstack/.agents/skills/codebase-design/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/confirm-requirements/SKILL.md +25 -0
- package/templates/hono-fullstack/.agents/skills/diagnosing-bugs/SKILL.md +140 -0
- package/templates/hono-fullstack/.agents/skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
- package/templates/hono-fullstack/.agents/skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/templates/hono-fullstack/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/templates/hono-fullstack/.agents/skills/domain-modeling/SKILL.md +74 -0
- package/templates/hono-fullstack/.agents/skills/domain-modeling/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/grill-me/SKILL.md +7 -0
- package/templates/hono-fullstack/.agents/skills/grill-me/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/grilling/SKILL.md +22 -0
- package/templates/hono-fullstack/.agents/skills/grilling/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/implement/SKILL.md +15 -0
- package/templates/hono-fullstack/.agents/skills/implement/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
- package/templates/hono-fullstack/.agents/skills/improve-codebase-architecture/SKILL.md +71 -0
- package/templates/hono-fullstack/.agents/skills/improve-codebase-architecture/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/prototype/LOGIC.md +67 -0
- package/templates/hono-fullstack/.agents/skills/prototype/SKILL.md +26 -0
- package/templates/hono-fullstack/.agents/skills/prototype/UI.md +112 -0
- package/templates/hono-fullstack/.agents/skills/prototype/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/research/SKILL.md +12 -0
- package/templates/hono-fullstack/.agents/skills/research/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/resolving-merge-conflicts/SKILL.md +14 -0
- package/templates/hono-fullstack/.agents/skills/resolving-merge-conflicts/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/scoped-code-review/SKILL.md +113 -0
- package/templates/hono-fullstack/.agents/skills/setup-matt-pocock-skills/SKILL.md +116 -0
- package/templates/hono-fullstack/.agents/skills/setup-matt-pocock-skills/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/setup-matt-pocock-skills/domain.md +51 -0
- package/templates/hono-fullstack/.agents/skills/setup-matt-pocock-skills/issue-tracker-github.md +45 -0
- package/templates/hono-fullstack/.agents/skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +46 -0
- package/templates/hono-fullstack/.agents/skills/setup-matt-pocock-skills/issue-tracker-local.md +30 -0
- package/templates/hono-fullstack/.agents/skills/setup-matt-pocock-skills/triage-labels.md +15 -0
- package/templates/hono-fullstack/.agents/skills/tdd/SKILL.md +38 -0
- package/templates/hono-fullstack/.agents/skills/tdd/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/tdd/mocking.md +59 -0
- package/templates/hono-fullstack/.agents/skills/tdd/tests.md +77 -0
- package/templates/hono-fullstack/.agents/skills/teach/GLOSSARY-FORMAT.md +35 -0
- package/templates/hono-fullstack/.agents/skills/teach/LEARNING-RECORD-FORMAT.md +46 -0
- package/templates/hono-fullstack/.agents/skills/teach/MISSION-FORMAT.md +31 -0
- package/templates/hono-fullstack/.agents/skills/teach/RESOURCES-FORMAT.md +32 -0
- package/templates/hono-fullstack/.agents/skills/teach/SKILL.md +140 -0
- package/templates/hono-fullstack/.agents/skills/teach/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/to-questionnaire/SKILL.md +53 -0
- package/templates/hono-fullstack/.agents/skills/to-questionnaire/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/triage/AGENT-BRIEF.md +207 -0
- package/templates/hono-fullstack/.agents/skills/triage/OUT-OF-SCOPE.md +105 -0
- package/templates/hono-fullstack/.agents/skills/triage/SKILL.md +112 -0
- package/templates/hono-fullstack/.agents/skills/triage/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/wait-what/SKILL.md +7 -0
- package/templates/hono-fullstack/.agents/skills/wait-what/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/wayfinder/SKILL.md +128 -0
- package/templates/hono-fullstack/.agents/skills/wayfinder/agents/openai.yaml +5 -0
- package/templates/hono-fullstack/.agents/skills/wizard/SKILL.md +44 -0
- package/templates/hono-fullstack/.agents/skills/wizard/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.agents/skills/wizard/template.sh +204 -0
- package/templates/hono-fullstack/.agents/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
- package/templates/hono-fullstack/.agents/skills/writing-for-agents/SKILL.md +81 -0
- package/templates/hono-fullstack/.agents/skills/writing-for-agents/agents/openai.yaml +3 -0
- package/templates/hono-fullstack/.changeset/README.md +8 -0
- package/templates/hono-fullstack/.changeset/config.json +11 -0
- package/templates/hono-fullstack/.editorconfig +31 -0
- package/templates/hono-fullstack/.gitattributes +39 -0
- package/templates/hono-fullstack/.vscode/extensions.json +5 -0
- package/templates/hono-fullstack/.vscode/launch.json +36 -0
- package/templates/hono-fullstack/.vscode/settings.json +26 -0
- package/templates/hono-fullstack/AGENTS.md +50 -0
- package/templates/hono-fullstack/README.md +51 -0
- package/templates/hono-fullstack/_gitignore +35 -0
- package/templates/hono-fullstack/apps/server/.dev.vars.example +9 -0
- package/templates/hono-fullstack/apps/server/package.json +63 -0
- package/templates/hono-fullstack/apps/server/src/adapters/cloudflare/entry.ts +36 -0
- package/templates/hono-fullstack/apps/server/src/adapters/nodejs/bootstrap.ts +61 -0
- package/templates/hono-fullstack/apps/server/src/adapters/nodejs/entry.ts +62 -0
- package/templates/hono-fullstack/apps/server/src/app.ts +43 -0
- package/templates/hono-fullstack/apps/server/src/config.ts +47 -0
- package/templates/hono-fullstack/apps/server/src/infra/logger/getter.ts +74 -0
- package/templates/hono-fullstack/apps/server/src/infra/logger/pino.ts +126 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/constants.ts +23 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/errors.ts +40 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/example/worker-entry.ts +13 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/pass-through/runner.ts +42 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/piscina/runner.ts +185 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/types.ts +118 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/utils/business-error.ts +19 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/utils/message.ts +49 -0
- package/templates/hono-fullstack/apps/server/src/infra/work-runner/utils/transfer.ts +144 -0
- package/templates/hono-fullstack/apps/server/src/middlewares/cors.ts +26 -0
- package/templates/hono-fullstack/apps/server/src/modules/example/contracts.ts +9 -0
- package/templates/hono-fullstack/apps/server/src/modules/example/routes.ts +73 -0
- package/templates/hono-fullstack/apps/server/src/modules/example/work-task/tasks.test.ts +49 -0
- package/templates/hono-fullstack/apps/server/src/modules/example/work-task/tasks.ts +58 -0
- package/templates/hono-fullstack/apps/server/src/shared/app/types.ts +44 -0
- package/templates/hono-fullstack/apps/server/src/shared/errors/constants.ts +152 -0
- package/templates/hono-fullstack/apps/server/src/shared/errors/defs/index.ts +15 -0
- package/templates/hono-fullstack/apps/server/src/shared/errors/handler.ts +16 -0
- package/templates/hono-fullstack/apps/server/src/shared/errors/log.ts +67 -0
- package/templates/hono-fullstack/apps/server/src/shared/errors/proto.ts +42 -0
- package/templates/hono-fullstack/apps/server/src/shared/errors/types.ts +29 -0
- package/templates/hono-fullstack/apps/server/src/shared/network/fetcher.ts +35 -0
- package/templates/hono-fullstack/apps/server/src/shared/network/openapi/index.ts +50 -0
- package/templates/hono-fullstack/apps/server/src/shared/network/openapi/res-defs.ts +39 -0
- package/templates/hono-fullstack/apps/server/src/shared/network/types.ts +3 -0
- package/templates/hono-fullstack/apps/server/src/shared/network/utils.ts +36 -0
- package/templates/hono-fullstack/apps/server/src/shared/network/validator.ts +28 -0
- package/templates/hono-fullstack/apps/server/src/shared/utils/index.ts +30 -0
- package/templates/hono-fullstack/apps/server/src/virtual-modules.d.ts +5 -0
- package/templates/hono-fullstack/apps/server/tsconfig.json +17 -0
- package/templates/hono-fullstack/apps/server/vite.config.ts +87 -0
- package/templates/hono-fullstack/apps/server/wrangler.jsonc +29 -0
- package/templates/hono-fullstack/apps/stack/backend/cloudflare.ts +5 -0
- package/templates/hono-fullstack/apps/stack/backend/node.ts +3 -0
- package/templates/hono-fullstack/apps/stack/frontend/components/general/ErrorMessage.tsx +4 -0
- package/templates/hono-fullstack/apps/stack/frontend/components/layouts/AppLayout.tsx +11 -0
- package/templates/hono-fullstack/apps/stack/frontend/components/layouts/Header.tsx +7 -0
- package/templates/hono-fullstack/apps/stack/frontend/components/layouts/Page.tsx +5 -0
- package/templates/hono-fullstack/apps/stack/frontend/components/layouts/PageContainer.tsx +5 -0
- package/templates/hono-fullstack/apps/stack/frontend/modules/example/api.ts +13 -0
- package/templates/hono-fullstack/apps/stack/frontend/modules/example/components/ExampleForm.tsx +45 -0
- package/templates/hono-fullstack/apps/stack/frontend/modules/example/components/ExampleList.tsx +13 -0
- package/templates/hono-fullstack/apps/stack/frontend/modules/example/hooks/api-hooks.ts +14 -0
- package/templates/hono-fullstack/apps/stack/frontend/modules/example/stores/index.ts +3 -0
- package/templates/hono-fullstack/apps/stack/frontend/routeTree.gen.ts +73 -0
- package/templates/hono-fullstack/apps/stack/frontend/router.tsx +22 -0
- package/templates/hono-fullstack/apps/stack/frontend/routes/__root.tsx +61 -0
- package/templates/hono-fullstack/apps/stack/frontend/routes/api/$.ts +18 -0
- package/templates/hono-fullstack/apps/stack/frontend/routes/index.tsx +50 -0
- package/templates/hono-fullstack/apps/stack/frontend/shared/network/client.ts +19 -0
- package/templates/hono-fullstack/apps/stack/frontend/shared/network/constants.ts +1 -0
- package/templates/hono-fullstack/apps/stack/frontend/shared/network/errors.ts +33 -0
- package/templates/hono-fullstack/apps/stack/frontend/styles.css +23 -0
- package/templates/hono-fullstack/apps/stack/frontend/vite-env.d.ts +6 -0
- package/templates/hono-fullstack/apps/stack/package.json +59 -0
- package/templates/hono-fullstack/apps/stack/tsconfig.json +13 -0
- package/templates/hono-fullstack/apps/stack/tsr.config.json +5 -0
- package/templates/hono-fullstack/apps/stack/vite.config.ts +82 -0
- package/templates/hono-fullstack/apps/stack/wrangler.jsonc +20 -0
- package/templates/hono-fullstack/docs/agents/domain.md +41 -0
- package/templates/hono-fullstack/docs/agents/issue-tracker.md +30 -0
- package/templates/hono-fullstack/docs/agents/triage-labels.md +15 -0
- package/templates/hono-fullstack/envs/.env.example.server +12 -0
- package/templates/hono-fullstack/envs/.env.example.sqlite +1 -0
- package/templates/hono-fullstack/envs/.env.example.sqlite-d1 +3 -0
- package/templates/hono-fullstack/libs/db/drizzle-kit/sqlite-d1.config.ts +22 -0
- package/templates/hono-fullstack/libs/db/drizzle-kit/sqlite.config.ts +22 -0
- package/templates/hono-fullstack/libs/db/package.json +42 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/client.ts +35 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/d1-client.ts +12 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/columns.ts +37 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/index.ts +7 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/modules/examples/examples.ts +22 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/relations.ts +5 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/tables.ts +5 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/types.ts +7 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/schema/vo.ts +1 -0
- package/templates/hono-fullstack/libs/db/src/dialects/sqlite/utils.ts +8 -0
- package/templates/hono-fullstack/libs/db/src/shared/types.ts +26 -0
- package/templates/hono-fullstack/libs/db/tsconfig.json +10 -0
- package/templates/hono-fullstack/libs/db/vite.config.ts +25 -0
- package/templates/hono-fullstack/libs/definition/package.json +30 -0
- package/templates/hono-fullstack/libs/definition/src/backend.ts +2 -0
- package/templates/hono-fullstack/libs/definition/src/configs/defs/log.ts +53 -0
- package/templates/hono-fullstack/libs/definition/src/configs/defs/middleware.ts +16 -0
- package/templates/hono-fullstack/libs/definition/src/configs/defs/runtime.ts +12 -0
- package/templates/hono-fullstack/libs/definition/src/configs/defs/sqlite.ts +26 -0
- package/templates/hono-fullstack/libs/definition/src/configs/defs/worker.ts +29 -0
- package/templates/hono-fullstack/libs/definition/src/configs/index.ts +5 -0
- package/templates/hono-fullstack/libs/definition/src/configs/proto.ts +81 -0
- package/templates/hono-fullstack/libs/definition/src/configs/schema.ts +23 -0
- package/templates/hono-fullstack/libs/definition/src/frontend.ts +1 -0
- package/templates/hono-fullstack/libs/definition/src/modules/example/index.ts +16 -0
- package/templates/hono-fullstack/libs/definition/src/modules/index.ts +1 -0
- package/templates/hono-fullstack/libs/definition/tsconfig.json +5 -0
- package/templates/hono-fullstack/libs/definition/vite.config.ts +16 -0
- package/templates/hono-fullstack/oyo.config.json +13 -0
- package/templates/hono-fullstack/package.json +25 -0
- package/templates/hono-fullstack/pnpm-workspace.yaml +84 -0
- package/templates/hono-fullstack/tsconfig.json +4 -0
- package/templates/hono-fullstack/turbo.json +36 -0
- package/templates/hono-fullstack/vite.config.ts +14 -0
- package/templates/hono-server/.agents/skills/ask-matt/PHASE-BOUNDARIES.md +55 -0
- package/templates/hono-server/.agents/skills/ask-matt/SKILL.md +90 -0
- package/templates/hono-server/.agents/skills/ask-matt/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/code-review/SKILL.md +87 -0
- package/templates/hono-server/.agents/skills/code-review/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/codebase-design/DEEPENING.md +37 -0
- package/templates/hono-server/.agents/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/templates/hono-server/.agents/skills/codebase-design/SKILL.md +114 -0
- package/templates/hono-server/.agents/skills/codebase-design/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/confirm-requirements/SKILL.md +25 -0
- package/templates/hono-server/.agents/skills/diagnosing-bugs/SKILL.md +140 -0
- package/templates/hono-server/.agents/skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
- package/templates/hono-server/.agents/skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/templates/hono-server/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/templates/hono-server/.agents/skills/domain-modeling/SKILL.md +74 -0
- package/templates/hono-server/.agents/skills/domain-modeling/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/grill-me/SKILL.md +7 -0
- package/templates/hono-server/.agents/skills/grill-me/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/grilling/SKILL.md +22 -0
- package/templates/hono-server/.agents/skills/grilling/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/implement/SKILL.md +15 -0
- package/templates/hono-server/.agents/skills/implement/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
- package/templates/hono-server/.agents/skills/improve-codebase-architecture/SKILL.md +71 -0
- package/templates/hono-server/.agents/skills/improve-codebase-architecture/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/prototype/LOGIC.md +67 -0
- package/templates/hono-server/.agents/skills/prototype/SKILL.md +26 -0
- package/templates/hono-server/.agents/skills/prototype/UI.md +112 -0
- package/templates/hono-server/.agents/skills/prototype/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/research/SKILL.md +12 -0
- package/templates/hono-server/.agents/skills/research/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/resolving-merge-conflicts/SKILL.md +14 -0
- package/templates/hono-server/.agents/skills/resolving-merge-conflicts/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/scoped-code-review/SKILL.md +113 -0
- package/templates/hono-server/.agents/skills/setup-matt-pocock-skills/SKILL.md +116 -0
- package/templates/hono-server/.agents/skills/setup-matt-pocock-skills/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/setup-matt-pocock-skills/domain.md +51 -0
- package/templates/hono-server/.agents/skills/setup-matt-pocock-skills/issue-tracker-github.md +45 -0
- package/templates/hono-server/.agents/skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +46 -0
- package/templates/hono-server/.agents/skills/setup-matt-pocock-skills/issue-tracker-local.md +30 -0
- package/templates/hono-server/.agents/skills/setup-matt-pocock-skills/triage-labels.md +15 -0
- package/templates/hono-server/.agents/skills/tdd/SKILL.md +38 -0
- package/templates/hono-server/.agents/skills/tdd/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/tdd/mocking.md +59 -0
- package/templates/hono-server/.agents/skills/tdd/tests.md +77 -0
- package/templates/hono-server/.agents/skills/teach/GLOSSARY-FORMAT.md +35 -0
- package/templates/hono-server/.agents/skills/teach/LEARNING-RECORD-FORMAT.md +46 -0
- package/templates/hono-server/.agents/skills/teach/MISSION-FORMAT.md +31 -0
- package/templates/hono-server/.agents/skills/teach/RESOURCES-FORMAT.md +32 -0
- package/templates/hono-server/.agents/skills/teach/SKILL.md +140 -0
- package/templates/hono-server/.agents/skills/teach/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/to-questionnaire/SKILL.md +53 -0
- package/templates/hono-server/.agents/skills/to-questionnaire/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/triage/AGENT-BRIEF.md +207 -0
- package/templates/hono-server/.agents/skills/triage/OUT-OF-SCOPE.md +105 -0
- package/templates/hono-server/.agents/skills/triage/SKILL.md +112 -0
- package/templates/hono-server/.agents/skills/triage/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/wait-what/SKILL.md +7 -0
- package/templates/hono-server/.agents/skills/wait-what/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/wayfinder/SKILL.md +128 -0
- package/templates/hono-server/.agents/skills/wayfinder/agents/openai.yaml +5 -0
- package/templates/hono-server/.agents/skills/wizard/SKILL.md +44 -0
- package/templates/hono-server/.agents/skills/wizard/agents/openai.yaml +3 -0
- package/templates/hono-server/.agents/skills/wizard/template.sh +204 -0
- package/templates/hono-server/.agents/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
- package/templates/hono-server/.agents/skills/writing-for-agents/SKILL.md +81 -0
- package/templates/hono-server/.agents/skills/writing-for-agents/agents/openai.yaml +3 -0
- package/templates/hono-server/.changeset/README.md +8 -0
- package/templates/hono-server/.changeset/config.json +11 -0
- package/templates/hono-server/.editorconfig +31 -0
- package/templates/hono-server/.gitattributes +39 -0
- package/templates/hono-server/.vscode/extensions.json +5 -0
- package/templates/hono-server/.vscode/launch.json +29 -0
- package/templates/hono-server/.vscode/settings.json +26 -0
- package/templates/hono-server/AGENTS.md +50 -0
- package/templates/hono-server/README.md +44 -0
- package/templates/hono-server/_gitignore +35 -0
- package/templates/hono-server/apps/server/.dev.vars.example +9 -0
- package/templates/hono-server/apps/server/package.json +64 -0
- package/templates/hono-server/apps/server/src/adapters/cloudflare/entry.ts +36 -0
- package/templates/hono-server/apps/server/src/adapters/nodejs/bootstrap.ts +61 -0
- package/templates/hono-server/apps/server/src/adapters/nodejs/entry.ts +62 -0
- package/templates/hono-server/apps/server/src/app.ts +43 -0
- package/templates/hono-server/apps/server/src/config.ts +47 -0
- package/templates/hono-server/apps/server/src/infra/logger/getter.ts +74 -0
- package/templates/hono-server/apps/server/src/infra/logger/pino.ts +126 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/constants.ts +23 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/errors.ts +40 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/example/worker-entry.ts +13 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/pass-through/runner.ts +42 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/piscina/runner.ts +185 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/types.ts +118 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/utils/business-error.ts +19 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/utils/message.ts +49 -0
- package/templates/hono-server/apps/server/src/infra/work-runner/utils/transfer.ts +144 -0
- package/templates/hono-server/apps/server/src/middlewares/cors.ts +26 -0
- package/templates/hono-server/apps/server/src/modules/example/contracts.ts +9 -0
- package/templates/hono-server/apps/server/src/modules/example/routes.ts +73 -0
- package/templates/hono-server/apps/server/src/modules/example/work-task/tasks.test.ts +49 -0
- package/templates/hono-server/apps/server/src/modules/example/work-task/tasks.ts +58 -0
- package/templates/hono-server/apps/server/src/shared/app/types.ts +44 -0
- package/templates/hono-server/apps/server/src/shared/errors/constants.ts +152 -0
- package/templates/hono-server/apps/server/src/shared/errors/defs/index.ts +15 -0
- package/templates/hono-server/apps/server/src/shared/errors/handler.ts +16 -0
- package/templates/hono-server/apps/server/src/shared/errors/log.ts +67 -0
- package/templates/hono-server/apps/server/src/shared/errors/proto.ts +42 -0
- package/templates/hono-server/apps/server/src/shared/errors/types.ts +29 -0
- package/templates/hono-server/apps/server/src/shared/network/fetcher.ts +35 -0
- package/templates/hono-server/apps/server/src/shared/network/openapi/index.ts +50 -0
- package/templates/hono-server/apps/server/src/shared/network/openapi/res-defs.ts +39 -0
- package/templates/hono-server/apps/server/src/shared/network/types.ts +3 -0
- package/templates/hono-server/apps/server/src/shared/network/utils.ts +36 -0
- package/templates/hono-server/apps/server/src/shared/network/validator.ts +28 -0
- package/templates/hono-server/apps/server/src/shared/utils/index.ts +30 -0
- package/templates/hono-server/apps/server/src/virtual-modules.d.ts +5 -0
- package/templates/hono-server/apps/server/tsconfig.json +17 -0
- package/templates/hono-server/apps/server/vite.config.ts +87 -0
- package/templates/hono-server/apps/server/wrangler.jsonc +29 -0
- package/templates/hono-server/docker/.env.example +4 -0
- package/templates/hono-server/docker/README.md +5 -0
- package/templates/hono-server/docker/local/compose.local.app.yml +21 -0
- package/templates/hono-server/docker/local/local-app-deploy.sh +8 -0
- package/templates/hono-server/docker/local/local-app-down.sh +8 -0
- package/templates/hono-server/docker/prod/.env.example.server +11 -0
- package/templates/hono-server/docker/prod/compose.prod.stack.yml +21 -0
- package/templates/hono-server/docker/prod/update.sh +7 -0
- package/templates/hono-server/docker/server.Dockerfile +38 -0
- package/templates/hono-server/docker/server.Dockerfile.dockerignore +23 -0
- package/templates/hono-server/docs/agents/domain.md +41 -0
- package/templates/hono-server/docs/agents/issue-tracker.md +30 -0
- package/templates/hono-server/docs/agents/triage-labels.md +15 -0
- package/templates/hono-server/envs/.env.example.server +12 -0
- package/templates/hono-server/envs/.env.example.sqlite +1 -0
- package/templates/hono-server/envs/.env.example.sqlite-d1 +3 -0
- package/templates/hono-server/libs/db/drizzle-kit/sqlite-d1.config.ts +22 -0
- package/templates/hono-server/libs/db/drizzle-kit/sqlite.config.ts +22 -0
- package/templates/hono-server/libs/db/package.json +42 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/client.ts +35 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/d1-client.ts +12 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/schema/columns.ts +37 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/schema/index.ts +7 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/schema/modules/examples/examples.ts +22 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/schema/relations.ts +5 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/schema/tables.ts +5 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/schema/types.ts +7 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/schema/vo.ts +1 -0
- package/templates/hono-server/libs/db/src/dialects/sqlite/utils.ts +8 -0
- package/templates/hono-server/libs/db/src/shared/types.ts +26 -0
- package/templates/hono-server/libs/db/tsconfig.json +10 -0
- package/templates/hono-server/libs/db/vite.config.ts +25 -0
- package/templates/hono-server/libs/definition/package.json +29 -0
- package/templates/hono-server/libs/definition/src/backend.ts +2 -0
- package/templates/hono-server/libs/definition/src/configs/defs/log.ts +53 -0
- package/templates/hono-server/libs/definition/src/configs/defs/middleware.ts +16 -0
- package/templates/hono-server/libs/definition/src/configs/defs/runtime.ts +12 -0
- package/templates/hono-server/libs/definition/src/configs/defs/sqlite.ts +26 -0
- package/templates/hono-server/libs/definition/src/configs/defs/worker.ts +29 -0
- package/templates/hono-server/libs/definition/src/configs/index.ts +5 -0
- package/templates/hono-server/libs/definition/src/configs/proto.ts +81 -0
- package/templates/hono-server/libs/definition/src/configs/schema.ts +23 -0
- package/templates/hono-server/libs/definition/src/modules/example/index.ts +16 -0
- package/templates/hono-server/libs/definition/src/modules/index.ts +1 -0
- package/templates/hono-server/libs/definition/tsconfig.json +5 -0
- package/templates/hono-server/libs/definition/vite.config.ts +15 -0
- package/templates/hono-server/oyo.config.json +13 -0
- package/templates/hono-server/package.json +25 -0
- package/templates/hono-server/pnpm-workspace.yaml +66 -0
- package/templates/hono-server/scripts/.env.example.docker +4 -0
- package/templates/hono-server/scripts/build-docker-server.sh +13 -0
- package/templates/hono-server/scripts/common.sh +20 -0
- package/templates/hono-server/tsconfig.json +4 -0
- package/templates/hono-server/turbo.json +36 -0
- package/templates/hono-server/vite.config.ts +14 -0
- package/templates/monorepo/.agents/skills/ask-matt/PHASE-BOUNDARIES.md +55 -0
- package/templates/monorepo/.agents/skills/ask-matt/SKILL.md +90 -0
- package/templates/monorepo/.agents/skills/ask-matt/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/code-review/SKILL.md +87 -0
- package/templates/monorepo/.agents/skills/code-review/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/codebase-design/DEEPENING.md +37 -0
- package/templates/monorepo/.agents/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/templates/monorepo/.agents/skills/codebase-design/SKILL.md +114 -0
- package/templates/monorepo/.agents/skills/codebase-design/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/confirm-requirements/SKILL.md +25 -0
- package/templates/monorepo/.agents/skills/diagnosing-bugs/SKILL.md +140 -0
- package/templates/monorepo/.agents/skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
- package/templates/monorepo/.agents/skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/templates/monorepo/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/templates/monorepo/.agents/skills/domain-modeling/SKILL.md +74 -0
- package/templates/monorepo/.agents/skills/domain-modeling/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/grill-me/SKILL.md +7 -0
- package/templates/monorepo/.agents/skills/grill-me/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/grilling/SKILL.md +22 -0
- package/templates/monorepo/.agents/skills/grilling/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/implement/SKILL.md +15 -0
- package/templates/monorepo/.agents/skills/implement/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
- package/templates/monorepo/.agents/skills/improve-codebase-architecture/SKILL.md +71 -0
- package/templates/monorepo/.agents/skills/improve-codebase-architecture/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/prototype/LOGIC.md +67 -0
- package/templates/monorepo/.agents/skills/prototype/SKILL.md +26 -0
- package/templates/monorepo/.agents/skills/prototype/UI.md +112 -0
- package/templates/monorepo/.agents/skills/prototype/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/research/SKILL.md +12 -0
- package/templates/monorepo/.agents/skills/research/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/resolving-merge-conflicts/SKILL.md +14 -0
- package/templates/monorepo/.agents/skills/resolving-merge-conflicts/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/scoped-code-review/SKILL.md +113 -0
- package/templates/monorepo/.agents/skills/setup-matt-pocock-skills/SKILL.md +116 -0
- package/templates/monorepo/.agents/skills/setup-matt-pocock-skills/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/setup-matt-pocock-skills/domain.md +51 -0
- package/templates/monorepo/.agents/skills/setup-matt-pocock-skills/issue-tracker-github.md +45 -0
- package/templates/monorepo/.agents/skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +46 -0
- package/templates/monorepo/.agents/skills/setup-matt-pocock-skills/issue-tracker-local.md +30 -0
- package/templates/monorepo/.agents/skills/setup-matt-pocock-skills/triage-labels.md +15 -0
- package/templates/monorepo/.agents/skills/tdd/SKILL.md +38 -0
- package/templates/monorepo/.agents/skills/tdd/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/tdd/mocking.md +59 -0
- package/templates/monorepo/.agents/skills/tdd/tests.md +77 -0
- package/templates/monorepo/.agents/skills/teach/GLOSSARY-FORMAT.md +35 -0
- package/templates/monorepo/.agents/skills/teach/LEARNING-RECORD-FORMAT.md +46 -0
- package/templates/monorepo/.agents/skills/teach/MISSION-FORMAT.md +31 -0
- package/templates/monorepo/.agents/skills/teach/RESOURCES-FORMAT.md +32 -0
- package/templates/monorepo/.agents/skills/teach/SKILL.md +140 -0
- package/templates/monorepo/.agents/skills/teach/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/to-questionnaire/SKILL.md +53 -0
- package/templates/monorepo/.agents/skills/to-questionnaire/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/triage/AGENT-BRIEF.md +207 -0
- package/templates/monorepo/.agents/skills/triage/OUT-OF-SCOPE.md +105 -0
- package/templates/monorepo/.agents/skills/triage/SKILL.md +112 -0
- package/templates/monorepo/.agents/skills/triage/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/wait-what/SKILL.md +7 -0
- package/templates/monorepo/.agents/skills/wait-what/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/wayfinder/SKILL.md +128 -0
- package/templates/monorepo/.agents/skills/wayfinder/agents/openai.yaml +5 -0
- package/templates/monorepo/.agents/skills/wizard/SKILL.md +44 -0
- package/templates/monorepo/.agents/skills/wizard/agents/openai.yaml +3 -0
- package/templates/monorepo/.agents/skills/wizard/template.sh +204 -0
- package/templates/monorepo/.agents/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
- package/templates/monorepo/.agents/skills/writing-for-agents/SKILL.md +81 -0
- package/templates/monorepo/.agents/skills/writing-for-agents/agents/openai.yaml +3 -0
- package/templates/monorepo/.vscode/extensions.json +5 -0
- package/templates/monorepo/.vscode/launch.json +0 -3
- package/templates/monorepo/.vscode/settings.json +3 -1
- package/templates/monorepo/AGENTS.md +50 -0
- package/templates/monorepo/README.md +27 -0
- package/templates/monorepo/_gitignore +5 -0
- package/templates/monorepo/docs/agents/domain.md +41 -0
- package/templates/monorepo/docs/agents/issue-tracker.md +30 -0
- package/templates/monorepo/docs/agents/triage-labels.md +15 -0
- package/templates/monorepo/package.json +4 -3
- package/templates/monorepo/pnpm-workspace.yaml +23 -26
- package/templates/monorepo/turbo.json +27 -3
- package/templates/monorepo/vite.config.ts +1 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { ExampleRunnerTaskModel } from '@/modules/example/work-task/tasks'
|
|
2
|
+
import type { Transferable } from 'node:worker_threads'
|
|
3
|
+
import type { WorkerErrorCode, WorkSubject } from './constants'
|
|
4
|
+
|
|
5
|
+
// export const WorkerInvocationType = Object.freeze({
|
|
6
|
+
// READY: 'READY',
|
|
7
|
+
// TASK: 'TASK',
|
|
8
|
+
// } as const)
|
|
9
|
+
// export type WorkerInvocationType = (typeof WorkerInvocationType)[keyof typeof WorkerInvocationType]
|
|
10
|
+
|
|
11
|
+
// export const WorkerSignalType = Object.freeze({
|
|
12
|
+
// STARTED: 'started',
|
|
13
|
+
// } as const)
|
|
14
|
+
// export type WorkerSignalType = (typeof WorkerSignalType)[keyof typeof WorkerSignalType]
|
|
15
|
+
|
|
16
|
+
export type DefineRunnerTaskModel<
|
|
17
|
+
TSubject extends WorkSubject,
|
|
18
|
+
TInput,
|
|
19
|
+
TOutput,
|
|
20
|
+
TTaskErrorCode extends string = string,
|
|
21
|
+
> = {
|
|
22
|
+
subject: TSubject
|
|
23
|
+
input: TInput
|
|
24
|
+
output: TOutput
|
|
25
|
+
errorCode: TTaskErrorCode | WorkerErrorCode
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type AnyRunnerTaskModel = ExampleRunnerTaskModel
|
|
29
|
+
|
|
30
|
+
export type GetRunnerTaskModel<TSubject extends WorkSubject> = Extract<
|
|
31
|
+
AnyRunnerTaskModel,
|
|
32
|
+
{ subject: TSubject }
|
|
33
|
+
>
|
|
34
|
+
|
|
35
|
+
export type RunnerTaskParams<TSubject extends WorkSubject> = Pick<
|
|
36
|
+
GetRunnerTaskModel<TSubject>,
|
|
37
|
+
'input' | 'subject'
|
|
38
|
+
>
|
|
39
|
+
export type RunnerTaskInput<TSubject extends WorkSubject> = GetRunnerTaskModel<TSubject>['input']
|
|
40
|
+
export type RunnerTaskOutput<TSubject extends WorkSubject> = GetRunnerTaskModel<TSubject>['output']
|
|
41
|
+
export type RunnerTaskErrorCode<TSubject extends WorkSubject> =
|
|
42
|
+
GetRunnerTaskModel<TSubject>['errorCode']
|
|
43
|
+
|
|
44
|
+
export type RunnerTaskInvocation<TInput> = {
|
|
45
|
+
input: TInput
|
|
46
|
+
messagePort: WorkerMessagePort
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type RunnerTaskJsonValue =
|
|
50
|
+
| string
|
|
51
|
+
| number
|
|
52
|
+
| boolean
|
|
53
|
+
| null
|
|
54
|
+
| readonly RunnerTaskJsonValue[]
|
|
55
|
+
| { readonly [key: string]: RunnerTaskJsonValue }
|
|
56
|
+
|
|
57
|
+
/** Worker 通信中的错误详情必须保持为可结构化克隆、可 JSON 序列化的普通数据。 */
|
|
58
|
+
export type RunnerTaskErrorDetails = Readonly<Record<string, RunnerTaskJsonValue>>
|
|
59
|
+
|
|
60
|
+
export type WorkerMessage =
|
|
61
|
+
| {
|
|
62
|
+
type: 'log'
|
|
63
|
+
level: 'debug' | 'info' | 'warn' | 'error'
|
|
64
|
+
message: string
|
|
65
|
+
data?: RunnerTaskErrorDetails
|
|
66
|
+
}
|
|
67
|
+
| {
|
|
68
|
+
type: 'progress'
|
|
69
|
+
value: number
|
|
70
|
+
message?: string
|
|
71
|
+
}
|
|
72
|
+
| {
|
|
73
|
+
type: 'result'
|
|
74
|
+
data: RunnerTaskJsonValue
|
|
75
|
+
}
|
|
76
|
+
| {
|
|
77
|
+
type: 'error'
|
|
78
|
+
error: RunnerTaskError
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface WorkerMessagePort {
|
|
82
|
+
postMessage(message: WorkerMessage): void
|
|
83
|
+
close(): void
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type RunnerTaskError<TCode extends string = string> = {
|
|
87
|
+
code: TCode
|
|
88
|
+
/** 仅供服务端诊断,不应直接作为 HTTP 响应文案。 */
|
|
89
|
+
message: string
|
|
90
|
+
details?: RunnerTaskErrorDetails
|
|
91
|
+
cause?: unknown
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type RunnerTaskResult<TData, TCode extends string = string> =
|
|
95
|
+
| { ok: true; data: TData }
|
|
96
|
+
| { ok: false; error: RunnerTaskError<TCode> }
|
|
97
|
+
|
|
98
|
+
export type RunnerTaskRunResult<TSubject extends WorkSubject> = RunnerTaskResult<
|
|
99
|
+
RunnerTaskOutput<TSubject>,
|
|
100
|
+
RunnerTaskErrorCode<TSubject>
|
|
101
|
+
>
|
|
102
|
+
|
|
103
|
+
export type RunnerTaskRunOptions = {
|
|
104
|
+
signal?: AbortSignal
|
|
105
|
+
transferList?: Transferable[]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface AppWorkRunner {
|
|
109
|
+
run<TSubject extends WorkSubject>(
|
|
110
|
+
task: RunnerTaskParams<TSubject>,
|
|
111
|
+
options?: RunnerTaskRunOptions,
|
|
112
|
+
): Promise<RunnerTaskRunResult<TSubject>>
|
|
113
|
+
shutdown(): Promise<void>
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 已识别的公共 Worker 错误 Code 由具体任务与业务错误 Code 组合:
|
|
117
|
+
// 队列满、任务超时、Worker 暂不可用等返回失败 DTO;
|
|
118
|
+
// 未识别的 Piscina 异常和程序缺陷仍保持 Promise rejection,不能在此兜底吞掉。
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { hasProp } from '@/shared/utils'
|
|
2
|
+
import type { RunnerTaskErrorDetails } from '../types'
|
|
3
|
+
|
|
4
|
+
export class WorkerTaskBusinessError extends Error {
|
|
5
|
+
readonly details?: RunnerTaskErrorDetails
|
|
6
|
+
|
|
7
|
+
constructor(message: string, details?: RunnerTaskErrorDetails, cause?: unknown) {
|
|
8
|
+
super(message, { cause })
|
|
9
|
+
this.name = 'WorkerTaskBusinessError'
|
|
10
|
+
this.details = details
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function isWorkerTaskBusinessError(error: unknown): error is WorkerTaskBusinessError {
|
|
15
|
+
return (
|
|
16
|
+
error instanceof WorkerTaskBusinessError ||
|
|
17
|
+
(error instanceof Error && hasProp(error, 'name') && error.name === 'WorkerTaskBusinessError')
|
|
18
|
+
)
|
|
19
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AppLogger } from '@/shared/app/types'
|
|
2
|
+
import type { RunnerTaskErrorDetails, WorkerMessage, WorkerMessagePort } from '../types'
|
|
3
|
+
import type { WorkSubject } from '../constants'
|
|
4
|
+
|
|
5
|
+
export function workerLog(
|
|
6
|
+
messagePort: WorkerMessagePort,
|
|
7
|
+
level: Extract<WorkerMessage, { type: 'log' }>['level'],
|
|
8
|
+
message: string,
|
|
9
|
+
data?: RunnerTaskErrorDetails,
|
|
10
|
+
): void {
|
|
11
|
+
messagePort.postMessage({ type: 'log', level, message, data } satisfies WorkerMessage)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function workerProgress(
|
|
15
|
+
messagePort: WorkerMessagePort,
|
|
16
|
+
value: number,
|
|
17
|
+
message?: string,
|
|
18
|
+
): void {
|
|
19
|
+
messagePort.postMessage({ type: 'progress', value, message } satisfies WorkerMessage)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function handleWorkerMessage(
|
|
23
|
+
message: WorkerMessage,
|
|
24
|
+
logger: AppLogger,
|
|
25
|
+
context: {
|
|
26
|
+
subject: WorkSubject
|
|
27
|
+
},
|
|
28
|
+
): void {
|
|
29
|
+
switch (message.type) {
|
|
30
|
+
case 'log':
|
|
31
|
+
logger[message.level]({ subject: context.subject, worker: message.data }, message.message)
|
|
32
|
+
break
|
|
33
|
+
case 'progress':
|
|
34
|
+
logger.debug(
|
|
35
|
+
{ subject: context.subject, progress: message.value },
|
|
36
|
+
message.message || 'Worker progress',
|
|
37
|
+
)
|
|
38
|
+
break
|
|
39
|
+
case 'result':
|
|
40
|
+
logger.debug({ subject: context.subject }, 'Worker result delivered')
|
|
41
|
+
break
|
|
42
|
+
case 'error':
|
|
43
|
+
logger.warn(
|
|
44
|
+
{ subject: context.subject, workerError: message.error },
|
|
45
|
+
'Worker error delivered',
|
|
46
|
+
)
|
|
47
|
+
break
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { isMarkedAsUntransferable } from 'node:worker_threads'
|
|
2
|
+
|
|
3
|
+
export interface TransferableResult<T> {
|
|
4
|
+
value: T
|
|
5
|
+
transferable?: ArrayBuffer
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 排除不需要遍历其属性的原生系统对象(交由 V8 结构化克隆内部处理)
|
|
10
|
+
*/
|
|
11
|
+
function isCloneableLeaf(value: unknown): boolean {
|
|
12
|
+
return (
|
|
13
|
+
value instanceof Date ||
|
|
14
|
+
value instanceof RegExp ||
|
|
15
|
+
value instanceof Error ||
|
|
16
|
+
(typeof URL !== 'undefined' && value instanceof URL)
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 转换 ArrayBufferView
|
|
22
|
+
*/
|
|
23
|
+
export function toTransferable<T extends ArrayBufferView>(view: T): TransferableResult<T> {
|
|
24
|
+
const buffer = view.buffer
|
|
25
|
+
|
|
26
|
+
// 1. SharedArrayBuffer 或已显式标记为不可转移的 Buffer,原样返回(由系统克隆)
|
|
27
|
+
if (!(buffer instanceof ArrayBuffer) || isMarkedAsUntransferable(buffer)) {
|
|
28
|
+
return { value: view }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 2. 独占且干净的 Buffer:直接转移,零拷贝
|
|
32
|
+
if (view.byteOffset === 0 && view.byteLength === buffer.byteLength) {
|
|
33
|
+
return { value: view, transferable: buffer }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 3. 处于切片/池化状态:切片降级,提取独立 ArrayBuffer
|
|
37
|
+
const newBuffer = buffer.slice(view.byteOffset, view.byteOffset + view.byteLength)
|
|
38
|
+
|
|
39
|
+
// 4. 重新包装 View,修复 Node.js Buffer 的构造函数废弃警告
|
|
40
|
+
let newView: T
|
|
41
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(view)) {
|
|
42
|
+
newView = Buffer.from(newBuffer) as unknown as T
|
|
43
|
+
} else {
|
|
44
|
+
const Ctor = view.constructor as new (buf: ArrayBuffer) => T
|
|
45
|
+
newView = new Ctor(newBuffer)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
value: newView,
|
|
50
|
+
transferable: newBuffer,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 【主入口】:深层提取 Transferables
|
|
56
|
+
*/
|
|
57
|
+
export function extractTransferables(input: any): {
|
|
58
|
+
input: any
|
|
59
|
+
transferList: ArrayBuffer[]
|
|
60
|
+
} {
|
|
61
|
+
const transferables = new Set<ArrayBuffer>()
|
|
62
|
+
const extracted = new WeakMap<object, unknown>()
|
|
63
|
+
|
|
64
|
+
function extract(value: any): any {
|
|
65
|
+
if (!value || typeof value !== 'object') return value
|
|
66
|
+
|
|
67
|
+
// 命中缓存(环状引用 / 重复对象)
|
|
68
|
+
const cached = extracted.get(value)
|
|
69
|
+
if (cached !== undefined) return cached
|
|
70
|
+
|
|
71
|
+
// 裸 ArrayBuffer
|
|
72
|
+
if (value instanceof ArrayBuffer) {
|
|
73
|
+
if (!isMarkedAsUntransferable(value)) {
|
|
74
|
+
transferables.add(value)
|
|
75
|
+
}
|
|
76
|
+
extracted.set(value, value)
|
|
77
|
+
return value
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ArrayBufferView (Buffer, TypedArray, DataView)
|
|
81
|
+
if (ArrayBuffer.isView(value)) {
|
|
82
|
+
const { value: transferableView, transferable } = toTransferable(value)
|
|
83
|
+
if (transferable) {
|
|
84
|
+
transferables.add(transferable)
|
|
85
|
+
}
|
|
86
|
+
extracted.set(value, transferableView)
|
|
87
|
+
return transferableView
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 遇到原生特殊对象,直接跳过深入遍历
|
|
91
|
+
if (isCloneableLeaf(value)) {
|
|
92
|
+
extracted.set(value, value)
|
|
93
|
+
return value
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 场景 4:普通数组
|
|
97
|
+
if (Array.isArray(value)) {
|
|
98
|
+
const array: unknown[] = []
|
|
99
|
+
extracted.set(value, array)
|
|
100
|
+
for (let i = 0; i < value.length; i++) {
|
|
101
|
+
array.push(extract(value[i]))
|
|
102
|
+
}
|
|
103
|
+
return array
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 场景 5:Map 和 Set
|
|
107
|
+
if (value instanceof Map) {
|
|
108
|
+
const map = new Map()
|
|
109
|
+
extracted.set(value, map)
|
|
110
|
+
for (const [k, v] of value) {
|
|
111
|
+
map.set(extract(k), extract(v))
|
|
112
|
+
}
|
|
113
|
+
return map
|
|
114
|
+
}
|
|
115
|
+
if (value instanceof Set) {
|
|
116
|
+
const set = new Set()
|
|
117
|
+
extracted.set(value, set)
|
|
118
|
+
for (const v of value) {
|
|
119
|
+
set.add(extract(v))
|
|
120
|
+
}
|
|
121
|
+
return set
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 场景 6:普通对象 & 自定义类实例(支持 Symbol 键)
|
|
125
|
+
const proto = Object.getPrototypeOf(value)
|
|
126
|
+
if (proto === null || proto === Object.prototype || (proto && proto.constructor !== Object)) {
|
|
127
|
+
const object: Record<string | symbol, unknown> = {}
|
|
128
|
+
extracted.set(value, object)
|
|
129
|
+
|
|
130
|
+
const keys = Reflect.ownKeys(value)
|
|
131
|
+
for (const key of keys) {
|
|
132
|
+
object[key] = extract(value[key as keyof typeof value])
|
|
133
|
+
}
|
|
134
|
+
return object
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return value
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
input: extract(input),
|
|
142
|
+
transferList: [...transferables],
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AppEnv } from '@/shared/app/types'
|
|
2
|
+
import { cors } from 'hono/cors'
|
|
3
|
+
import { createMiddleware } from 'hono/factory'
|
|
4
|
+
|
|
5
|
+
export const corsMiddleware = () => {
|
|
6
|
+
return createMiddleware<AppEnv>(async (c, next) => {
|
|
7
|
+
const corsConfig = c.get('appConfig')
|
|
8
|
+
const domains = corsConfig.middleware.cors.domains
|
|
9
|
+
const middleware = cors({
|
|
10
|
+
origin: (origin) => {
|
|
11
|
+
const isAllowedDomain = domains.some((domain) => {
|
|
12
|
+
try {
|
|
13
|
+
return domain === '*' || new URL(origin).host === domain
|
|
14
|
+
} catch {
|
|
15
|
+
return false
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
return isAllowedDomain ? origin : null
|
|
19
|
+
},
|
|
20
|
+
allowHeaders: ['Content-Type'],
|
|
21
|
+
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
22
|
+
credentials: true,
|
|
23
|
+
})
|
|
24
|
+
return middleware(c, next)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as v from 'valibot'
|
|
2
|
+
|
|
3
|
+
export const processExampleInputSchema = v.object({
|
|
4
|
+
message: v.pipe(v.string(), v.minLength(1)),
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
export const createExampleInputSchema = v.object({
|
|
8
|
+
message: v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(500)),
|
|
9
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type Context, Hono } from 'hono'
|
|
2
|
+
import { describeRoute } from 'hono-openapi'
|
|
3
|
+
import * as v from 'valibot'
|
|
4
|
+
import { examples, vcExamples, type SqliteDBType } from '@repo/db/sqlite/schema'
|
|
5
|
+
import type { AppEnv } from '@/shared/app/types'
|
|
6
|
+
import { WorkSubject } from '@/infra/work-runner/constants'
|
|
7
|
+
import { E } from '@/shared/errors/defs'
|
|
8
|
+
import { jsonResponse, OpenApiTags } from '@/shared/network/openapi'
|
|
9
|
+
import { successJson } from '@/shared/network/utils'
|
|
10
|
+
import { generalValidator } from '@/shared/network/validator'
|
|
11
|
+
import { createExampleInputSchema, processExampleInputSchema } from './contracts'
|
|
12
|
+
|
|
13
|
+
const getDb = (context: Context<AppEnv>) => context.get('db') as SqliteDBType
|
|
14
|
+
|
|
15
|
+
export const exampleRoutes = new Hono<AppEnv>()
|
|
16
|
+
.get(
|
|
17
|
+
'/health',
|
|
18
|
+
describeRoute({
|
|
19
|
+
operationId: 'getHealth',
|
|
20
|
+
tags: [OpenApiTags.System],
|
|
21
|
+
summary: 'Health check',
|
|
22
|
+
responses: { 200: jsonResponse(v.object({ data: v.object({ status: v.string() }) })) },
|
|
23
|
+
}),
|
|
24
|
+
(c) => successJson(c, { status: 'ok' }),
|
|
25
|
+
)
|
|
26
|
+
.get(
|
|
27
|
+
'/examples',
|
|
28
|
+
describeRoute({
|
|
29
|
+
operationId: 'listExamples',
|
|
30
|
+
tags: [OpenApiTags.Example],
|
|
31
|
+
summary: 'List example rows',
|
|
32
|
+
responses: { 200: { description: 'Example rows' } },
|
|
33
|
+
}),
|
|
34
|
+
async (c) => successJson(c, await getDb(c).select(vcExamples.default).from(examples)),
|
|
35
|
+
)
|
|
36
|
+
.post(
|
|
37
|
+
'/examples',
|
|
38
|
+
describeRoute({
|
|
39
|
+
operationId: 'createExample',
|
|
40
|
+
tags: [OpenApiTags.Example],
|
|
41
|
+
summary: 'Create an example row',
|
|
42
|
+
responses: { 200: { description: 'Created example row' } },
|
|
43
|
+
}),
|
|
44
|
+
generalValidator('json', createExampleInputSchema),
|
|
45
|
+
async (c) => {
|
|
46
|
+
const input = c.req.valid('json')
|
|
47
|
+
const [row] = await getDb(c).insert(examples).values(input).returning(vcExamples.default)
|
|
48
|
+
return successJson(c, row)
|
|
49
|
+
},
|
|
50
|
+
)
|
|
51
|
+
.post(
|
|
52
|
+
'/examples/process',
|
|
53
|
+
describeRoute({
|
|
54
|
+
operationId: 'processExample',
|
|
55
|
+
tags: [OpenApiTags.Example],
|
|
56
|
+
summary: 'Process an example message in the worker pool',
|
|
57
|
+
responses: { 200: jsonResponse(v.object({ data: v.object({ normalized: v.string() }) })) },
|
|
58
|
+
}),
|
|
59
|
+
generalValidator('json', processExampleInputSchema),
|
|
60
|
+
async (c) => {
|
|
61
|
+
const result = await c.get('workRunner').run({
|
|
62
|
+
subject: WorkSubject.PROCESS_EXAMPLE,
|
|
63
|
+
input: c.req.valid('json'),
|
|
64
|
+
})
|
|
65
|
+
if (!result.ok) {
|
|
66
|
+
throw E.NORMAL.INTERNAL.create({
|
|
67
|
+
cause: result.error,
|
|
68
|
+
extensions: { workerCode: result.error.code },
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
return successJson(c, result.data)
|
|
72
|
+
},
|
|
73
|
+
)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { MessageChannel } from 'node:worker_threads'
|
|
2
|
+
import { describe, expect, it } from 'vite-plus/test'
|
|
3
|
+
import { executeExampleTask } from './tasks'
|
|
4
|
+
|
|
5
|
+
describe('Example worker task', () => {
|
|
6
|
+
it('normalizes a message and reports progress', async () => {
|
|
7
|
+
const { port1, port2 } = new MessageChannel()
|
|
8
|
+
const messages: unknown[] = []
|
|
9
|
+
port1.on('message', (message) => messages.push(message))
|
|
10
|
+
const result = await executeExampleTask({ message: ' hello worker ' }, port2)
|
|
11
|
+
await new Promise<void>((resolve) => setImmediate(resolve))
|
|
12
|
+
|
|
13
|
+
expect(result).toEqual({
|
|
14
|
+
ok: true,
|
|
15
|
+
data: { original: ' hello worker ', normalized: 'hello worker', length: 12 },
|
|
16
|
+
})
|
|
17
|
+
expect(messages).toEqual(
|
|
18
|
+
expect.arrayContaining([
|
|
19
|
+
expect.objectContaining({ type: 'log' }),
|
|
20
|
+
expect.objectContaining({ type: 'progress', value: 100 }),
|
|
21
|
+
expect.objectContaining({ type: 'result' }),
|
|
22
|
+
]),
|
|
23
|
+
)
|
|
24
|
+
port1.close()
|
|
25
|
+
port2.close()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('serializes a business exception and reports it', async () => {
|
|
29
|
+
const { port1, port2 } = new MessageChannel()
|
|
30
|
+
const messages: unknown[] = []
|
|
31
|
+
port1.on('message', (message) => messages.push(message))
|
|
32
|
+
const result = await executeExampleTask({ message: ' ' }, port2)
|
|
33
|
+
await new Promise<void>((resolve) => setImmediate(resolve))
|
|
34
|
+
|
|
35
|
+
expect(result).toEqual({
|
|
36
|
+
ok: false,
|
|
37
|
+
error: {
|
|
38
|
+
code: 'EXAMPLE_PROCESS_FAILED',
|
|
39
|
+
message: 'Message must not be empty',
|
|
40
|
+
details: { field: 'message' },
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
expect(messages).toEqual(
|
|
44
|
+
expect.arrayContaining([expect.objectContaining({ type: 'error' })]),
|
|
45
|
+
)
|
|
46
|
+
port1.close()
|
|
47
|
+
port2.close()
|
|
48
|
+
})
|
|
49
|
+
})
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ProcessExampleInput, ProcessExampleOutput } from '@repo/definition/backend'
|
|
2
|
+
import { type WorkSubject } from '@/infra/work-runner/constants'
|
|
3
|
+
import type {
|
|
4
|
+
DefineRunnerTaskModel,
|
|
5
|
+
RunnerTaskResult,
|
|
6
|
+
WorkerMessagePort,
|
|
7
|
+
} from '@/infra/work-runner/types'
|
|
8
|
+
import {
|
|
9
|
+
isWorkerTaskBusinessError,
|
|
10
|
+
WorkerTaskBusinessError,
|
|
11
|
+
} from '@/infra/work-runner/utils/business-error'
|
|
12
|
+
import { workerLog, workerProgress } from '@/infra/work-runner/utils/message'
|
|
13
|
+
|
|
14
|
+
export type ExampleTaskErrorCode = 'EXAMPLE_PROCESS_FAILED'
|
|
15
|
+
|
|
16
|
+
export type ExampleRunnerTaskModel = DefineRunnerTaskModel<
|
|
17
|
+
typeof WorkSubject.PROCESS_EXAMPLE,
|
|
18
|
+
ProcessExampleInput,
|
|
19
|
+
ProcessExampleOutput,
|
|
20
|
+
ExampleTaskErrorCode
|
|
21
|
+
>
|
|
22
|
+
|
|
23
|
+
export async function executeExampleTask(
|
|
24
|
+
input: ExampleRunnerTaskModel['input'],
|
|
25
|
+
messagePort: WorkerMessagePort,
|
|
26
|
+
): Promise<RunnerTaskResult<ProcessExampleOutput, ExampleTaskErrorCode>> {
|
|
27
|
+
try {
|
|
28
|
+
workerLog(messagePort, 'debug', 'Example task started')
|
|
29
|
+
workerProgress(messagePort, 0, 'Validating input')
|
|
30
|
+
|
|
31
|
+
const original = input.message
|
|
32
|
+
const normalized = original.trim().replace(/\s+/g, ' ')
|
|
33
|
+
if (!normalized) {
|
|
34
|
+
throw new WorkerTaskBusinessError('Message must not be empty', { field: 'message' })
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
workerProgress(messagePort, 100, 'Example task completed')
|
|
38
|
+
const result = {
|
|
39
|
+
ok: true,
|
|
40
|
+
data: { original, normalized, length: normalized.length },
|
|
41
|
+
} as const
|
|
42
|
+
messagePort.postMessage({ type: 'result', data: result.data })
|
|
43
|
+
return result
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (!isWorkerTaskBusinessError(error)) throw error
|
|
46
|
+
|
|
47
|
+
const result: RunnerTaskResult<ProcessExampleOutput, ExampleTaskErrorCode> = {
|
|
48
|
+
ok: false,
|
|
49
|
+
error: {
|
|
50
|
+
code: 'EXAMPLE_PROCESS_FAILED',
|
|
51
|
+
message: error.message,
|
|
52
|
+
...(error.details ? { details: error.details } : {}),
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
messagePort.postMessage({ type: 'error', error: result.error })
|
|
56
|
+
return result
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CORSConfig,
|
|
3
|
+
LogBaseConfig,
|
|
4
|
+
LogPrettyRawConfig,
|
|
5
|
+
LogRollRawConfig,
|
|
6
|
+
LogRollSchemaConfig,
|
|
7
|
+
RuntimeConfig,
|
|
8
|
+
WorkerConfig,
|
|
9
|
+
} from '@repo/definition/backend'
|
|
10
|
+
import type { AppWorkRunner } from '@/infra/work-runner/types'
|
|
11
|
+
import type { MiddlewareHandler, Context } from 'hono'
|
|
12
|
+
import type { PinoLogger as HonoPinoLogger } from 'hono-pino'
|
|
13
|
+
import type { RequestIdVariables } from 'hono/request-id'
|
|
14
|
+
|
|
15
|
+
export type AppLogger = HonoPinoLogger
|
|
16
|
+
|
|
17
|
+
export type LogConfig = {
|
|
18
|
+
base: LogBaseConfig
|
|
19
|
+
roll?: LogRollSchemaConfig & LogRollRawConfig
|
|
20
|
+
pretty?: LogPrettyRawConfig
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type AppConfig = {
|
|
24
|
+
runtime: RuntimeConfig & { isLocal: boolean }
|
|
25
|
+
log: LogConfig
|
|
26
|
+
worker: WorkerConfig
|
|
27
|
+
middleware: { cors: CORSConfig }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type AppDependencies = {
|
|
31
|
+
appConfig: AppConfig
|
|
32
|
+
loggerHandler: MiddlewareHandler<{ Variables: { logger: AppLogger } }>
|
|
33
|
+
workRunner: AppWorkRunner
|
|
34
|
+
db: unknown
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type AppEnv = {
|
|
38
|
+
Variables: RequestIdVariables & AppDependencies & { logger?: AppLogger }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type CreateAppOptions = {
|
|
42
|
+
serverBasePath: string
|
|
43
|
+
makeDependencies: (c: Context<AppEnv>) => Promise<AppDependencies> | AppDependencies
|
|
44
|
+
}
|