@askdkc/kiokuko 0.1.17 → 0.1.19
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/README.ja.md +91 -112
- package/README.ko.md +90 -102
- package/README.md +103 -262
- package/README.zh-CN.md +88 -102
- package/dist/agent-file/atomic-write.d.ts +90 -3
- package/dist/agent-file/atomic-write.d.ts.map +1 -1
- package/dist/agent-file/atomic-write.js +990 -14
- package/dist/agent-file/atomic-write.js.map +1 -1
- package/dist/agent-file/managed-block.d.ts +12 -1
- package/dist/agent-file/managed-block.d.ts.map +1 -1
- package/dist/agent-file/managed-block.js +49 -4
- package/dist/agent-file/managed-block.js.map +1 -1
- package/dist/agent-file/render.d.ts +1 -1
- package/dist/agent-file/render.d.ts.map +1 -1
- package/dist/agent-file/render.js +10 -7
- package/dist/agent-file/render.js.map +1 -1
- package/dist/akinator/agent-task.d.ts +11 -22
- package/dist/akinator/agent-task.d.ts.map +1 -1
- package/dist/akinator/agent-task.js +454 -99
- package/dist/akinator/agent-task.js.map +1 -1
- package/dist/akinator/capabilities.d.ts +18 -6
- package/dist/akinator/capabilities.d.ts.map +1 -1
- package/dist/akinator/capabilities.js +72 -35
- package/dist/akinator/capabilities.js.map +1 -1
- package/dist/akinator/capability-binding.d.ts +11 -0
- package/dist/akinator/capability-binding.d.ts.map +1 -0
- package/dist/akinator/capability-binding.js +56 -0
- package/dist/akinator/capability-binding.js.map +1 -0
- package/dist/akinator/domain.js +2 -2
- package/dist/akinator/domain.js.map +1 -1
- package/dist/akinator/knowledge-path.d.ts.map +1 -1
- package/dist/akinator/knowledge-path.js +409 -39
- package/dist/akinator/knowledge-path.js.map +1 -1
- package/dist/akinator/orchestrator.d.ts +3 -4
- package/dist/akinator/orchestrator.d.ts.map +1 -1
- package/dist/akinator/orchestrator.js +1 -4
- package/dist/akinator/orchestrator.js.map +1 -1
- package/dist/akinator/service.d.ts +0 -4
- package/dist/akinator/service.d.ts.map +1 -1
- package/dist/akinator/service.js +19 -35
- package/dist/akinator/service.js.map +1 -1
- package/dist/akinator/skill-discovery-attempt.d.ts +20 -0
- package/dist/akinator/skill-discovery-attempt.d.ts.map +1 -0
- package/dist/akinator/skill-discovery-attempt.js +390 -0
- package/dist/akinator/skill-discovery-attempt.js.map +1 -0
- package/dist/akinator/store.d.ts.map +1 -1
- package/dist/akinator/store.js +107 -52
- package/dist/akinator/store.js.map +1 -1
- package/dist/akinator/types.d.ts +0 -12
- package/dist/akinator/types.d.ts.map +1 -1
- package/dist/bin/kiokuko.js +0 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +534 -148
- package/dist/cli.js.map +1 -1
- package/dist/client/server-client.d.ts +5 -3
- package/dist/client/server-client.d.ts.map +1 -1
- package/dist/client/server-client.js +486 -181
- package/dist/client/server-client.js.map +1 -1
- package/dist/commands/agent.d.ts +2 -0
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +861 -86
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/backup.d.ts +2 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +64 -8
- package/dist/commands/backup.js.map +1 -1
- package/dist/commands/doctor.d.ts +5 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +70 -26
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/export.d.ts +0 -4
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +191 -32
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.d.ts +10 -1
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +592 -113
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +19 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +569 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/purge.d.ts.map +1 -1
- package/dist/commands/purge.js +3 -0
- package/dist/commands/purge.js.map +1 -1
- package/dist/commands/setup.d.ts +34 -8
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +418 -86
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/skills.d.ts +9 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +317 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/use.d.ts +10 -2
- package/dist/commands/use.d.ts.map +1 -1
- package/dist/commands/use.js +851 -73
- package/dist/commands/use.js.map +1 -1
- package/dist/config/paths.d.ts +11 -1
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +64 -29
- package/dist/config/paths.js.map +1 -1
- package/dist/config/project-config.d.ts +1 -0
- package/dist/config/project-config.d.ts.map +1 -1
- package/dist/config/project-config.js +70 -32
- package/dist/config/project-config.js.map +1 -1
- package/dist/context/broker.d.ts +28 -14
- package/dist/context/broker.d.ts.map +1 -1
- package/dist/context/broker.js +604 -145
- package/dist/context/broker.js.map +1 -1
- package/dist/context/delivery.d.ts +6 -21
- package/dist/context/delivery.d.ts.map +1 -1
- package/dist/context/delivery.js +196 -147
- package/dist/context/delivery.js.map +1 -1
- package/dist/context/feedback.d.ts +11 -12
- package/dist/context/feedback.d.ts.map +1 -1
- package/dist/context/feedback.js +229 -261
- package/dist/context/feedback.js.map +1 -1
- package/dist/context/ranking.d.ts +1 -12
- package/dist/context/ranking.d.ts.map +1 -1
- package/dist/context/ranking.js +13 -4
- package/dist/context/ranking.js.map +1 -1
- package/dist/context/recommendations.d.ts +0 -5
- package/dist/context/recommendations.d.ts.map +1 -1
- package/dist/context/recommendations.js +0 -1
- package/dist/context/recommendations.js.map +1 -1
- package/dist/context/run-state.d.ts +26 -0
- package/dist/context/run-state.d.ts.map +1 -0
- package/dist/context/run-state.js +399 -0
- package/dist/context/run-state.js.map +1 -0
- package/dist/context/scoped-broker.d.ts +17 -5
- package/dist/context/scoped-broker.d.ts.map +1 -1
- package/dist/context/scoped-broker.js +512 -106
- package/dist/context/scoped-broker.js.map +1 -1
- package/dist/context/selection-state.d.ts +19 -0
- package/dist/context/selection-state.d.ts.map +1 -0
- package/dist/context/selection-state.js +250 -0
- package/dist/context/selection-state.js.map +1 -0
- package/dist/db/adapter.d.ts +5 -3
- package/dist/db/adapter.d.ts.map +1 -1
- package/dist/db/adapter.js +6 -3
- package/dist/db/adapter.js.map +1 -1
- package/dist/db/capabilities.d.ts.map +1 -1
- package/dist/db/capabilities.js +34 -16
- package/dist/db/capabilities.js.map +1 -1
- package/dist/db/connection.d.ts +8 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +55 -26
- package/dist/db/connection.js.map +1 -1
- package/dist/db/migrate.d.ts +28 -7
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +106 -78
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/sqlite-retry.d.ts +11 -0
- package/dist/db/sqlite-retry.d.ts.map +1 -0
- package/dist/db/sqlite-retry.js +66 -0
- package/dist/db/sqlite-retry.js.map +1 -0
- package/dist/db/transaction.d.ts +13 -0
- package/dist/db/transaction.d.ts.map +1 -1
- package/dist/db/transaction.js +53 -24
- package/dist/db/transaction.js.map +1 -1
- package/dist/db/upgrade-backup.d.ts +58 -2
- package/dist/db/upgrade-backup.d.ts.map +1 -1
- package/dist/db/upgrade-backup.js +757 -28
- package/dist/db/upgrade-backup.js.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/gateway/agent-service.d.ts +4 -1
- package/dist/gateway/agent-service.d.ts.map +1 -1
- package/dist/gateway/agent-service.js +71 -58
- package/dist/gateway/agent-service.js.map +1 -1
- package/dist/gateway/checkpoint-service.d.ts +1 -0
- package/dist/gateway/checkpoint-service.d.ts.map +1 -1
- package/dist/gateway/checkpoint-service.js +47 -24
- package/dist/gateway/checkpoint-service.js.map +1 -1
- package/dist/ledger/archive.d.ts +1 -4
- package/dist/ledger/archive.d.ts.map +1 -1
- package/dist/ledger/archive.js +77 -39
- package/dist/ledger/archive.js.map +1 -1
- package/dist/ledger/maintenance.d.ts +0 -11
- package/dist/ledger/maintenance.d.ts.map +1 -1
- package/dist/ledger/maintenance.js +24 -40
- package/dist/ledger/maintenance.js.map +1 -1
- package/dist/ledger/projection.d.ts +0 -1
- package/dist/ledger/projection.d.ts.map +1 -1
- package/dist/ledger/projection.js.map +1 -1
- package/dist/ledger/promotion.d.ts +0 -9
- package/dist/ledger/promotion.d.ts.map +1 -1
- package/dist/ledger/promotion.js.map +1 -1
- package/dist/ledger/query.d.ts +1 -15
- package/dist/ledger/query.d.ts.map +1 -1
- package/dist/ledger/query.js.map +1 -1
- package/dist/ledger/store.d.ts +0 -1
- package/dist/ledger/store.d.ts.map +1 -1
- package/dist/ledger/store.js +11 -8
- package/dist/ledger/store.js.map +1 -1
- package/dist/ledger/types.d.ts +0 -4
- package/dist/ledger/types.d.ts.map +1 -1
- package/dist/ledger/types.js.map +1 -1
- package/dist/ledger/validate.d.ts.map +1 -1
- package/dist/ledger/validate.js +0 -5
- package/dist/ledger/validate.js.map +1 -1
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +105 -54
- package/dist/mcp/server.js.map +1 -1
- package/dist/memory/audit.d.ts +0 -1
- package/dist/memory/audit.d.ts.map +1 -1
- package/dist/memory/audit.js +0 -1
- package/dist/memory/audit.js.map +1 -1
- package/dist/memory/curator.d.ts.map +1 -1
- package/dist/memory/curator.js +172 -96
- package/dist/memory/curator.js.map +1 -1
- package/dist/memory/entries.d.ts +12 -2
- package/dist/memory/entries.d.ts.map +1 -1
- package/dist/memory/entries.js +198 -114
- package/dist/memory/entries.js.map +1 -1
- package/dist/memory/federated-retrieval.d.ts +12 -1
- package/dist/memory/federated-retrieval.d.ts.map +1 -1
- package/dist/memory/federated-retrieval.js +183 -70
- package/dist/memory/federated-retrieval.js.map +1 -1
- package/dist/memory/hybrid-retrieval.d.ts +5 -11
- package/dist/memory/hybrid-retrieval.d.ts.map +1 -1
- package/dist/memory/hybrid-retrieval.js +78 -58
- package/dist/memory/hybrid-retrieval.js.map +1 -1
- package/dist/memory/lifecycle.d.ts.map +1 -1
- package/dist/memory/lifecycle.js +17 -13
- package/dist/memory/lifecycle.js.map +1 -1
- package/dist/memory/rebuild-search.d.ts +5 -0
- package/dist/memory/rebuild-search.d.ts.map +1 -1
- package/dist/memory/rebuild-search.js +101 -76
- package/dist/memory/rebuild-search.js.map +1 -1
- package/dist/memory/retrieval-query.d.ts +0 -5
- package/dist/memory/retrieval-query.d.ts.map +1 -1
- package/dist/memory/retrieval-query.js +0 -5
- package/dist/memory/retrieval-query.js.map +1 -1
- package/dist/memory/retrieval.d.ts.map +1 -1
- package/dist/memory/retrieval.js +25 -131
- package/dist/memory/retrieval.js.map +1 -1
- package/dist/memory/revisions.d.ts +76 -1
- package/dist/memory/revisions.d.ts.map +1 -1
- package/dist/memory/revisions.js +539 -35
- package/dist/memory/revisions.js.map +1 -1
- package/dist/memory/scoped-memory.d.ts +16 -1
- package/dist/memory/scoped-memory.d.ts.map +1 -1
- package/dist/memory/scoped-memory.js +240 -107
- package/dist/memory/scoped-memory.js.map +1 -1
- package/dist/memory/secrets.d.ts +2 -0
- package/dist/memory/secrets.d.ts.map +1 -1
- package/dist/memory/secrets.js +36 -0
- package/dist/memory/secrets.js.map +1 -1
- package/dist/memory/structured-memory.d.ts +3 -2
- package/dist/memory/structured-memory.d.ts.map +1 -1
- package/dist/memory/structured-memory.js +54 -22
- package/dist/memory/structured-memory.js.map +1 -1
- package/dist/memory/workspaces.d.ts +9 -0
- package/dist/memory/workspaces.d.ts.map +1 -1
- package/dist/memory/workspaces.js +67 -0
- package/dist/memory/workspaces.js.map +1 -1
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +7 -0
- package/dist/package-version.js.map +1 -0
- package/dist/repository/binding.d.ts +5 -0
- package/dist/repository/binding.d.ts.map +1 -1
- package/dist/repository/binding.js +117 -17
- package/dist/repository/binding.js.map +1 -1
- package/dist/repository/framework-version.d.ts +8 -0
- package/dist/repository/framework-version.d.ts.map +1 -0
- package/dist/repository/framework-version.js +29 -0
- package/dist/repository/framework-version.js.map +1 -0
- package/dist/repository/identity-value.d.ts +4 -0
- package/dist/repository/identity-value.d.ts.map +1 -0
- package/dist/repository/identity-value.js +24 -0
- package/dist/repository/identity-value.js.map +1 -0
- package/dist/repository/identity.d.ts.map +1 -1
- package/dist/repository/identity.js +2 -0
- package/dist/repository/identity.js.map +1 -1
- package/dist/repository/project-fingerprint.d.ts +14 -2
- package/dist/repository/project-fingerprint.d.ts.map +1 -1
- package/dist/repository/project-fingerprint.js +312 -33
- package/dist/repository/project-fingerprint.js.map +1 -1
- package/dist/repository/remote-url.d.ts +0 -1
- package/dist/repository/remote-url.d.ts.map +1 -1
- package/dist/repository/remote-url.js +0 -1
- package/dist/repository/remote-url.js.map +1 -1
- package/dist/runtime-version.d.ts +2 -1
- package/dist/runtime-version.d.ts.map +1 -1
- package/dist/runtime-version.js +21 -4
- package/dist/runtime-version.js.map +1 -1
- package/dist/serialization/boundary-json.d.ts +20 -0
- package/dist/serialization/boundary-json.d.ts.map +1 -0
- package/dist/serialization/boundary-json.js +129 -0
- package/dist/serialization/boundary-json.js.map +1 -0
- package/dist/serialization/envelope.js +1 -1
- package/dist/serialization/envelope.js.map +1 -1
- package/dist/serialization/validate.d.ts +7 -0
- package/dist/serialization/validate.d.ts.map +1 -1
- package/dist/serialization/validate.js +53 -13
- package/dist/serialization/validate.js.map +1 -1
- package/dist/server/app.js +1 -1
- package/dist/server/app.js.map +1 -1
- package/dist/server/http.d.ts +4 -3
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +90 -50
- package/dist/server/http.js.map +1 -1
- package/dist/server/idempotency.d.ts +0 -6
- package/dist/server/idempotency.d.ts.map +1 -1
- package/dist/server/idempotency.js.map +1 -1
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/router.js +21 -4
- package/dist/server/router.js.map +1 -1
- package/dist/server/routes/agent-capability-gate.d.ts +40 -0
- package/dist/server/routes/agent-capability-gate.d.ts.map +1 -0
- package/dist/server/routes/agent-capability-gate.js +182 -0
- package/dist/server/routes/agent-capability-gate.js.map +1 -0
- package/dist/server/routes/agent-events.d.ts.map +1 -1
- package/dist/server/routes/agent-events.js +8 -1
- package/dist/server/routes/agent-events.js.map +1 -1
- package/dist/server/routes/agent-intake.d.ts.map +1 -1
- package/dist/server/routes/agent-intake.js +10 -2
- package/dist/server/routes/agent-intake.js.map +1 -1
- package/dist/server/routes/agent-promotions.d.ts.map +1 -1
- package/dist/server/routes/agent-promotions.js +5 -2
- package/dist/server/routes/agent-promotions.js.map +1 -1
- package/dist/server/routes/agent-runs.d.ts.map +1 -1
- package/dist/server/routes/agent-runs.js +18 -4
- package/dist/server/routes/agent-runs.js.map +1 -1
- package/dist/server/routes/request-binding.d.ts +5 -0
- package/dist/server/routes/request-binding.d.ts.map +1 -0
- package/dist/server/routes/request-binding.js +49 -0
- package/dist/server/routes/request-binding.js.map +1 -0
- package/dist/server/routes/task5-support.d.ts +1 -8
- package/dist/server/routes/task5-support.d.ts.map +1 -1
- package/dist/server/routes/task5-support.js +1 -17
- package/dist/server/routes/task5-support.js.map +1 -1
- package/dist/server/routes/task5.d.ts.map +1 -1
- package/dist/server/routes/task5.js +106 -36
- package/dist/server/routes/task5.js.map +1 -1
- package/dist/server/write-queue.js +2 -2
- package/dist/server/write-queue.js.map +1 -1
- package/dist/setup/claude-config.d.ts +2 -1
- package/dist/setup/claude-config.d.ts.map +1 -1
- package/dist/setup/claude-config.js +54 -4
- package/dist/setup/claude-config.js.map +1 -1
- package/dist/setup/client-detection.d.ts +7 -2
- package/dist/setup/client-detection.d.ts.map +1 -1
- package/dist/setup/client-detection.js +27 -9
- package/dist/setup/client-detection.js.map +1 -1
- package/dist/setup/hermes-config.d.ts +2 -1
- package/dist/setup/hermes-config.d.ts.map +1 -1
- package/dist/setup/hermes-config.js +53 -12
- package/dist/setup/hermes-config.js.map +1 -1
- package/dist/setup/legacy-client-cleanup.d.ts +6 -0
- package/dist/setup/legacy-client-cleanup.d.ts.map +1 -0
- package/dist/setup/legacy-client-cleanup.js +152 -0
- package/dist/setup/legacy-client-cleanup.js.map +1 -0
- package/dist/setup/managed-text.d.ts.map +1 -1
- package/dist/setup/managed-text.js +11 -1
- package/dist/setup/managed-text.js.map +1 -1
- package/dist/setup/opencode-config.d.ts +2 -1
- package/dist/setup/opencode-config.d.ts.map +1 -1
- package/dist/setup/opencode-config.js +57 -5
- package/dist/setup/opencode-config.js.map +1 -1
- package/dist/setup/render.d.ts +2 -1
- package/dist/setup/render.d.ts.map +1 -1
- package/dist/setup/render.js +91 -17
- package/dist/setup/render.js.map +1 -1
- package/dist/setup/standard-skills.d.ts +16 -2
- package/dist/setup/standard-skills.d.ts.map +1 -1
- package/dist/setup/standard-skills.js +37 -13
- package/dist/setup/standard-skills.js.map +1 -1
- package/dist/setup/strict-json.d.ts +7 -0
- package/dist/setup/strict-json.d.ts.map +1 -0
- package/dist/setup/strict-json.js +98 -0
- package/dist/setup/strict-json.js.map +1 -0
- package/dist/setup/strict-toml.d.ts +7 -0
- package/dist/setup/strict-toml.d.ts.map +1 -0
- package/dist/setup/strict-toml.js +470 -0
- package/dist/setup/strict-toml.js.map +1 -0
- package/dist/skills/cache.d.ts +15 -0
- package/dist/skills/cache.d.ts.map +1 -0
- package/dist/skills/cache.js +19 -0
- package/dist/skills/cache.js.map +1 -0
- package/dist/skills/candidate-ranking.d.ts +15 -0
- package/dist/skills/candidate-ranking.d.ts.map +1 -0
- package/dist/skills/candidate-ranking.js +52 -0
- package/dist/skills/candidate-ranking.js.map +1 -0
- package/dist/skills/chunking.d.ts +11 -0
- package/dist/skills/chunking.d.ts.map +1 -0
- package/dist/skills/chunking.js +291 -0
- package/dist/skills/chunking.js.map +1 -0
- package/dist/skills/config.d.ts +19 -0
- package/dist/skills/config.d.ts.map +1 -0
- package/dist/skills/config.js +103 -0
- package/dist/skills/config.js.map +1 -0
- package/dist/skills/discovery-service.d.ts +26 -0
- package/dist/skills/discovery-service.d.ts.map +1 -0
- package/dist/skills/discovery-service.js +921 -0
- package/dist/skills/discovery-service.js.map +1 -0
- package/dist/skills/external-transport.d.ts +2 -0
- package/dist/skills/external-transport.d.ts.map +1 -0
- package/dist/skills/external-transport.js +30 -0
- package/dist/skills/external-transport.js.map +1 -0
- package/dist/skills/find.d.ts +16 -0
- package/dist/skills/find.d.ts.map +1 -0
- package/dist/skills/find.js +58 -0
- package/dist/skills/find.js.map +1 -0
- package/dist/skills/gap-detection.d.ts +23 -0
- package/dist/skills/gap-detection.d.ts.map +1 -0
- package/dist/skills/gap-detection.js +62 -0
- package/dist/skills/gap-detection.js.map +1 -0
- package/dist/skills/import-preparation.d.ts +4 -0
- package/dist/skills/import-preparation.d.ts.map +1 -0
- package/dist/skills/import-preparation.js +20 -0
- package/dist/skills/import-preparation.js.map +1 -0
- package/dist/skills/materialization-authority.d.ts +11 -0
- package/dist/skills/materialization-authority.d.ts.map +1 -0
- package/dist/skills/materialization-authority.js +92 -0
- package/dist/skills/materialization-authority.js.map +1 -0
- package/dist/skills/materialization-service.d.ts +22 -0
- package/dist/skills/materialization-service.d.ts.map +1 -0
- package/dist/skills/materialization-service.js +101 -0
- package/dist/skills/materialization-service.js.map +1 -0
- package/dist/skills/official-catalog.d.ts +31 -0
- package/dist/skills/official-catalog.d.ts.map +1 -0
- package/dist/skills/official-catalog.js +110 -0
- package/dist/skills/official-catalog.js.map +1 -0
- package/dist/skills/providers/schema.d.ts +30 -0
- package/dist/skills/providers/schema.d.ts.map +1 -0
- package/dist/skills/providers/schema.js +354 -0
- package/dist/skills/providers/schema.js.map +1 -0
- package/dist/skills/providers/skills-sh-compat.d.ts +17 -0
- package/dist/skills/providers/skills-sh-compat.d.ts.map +1 -0
- package/dist/skills/providers/skills-sh-compat.js +71 -0
- package/dist/skills/providers/skills-sh-compat.js.map +1 -0
- package/dist/skills/providers/skills-sh-v1.d.ts +23 -0
- package/dist/skills/providers/skills-sh-v1.d.ts.map +1 -0
- package/dist/skills/providers/skills-sh-v1.js +134 -0
- package/dist/skills/providers/skills-sh-v1.js.map +1 -0
- package/dist/skills/query-builder.d.ts +18 -0
- package/dist/skills/query-builder.d.ts.map +1 -0
- package/dist/skills/query-builder.js +93 -0
- package/dist/skills/query-builder.js.map +1 -0
- package/dist/skills/source/errors.d.ts +9 -0
- package/dist/skills/source/errors.d.ts.map +1 -0
- package/dist/skills/source/errors.js +15 -0
- package/dist/skills/source/errors.js.map +1 -0
- package/dist/skills/source/frontmatter.d.ts +9 -0
- package/dist/skills/source/frontmatter.d.ts.map +1 -0
- package/dist/skills/source/frontmatter.js +77 -0
- package/dist/skills/source/frontmatter.js.map +1 -0
- package/dist/skills/source/github-fetcher.d.ts +20 -0
- package/dist/skills/source/github-fetcher.d.ts.map +1 -0
- package/dist/skills/source/github-fetcher.js +292 -0
- package/dist/skills/source/github-fetcher.js.map +1 -0
- package/dist/skills/source/snapshot-validator.d.ts +28 -0
- package/dist/skills/source/snapshot-validator.d.ts.map +1 -0
- package/dist/skills/source/snapshot-validator.js +186 -0
- package/dist/skills/source/snapshot-validator.js.map +1 -0
- package/dist/skills/store.d.ts +181 -0
- package/dist/skills/store.d.ts.map +1 -0
- package/dist/skills/store.js +1710 -0
- package/dist/skills/store.js.map +1 -0
- package/dist/skills/types.d.ts +169 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/web/i18n.d.ts +32 -0
- package/dist/web/i18n.d.ts.map +1 -1
- package/dist/web/i18n.js +128 -0
- package/dist/web/i18n.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +386 -38
- package/dist/web/server.js.map +1 -1
- package/dist/web/ui.d.ts +4 -0
- package/dist/web/ui.d.ts.map +1 -1
- package/dist/web/ui.js +382 -6
- package/dist/web/ui.js.map +1 -1
- package/migrations/009_external_skill_discovery.sql +126 -0
- package/package.json +4 -3
- package/skills/kiokuko-single-purpose-functions/SKILL.md +288 -0
- package/skills/kiokuko-single-purpose-functions/references/kiokuko-patterns.md +344 -0
- package/skills/kiokuko-single-purpose-functions/references/review-checklist.md +97 -0
- package/skills/kiokuko-ui-design-soul/SKILL.md +1186 -28
- package/templates/AGENTS.md +8 -7
- package/dist/client/runtime-discovery.d.ts +0 -15
- package/dist/client/runtime-discovery.d.ts.map +0 -1
- package/dist/client/runtime-discovery.js +0 -45
- package/dist/client/runtime-discovery.js.map +0 -1
- package/dist/commands/call.d.ts +0 -7
- package/dist/commands/call.d.ts.map +0 -1
- package/dist/commands/call.js +0 -10
- package/dist/commands/call.js.map +0 -1
- package/dist/commands/link.d.ts +0 -6
- package/dist/commands/link.d.ts.map +0 -1
- package/dist/commands/link.js +0 -6
- package/dist/commands/link.js.map +0 -1
- package/dist/commands/promote.d.ts +0 -6
- package/dist/commands/promote.d.ts.map +0 -1
- package/dist/commands/promote.js +0 -6
- package/dist/commands/promote.js.map +0 -1
- package/dist/commands/read.d.ts +0 -6
- package/dist/commands/read.d.ts.map +0 -1
- package/dist/commands/read.js +0 -4
- package/dist/commands/read.js.map +0 -1
- package/dist/commands/recall.d.ts +0 -6
- package/dist/commands/recall.d.ts.map +0 -1
- package/dist/commands/recall.js +0 -4
- package/dist/commands/recall.js.map +0 -1
- package/dist/commands/record.d.ts +0 -6
- package/dist/commands/record.d.ts.map +0 -1
- package/dist/commands/record.js +0 -4
- package/dist/commands/record.js.map +0 -1
- package/dist/commands/search.d.ts +0 -6
- package/dist/commands/search.d.ts.map +0 -1
- package/dist/commands/search.js +0 -4
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/supersede.d.ts +0 -6
- package/dist/commands/supersede.d.ts.map +0 -1
- package/dist/commands/supersede.js +0 -6
- package/dist/commands/supersede.js.map +0 -1
- package/dist/knowledge/sources.d.ts +0 -72
- package/dist/knowledge/sources.d.ts.map +0 -1
- package/dist/knowledge/sources.js +0 -388
- package/dist/knowledge/sources.js.map +0 -1
- package/dist/setup/opencode-evidence.d.ts +0 -37
- package/dist/setup/opencode-evidence.d.ts.map +0 -1
- package/dist/setup/opencode-evidence.js +0 -58
- package/dist/setup/opencode-evidence.js.map +0 -1
- package/dist/setup/opencode-loop-guard.d.ts +0 -9
- package/dist/setup/opencode-loop-guard.d.ts.map +0 -1
- package/dist/setup/opencode-loop-guard.js +0 -248
- package/dist/setup/opencode-loop-guard.js.map +0 -1
package/dist/commands/setup.js
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import { access, unlink } from 'node:fs/promises';
|
|
2
1
|
import path from 'node:path';
|
|
2
|
+
import { mkdir, rmdir } from 'node:fs/promises';
|
|
3
3
|
import { createInterface } from 'node:readline/promises';
|
|
4
4
|
import { stdin, stdout } from 'node:process';
|
|
5
|
-
import {
|
|
6
|
-
import { getClaudeInstructionsPath, getClaudeMcpConfigPath, getClaudeSkillsDirectory, getCodexConfigPath, getCodexInstructionsPath, getCodexSkillsDirectory, getGlobalDatabasePath,
|
|
5
|
+
import { atomicWriteTextIfUnchanged, assertAtomicCleanupComplete, AtomicCommittedMutationError, AtomicCommittedUnlinkError, assertFileExpectation, readDirectoryIdentity, readRegularFile, unlinkRegularFileIfUnchanged, } from '../agent-file/atomic-write.js';
|
|
6
|
+
import { getClaudeInstructionsPath, getClaudeMcpConfigPath, getClaudeSkillsDirectory, getCodexConfigPath, getCodexInstructionsPath, getCodexSkillsDirectory, getGlobalDatabasePath, getLegacyClaudePromptHookSettingsPath, getLegacyOpenCodeLoopGuardPath, getOpenCodeConfigDirectory, getOpenCodeInstructionsPath, getOpenCodeSkillsDirectory, resolveHermesProfilePaths, } from '../config/paths.js';
|
|
7
7
|
import { initializeDatabase } from './init.js';
|
|
8
8
|
import { openConnection } from '../db/connection.js';
|
|
9
9
|
import { ensureGlobalWorkspace } from '../memory/workspaces.js';
|
|
10
10
|
import { KiokukoError } from '../errors.js';
|
|
11
|
+
import { isSkillDiscoveryMode, normalizeSkillDiscoveryMode, SKILL_DISCOVERY_ENV } from '../skills/config.js';
|
|
11
12
|
import { renderOpenCodeConfig } from '../setup/opencode-config.js';
|
|
12
|
-
import { renderOpenCodeLoopGuard } from '../setup/opencode-loop-guard.js';
|
|
13
13
|
import { renderCodexMcpConfig, renderGlobalInstructions } from '../setup/render.js';
|
|
14
14
|
import { renderClaudeConfig } from '../setup/claude-config.js';
|
|
15
15
|
import { renderHermesConfig } from '../setup/hermes-config.js';
|
|
16
16
|
import { detectInstalledClients } from '../setup/client-detection.js';
|
|
17
|
-
import {
|
|
17
|
+
import { assertExactLegacyOpenCodeLoopGuard, cleanupLegacyClaudePromptHook, } from '../setup/legacy-client-cleanup.js';
|
|
18
|
+
import { loadBundledStandardSkillFiles, renderStandardSkillFile, } from '../setup/standard-skills.js';
|
|
18
19
|
export const SETUP_CLIENTS = ['codex', 'opencode', 'claude', 'hermes'];
|
|
20
|
+
function setupPathJoin(options, ...segments) {
|
|
21
|
+
const platform = options.platform ?? process.platform;
|
|
22
|
+
return platform === 'win32' ? path.win32.join(...segments) : path.posix.join(...segments);
|
|
23
|
+
}
|
|
19
24
|
export function parseSetupClients(value) {
|
|
20
25
|
const clients = [...new Set(value.split(',').map((client) => client.trim()).filter(Boolean))];
|
|
21
26
|
if (clients.length === 0 || clients.some((client) => !SETUP_CLIENTS.includes(client))) {
|
|
@@ -23,6 +28,12 @@ export function parseSetupClients(value) {
|
|
|
23
28
|
}
|
|
24
29
|
return clients;
|
|
25
30
|
}
|
|
31
|
+
export function parseSetupSkillDiscoveryMode(value) {
|
|
32
|
+
if (!isSkillDiscoveryMode(value)) {
|
|
33
|
+
throw new KiokukoError('VALIDATION_ERROR', 'skill discovery must be off, official, or community');
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
26
37
|
function setupClientLabel(client) {
|
|
27
38
|
if (client === 'codex')
|
|
28
39
|
return 'Codex';
|
|
@@ -32,92 +43,287 @@ function setupClientLabel(client) {
|
|
|
32
43
|
return 'Claude Code';
|
|
33
44
|
return 'Hermes Agent';
|
|
34
45
|
}
|
|
46
|
+
async function askSetupClients(prompt, output, detected) {
|
|
47
|
+
const defaultSelection = detected.length === 0 ? 'none' : detected.join(',');
|
|
48
|
+
output.write('Select clients to configure (detected clients are preselected):\n');
|
|
49
|
+
for (const [index, client] of SETUP_CLIENTS.entries()) {
|
|
50
|
+
const checked = detected.includes(client) ? 'x' : ' ';
|
|
51
|
+
const status = detected.includes(client) ? 'detected' : 'not detected';
|
|
52
|
+
output.write(` ${index + 1}. [${checked}] ${setupClientLabel(client)} (${status})\n`);
|
|
53
|
+
}
|
|
54
|
+
output.write('Enter client names or numbers separated by commas. Press Enter to accept the checked clients; type none to skip all.\n');
|
|
55
|
+
while (true) {
|
|
56
|
+
const answer = (await prompt.question(`Clients [${defaultSelection}]: `)).trim();
|
|
57
|
+
if (answer.length === 0)
|
|
58
|
+
return detected;
|
|
59
|
+
if (/^(?:none|なし)$/iu.test(answer))
|
|
60
|
+
return [];
|
|
61
|
+
const selected = [];
|
|
62
|
+
let invalid = false;
|
|
63
|
+
for (const token of answer.split(',').map((value) => value.trim()).filter(Boolean)) {
|
|
64
|
+
const index = Number(token);
|
|
65
|
+
const indexedClient = Number.isInteger(index) && index >= 1 && index <= SETUP_CLIENTS.length
|
|
66
|
+
? SETUP_CLIENTS[index - 1]
|
|
67
|
+
: undefined;
|
|
68
|
+
const client = indexedClient ?? token.toLowerCase();
|
|
69
|
+
if (!SETUP_CLIENTS.includes(client)) {
|
|
70
|
+
invalid = true;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
selected.push(client);
|
|
74
|
+
}
|
|
75
|
+
if (!invalid)
|
|
76
|
+
return [...new Set(selected)];
|
|
77
|
+
output.write(`Invalid selection. Choose names or numbers for: ${SETUP_CLIENTS.join(', ')}.\n`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function askCommunitySkillDiscovery(prompt, output) {
|
|
81
|
+
output.write('Official external Skill discovery is enabled by default and uses validated content only as untrusted references. It never installs or executes Skills.\n');
|
|
82
|
+
output.write('Community discovery can also use audited community Skills as untrusted references when relevant.\n');
|
|
83
|
+
const answer = (await prompt.question('Enable community Skill discovery? [y/N] ')).trim();
|
|
84
|
+
return /^(?:y|yes|はい)$/iu.test(answer) ? 'community' : 'official';
|
|
85
|
+
}
|
|
35
86
|
/** Ask which supported clients should receive configuration in an interactive terminal. */
|
|
36
87
|
export async function promptSetupClients(detected, options = {}) {
|
|
37
88
|
const input = options.input ?? stdin;
|
|
38
89
|
const output = options.output ?? stdout;
|
|
39
90
|
const prompt = createInterface({ input, output });
|
|
40
|
-
const defaultSelection = detected.length === 0 ? 'none' : detected.join(',');
|
|
41
91
|
try {
|
|
42
|
-
|
|
43
|
-
for (const [index, client] of SETUP_CLIENTS.entries()) {
|
|
44
|
-
const checked = detected.includes(client) ? 'x' : ' ';
|
|
45
|
-
const status = detected.includes(client) ? 'detected' : 'not detected';
|
|
46
|
-
output.write(` ${index + 1}. [${checked}] ${setupClientLabel(client)} (${status})\n`);
|
|
47
|
-
}
|
|
48
|
-
output.write('Enter client names or numbers separated by commas. Press Enter to accept the checked clients; type none to skip all.\n');
|
|
49
|
-
while (true) {
|
|
50
|
-
const answer = (await prompt.question(`Clients [${defaultSelection}]: `)).trim();
|
|
51
|
-
if (answer.length === 0)
|
|
52
|
-
return detected;
|
|
53
|
-
if (/^(?:none|なし)$/iu.test(answer))
|
|
54
|
-
return [];
|
|
55
|
-
const selected = [];
|
|
56
|
-
let invalid = false;
|
|
57
|
-
for (const token of answer.split(',').map((value) => value.trim()).filter(Boolean)) {
|
|
58
|
-
const index = Number(token);
|
|
59
|
-
const indexedClient = Number.isInteger(index) && index >= 1 && index <= SETUP_CLIENTS.length
|
|
60
|
-
? SETUP_CLIENTS[index - 1]
|
|
61
|
-
: undefined;
|
|
62
|
-
const client = indexedClient ?? token.toLowerCase();
|
|
63
|
-
if (!SETUP_CLIENTS.includes(client)) {
|
|
64
|
-
invalid = true;
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
selected.push(client);
|
|
68
|
-
}
|
|
69
|
-
if (!invalid)
|
|
70
|
-
return [...new Set(selected)];
|
|
71
|
-
output.write(`Invalid selection. Choose names or numbers for: ${SETUP_CLIENTS.join(', ')}.\n`);
|
|
72
|
-
}
|
|
92
|
+
return await askSetupClients(prompt, output, detected);
|
|
73
93
|
}
|
|
74
94
|
finally {
|
|
75
95
|
prompt.close();
|
|
76
96
|
}
|
|
77
97
|
}
|
|
78
|
-
|
|
98
|
+
/** Ask whether audited community Skill discovery should be enabled. */
|
|
99
|
+
export async function promptCommunitySkillDiscovery(options = {}) {
|
|
100
|
+
const input = options.input ?? stdin;
|
|
101
|
+
const output = options.output ?? stdout;
|
|
102
|
+
const prompt = createInterface({ input, output });
|
|
79
103
|
try {
|
|
80
|
-
await
|
|
81
|
-
return true;
|
|
104
|
+
return await askCommunitySkillDiscovery(prompt, output);
|
|
82
105
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
106
|
+
finally {
|
|
107
|
+
prompt.close();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Ask both setup questions through one readline session so buffered input remains intact. */
|
|
111
|
+
export async function promptSetupConfiguration(detected, options = {}) {
|
|
112
|
+
const input = options.input ?? stdin;
|
|
113
|
+
const output = options.output ?? stdout;
|
|
114
|
+
const prompt = createInterface({ input, output });
|
|
115
|
+
try {
|
|
116
|
+
const clients = await askSetupClients(prompt, output, detected);
|
|
117
|
+
const skillDiscoveryMode = clients.length === 0
|
|
118
|
+
? 'official'
|
|
119
|
+
: await askCommunitySkillDiscovery(prompt, output);
|
|
120
|
+
return { clients, skillDiscoveryMode };
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
prompt.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function sameFileIdentity(left, right) {
|
|
127
|
+
return left.device === right.device && left.inode === right.inode;
|
|
128
|
+
}
|
|
129
|
+
function setupDirectoryChanged(directoryPath) {
|
|
130
|
+
return new KiokukoError('CONFLICT', 'Setup directory changed after planning', { target: directoryPath });
|
|
131
|
+
}
|
|
132
|
+
function plannedDirectoryIdentity(directory) {
|
|
133
|
+
return directory.original ?? directory.created;
|
|
134
|
+
}
|
|
135
|
+
function directoryLineage(directory) {
|
|
136
|
+
const lineage = [];
|
|
137
|
+
let current = directory;
|
|
138
|
+
while (current !== undefined) {
|
|
139
|
+
lineage.push(current);
|
|
140
|
+
current = current.parent;
|
|
141
|
+
}
|
|
142
|
+
return lineage.reverse();
|
|
143
|
+
}
|
|
144
|
+
async function assertPlannedDirectory(directory) {
|
|
145
|
+
for (const planned of directoryLineage(directory)) {
|
|
146
|
+
const current = await readDirectoryIdentity(planned.path);
|
|
147
|
+
const expected = plannedDirectoryIdentity(planned);
|
|
148
|
+
if ((current === undefined) !== (expected === undefined)
|
|
149
|
+
|| (current !== undefined && expected !== undefined && !sameFileIdentity(current, expected))) {
|
|
150
|
+
throw setupDirectoryChanged(planned.path);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async function planDirectory(planning, directoryPath) {
|
|
155
|
+
const resolved = path.resolve(directoryPath);
|
|
156
|
+
const existing = planning.directories.get(resolved);
|
|
157
|
+
if (existing !== undefined)
|
|
158
|
+
return existing;
|
|
159
|
+
const original = await readDirectoryIdentity(resolved);
|
|
160
|
+
const parentPath = path.dirname(resolved);
|
|
161
|
+
const parent = original !== undefined || parentPath === resolved
|
|
162
|
+
? undefined
|
|
163
|
+
: await planDirectory(planning, parentPath);
|
|
164
|
+
const planned = {
|
|
165
|
+
path: resolved,
|
|
166
|
+
parent,
|
|
167
|
+
original,
|
|
168
|
+
created: undefined,
|
|
169
|
+
};
|
|
170
|
+
planning.directories.set(resolved, planned);
|
|
171
|
+
return planned;
|
|
172
|
+
}
|
|
173
|
+
async function readPlannedRegularFile(planning, filePath) {
|
|
174
|
+
const parentDirectory = await planDirectory(planning, path.dirname(filePath));
|
|
175
|
+
await assertPlannedDirectory(parentDirectory);
|
|
176
|
+
const snapshot = await readRegularFile(filePath);
|
|
177
|
+
await assertPlannedDirectory(parentDirectory);
|
|
178
|
+
return { parentDirectory, snapshot };
|
|
179
|
+
}
|
|
180
|
+
function errno(error) {
|
|
181
|
+
return error instanceof Error && 'code' in error
|
|
182
|
+
? String(error.code)
|
|
183
|
+
: undefined;
|
|
184
|
+
}
|
|
185
|
+
async function preparePlannedDirectories(files, createdDirectories) {
|
|
186
|
+
const required = new Set();
|
|
187
|
+
for (const file of files) {
|
|
188
|
+
if (file.action === 'unchanged')
|
|
189
|
+
continue;
|
|
190
|
+
for (const directory of directoryLineage(file.parentDirectory))
|
|
191
|
+
required.add(directory);
|
|
192
|
+
}
|
|
193
|
+
const ordered = [...required].sort((left, right) => directoryLineage(left).length - directoryLineage(right).length);
|
|
194
|
+
for (const directory of ordered) {
|
|
195
|
+
const expected = plannedDirectoryIdentity(directory);
|
|
196
|
+
if (expected !== undefined) {
|
|
197
|
+
await assertPlannedDirectory(directory);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (directory.parent === undefined) {
|
|
201
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Setup cannot create a missing filesystem root');
|
|
202
|
+
}
|
|
203
|
+
await assertPlannedDirectory(directory.parent);
|
|
204
|
+
if (await readDirectoryIdentity(directory.path) !== undefined) {
|
|
205
|
+
throw setupDirectoryChanged(directory.path);
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
await mkdir(directory.path, { mode: 0o700 });
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
if (errno(error) === 'EEXIST')
|
|
212
|
+
throw setupDirectoryChanged(directory.path);
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
const created = await readDirectoryIdentity(directory.path);
|
|
216
|
+
if (created === undefined) {
|
|
217
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Setup directory disappeared immediately after creation', {
|
|
218
|
+
target: directory.path,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
directory.created = created;
|
|
222
|
+
createdDirectories.push(directory);
|
|
223
|
+
await assertPlannedDirectory(directory);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async function removeCreatedDirectories(createdDirectories) {
|
|
227
|
+
const failures = [];
|
|
228
|
+
for (const directory of [...createdDirectories].reverse()) {
|
|
229
|
+
try {
|
|
230
|
+
await assertPlannedDirectory(directory);
|
|
231
|
+
await rmdir(directory.path);
|
|
232
|
+
if (await readDirectoryIdentity(directory.path) !== undefined) {
|
|
233
|
+
throw setupDirectoryChanged(directory.path);
|
|
234
|
+
}
|
|
235
|
+
directory.created = undefined;
|
|
236
|
+
if (directory.parent !== undefined)
|
|
237
|
+
await assertPlannedDirectory(directory.parent);
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
failures.push(error);
|
|
241
|
+
}
|
|
87
242
|
}
|
|
243
|
+
return failures;
|
|
88
244
|
}
|
|
89
|
-
async function planFile(filePath, client, purpose, render) {
|
|
90
|
-
const original = await
|
|
245
|
+
async function planFile(planning, filePath, client, purpose, render, mustRemainAbsent = []) {
|
|
246
|
+
const { parentDirectory, snapshot: original } = await readPlannedRegularFile(planning, filePath);
|
|
91
247
|
const rendered = render(original?.content);
|
|
92
248
|
const action = original === undefined
|
|
93
249
|
? 'created'
|
|
94
250
|
: rendered.content === original.content ? 'unchanged' : 'updated';
|
|
95
251
|
return {
|
|
96
252
|
path: filePath,
|
|
253
|
+
parentDirectory,
|
|
97
254
|
content: rendered.content,
|
|
98
255
|
mode: original?.mode ?? 0o600,
|
|
99
|
-
original
|
|
256
|
+
original,
|
|
257
|
+
...(mustRemainAbsent.length === 0 ? {} : { mustRemainAbsent }),
|
|
100
258
|
action,
|
|
101
259
|
purpose,
|
|
102
260
|
client,
|
|
261
|
+
report: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
async function planLegacyClaudeHookCleanup(planning, options) {
|
|
265
|
+
const filePath = getLegacyClaudePromptHookSettingsPath(options);
|
|
266
|
+
const { parentDirectory, snapshot: original } = await readPlannedRegularFile(planning, filePath);
|
|
267
|
+
const content = original === undefined ? undefined : cleanupLegacyClaudePromptHook(original.content);
|
|
268
|
+
const changed = original !== undefined && content !== original.content;
|
|
269
|
+
return {
|
|
270
|
+
path: filePath,
|
|
271
|
+
parentDirectory,
|
|
272
|
+
content,
|
|
273
|
+
mode: original?.mode ?? 0o600,
|
|
274
|
+
original,
|
|
275
|
+
action: changed ? 'updated' : 'unchanged',
|
|
276
|
+
purpose: 'legacy-cleanup',
|
|
277
|
+
client: 'claude',
|
|
278
|
+
report: changed,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
async function planLegacyOpenCodeGuardCleanup(planning, options) {
|
|
282
|
+
const filePath = getLegacyOpenCodeLoopGuardPath(options);
|
|
283
|
+
const { parentDirectory, snapshot: original } = await readPlannedRegularFile(planning, filePath);
|
|
284
|
+
if (original !== undefined)
|
|
285
|
+
assertExactLegacyOpenCodeLoopGuard(original.content);
|
|
286
|
+
return {
|
|
287
|
+
path: filePath,
|
|
288
|
+
parentDirectory,
|
|
289
|
+
content: undefined,
|
|
290
|
+
mode: original?.mode ?? 0o600,
|
|
291
|
+
original,
|
|
292
|
+
action: original === undefined ? 'unchanged' : 'deleted',
|
|
293
|
+
purpose: 'legacy-cleanup',
|
|
294
|
+
client: 'opencode',
|
|
295
|
+
report: original !== undefined,
|
|
103
296
|
};
|
|
104
297
|
}
|
|
105
|
-
async function openCodeConfigPath(options) {
|
|
298
|
+
async function openCodeConfigPath(planning, options) {
|
|
106
299
|
const directory = getOpenCodeConfigDirectory(options);
|
|
107
|
-
const jsonc =
|
|
108
|
-
if (await
|
|
109
|
-
return jsonc;
|
|
110
|
-
|
|
300
|
+
const jsonc = setupPathJoin(options, directory, 'opencode.jsonc');
|
|
301
|
+
if ((await readPlannedRegularFile(planning, jsonc)).snapshot !== undefined) {
|
|
302
|
+
return { path: jsonc, mustRemainAbsent: [] };
|
|
303
|
+
}
|
|
304
|
+
return { path: setupPathJoin(options, directory, 'opencode.json'), mustRemainAbsent: [jsonc] };
|
|
111
305
|
}
|
|
112
|
-
async function restoreFiles(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
306
|
+
async function restoreFiles(mutations, dependencies) {
|
|
307
|
+
const failures = [];
|
|
308
|
+
for (const mutation of [...mutations].reverse()) {
|
|
309
|
+
const { file, installed } = mutation;
|
|
310
|
+
try {
|
|
311
|
+
if (file.original === undefined) {
|
|
312
|
+
if (installed === undefined)
|
|
313
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Setup rollback record is invalid');
|
|
314
|
+
const outcome = await dependencies.unlinkRegularFileIfUnchanged(file.path, fileExpectation(file, installed, false));
|
|
315
|
+
assertAtomicCleanupComplete(outcome);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
const outcome = await dependencies.atomicWriteTextIfUnchanged(file.path, file.original.content, fileExpectation(file, installed, false), file.original.mode);
|
|
319
|
+
assertAtomicCleanupComplete(outcome);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
failures.push(error);
|
|
324
|
+
}
|
|
120
325
|
}
|
|
326
|
+
return failures;
|
|
121
327
|
}
|
|
122
328
|
function setupNextStep(clients, standardSkills) {
|
|
123
329
|
return clients.map((client) => {
|
|
@@ -130,55 +336,118 @@ function setupNextStep(clients, standardSkills) {
|
|
|
130
336
|
return `Restart ${label} so it reloads global MCP and instruction configuration${standardSkills ? ' and standard skills' : ''}.`;
|
|
131
337
|
}).join(' ');
|
|
132
338
|
}
|
|
133
|
-
async function standardSkillDirectory(client, options) {
|
|
339
|
+
async function standardSkillDirectory(client, options, hermesProfile) {
|
|
134
340
|
if (client === 'codex')
|
|
135
341
|
return getCodexSkillsDirectory(options);
|
|
136
342
|
if (client === 'opencode')
|
|
137
343
|
return getOpenCodeSkillsDirectory(options);
|
|
138
344
|
if (client === 'claude')
|
|
139
345
|
return getClaudeSkillsDirectory(options);
|
|
140
|
-
|
|
346
|
+
if (hermesProfile === undefined)
|
|
347
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Hermes profile was not bound during setup planning');
|
|
348
|
+
return hermesProfile.skillsDirectory;
|
|
349
|
+
}
|
|
350
|
+
function fileExpectation(file, expected, includeAlternatePaths = true) {
|
|
351
|
+
const expectedParentDirectory = plannedDirectoryIdentity(file.parentDirectory);
|
|
352
|
+
if (expectedParentDirectory === undefined) {
|
|
353
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Setup file parent was not created or bound before mutation', {
|
|
354
|
+
target: file.parentDirectory.path,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
expected,
|
|
359
|
+
expectedParentDirectory,
|
|
360
|
+
...(includeAlternatePaths && file.mustRemainAbsent !== undefined
|
|
361
|
+
? { mustRemainAbsent: file.mustRemainAbsent }
|
|
362
|
+
: {}),
|
|
363
|
+
};
|
|
141
364
|
}
|
|
142
|
-
|
|
365
|
+
async function assertPlannedFile(file, expected) {
|
|
366
|
+
await assertPlannedDirectory(file.parentDirectory);
|
|
367
|
+
if (plannedDirectoryIdentity(file.parentDirectory) === undefined) {
|
|
368
|
+
if (expected !== undefined || await readRegularFile(file.path) !== undefined) {
|
|
369
|
+
throw setupDirectoryChanged(file.parentDirectory.path);
|
|
370
|
+
}
|
|
371
|
+
for (const absentPath of file.mustRemainAbsent ?? []) {
|
|
372
|
+
if (await readRegularFile(absentPath) !== undefined) {
|
|
373
|
+
throw new KiokukoError('CONFLICT', 'Setup target changed after planning', { target: absentPath });
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
await assertFileExpectation(file.path, fileExpectation(file, expected));
|
|
379
|
+
}
|
|
380
|
+
await assertPlannedDirectory(file.parentDirectory);
|
|
381
|
+
}
|
|
382
|
+
async function assertPlannedFiles(files, applied = []) {
|
|
383
|
+
const installedByPath = new Map(applied.map((mutation) => [mutation.file.path, mutation.installed]));
|
|
384
|
+
for (const file of files) {
|
|
385
|
+
const expected = installedByPath.has(file.path) ? installedByPath.get(file.path) : file.original;
|
|
386
|
+
await assertPlannedFile(file, expected);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
export async function setupGlobalClients(options = {}, dependencyOverrides = {}) {
|
|
390
|
+
const dependencies = {
|
|
391
|
+
atomicWriteTextIfUnchanged: dependencyOverrides.atomicWriteTextIfUnchanged ?? atomicWriteTextIfUnchanged,
|
|
392
|
+
unlinkRegularFileIfUnchanged: dependencyOverrides.unlinkRegularFileIfUnchanged ?? unlinkRegularFileIfUnchanged,
|
|
393
|
+
beforeCommit: dependencyOverrides.beforeCommit ?? (() => undefined),
|
|
394
|
+
openConnection: dependencyOverrides.openConnection ?? openConnection,
|
|
395
|
+
ensureGlobalWorkspace: dependencyOverrides.ensureGlobalWorkspace ?? ensureGlobalWorkspace,
|
|
396
|
+
};
|
|
143
397
|
const pathEnvironment = {
|
|
144
398
|
...(options.platform === undefined ? {} : { platform: options.platform }),
|
|
145
399
|
...(options.env === undefined ? {} : { env: options.env }),
|
|
146
400
|
};
|
|
401
|
+
if (options.skillDiscoveryMode !== undefined && !isSkillDiscoveryMode(options.skillDiscoveryMode)) {
|
|
402
|
+
throw new KiokukoError('VALIDATION_ERROR', 'skill discovery must be off, official, or community');
|
|
403
|
+
}
|
|
147
404
|
const clients = options.clients ?? await detectInstalledClients(pathEnvironment);
|
|
148
|
-
if (clients.some((client) => !SETUP_CLIENTS.includes(client))) {
|
|
405
|
+
if (!Array.isArray(clients) || clients.some((client) => !SETUP_CLIENTS.includes(client))) {
|
|
149
406
|
throw new KiokukoError('VALIDATION_ERROR', `clients must be a subset of: ${SETUP_CLIENTS.join(', ')}`);
|
|
150
407
|
}
|
|
151
408
|
const command = options.command ?? 'kiokuko';
|
|
152
|
-
if (command.trim().length === 0 || command.includes('\0'))
|
|
409
|
+
if (typeof command !== 'string' || command.trim().length === 0 || command.includes('\0')) {
|
|
153
410
|
throw new KiokukoError('VALIDATION_ERROR', 'command must be a non-empty executable path or name');
|
|
411
|
+
}
|
|
154
412
|
const databasePath = options.databasePath ?? getGlobalDatabasePath(pathEnvironment);
|
|
155
413
|
const standardSkills = options.standardSkills ?? true;
|
|
414
|
+
const environment = options.env ?? process.env;
|
|
415
|
+
const environmentSkillDiscoveryMode = options.skillDiscoveryMode === undefined
|
|
416
|
+
&& Object.prototype.hasOwnProperty.call(environment, SKILL_DISCOVERY_ENV)
|
|
417
|
+
? normalizeSkillDiscoveryMode(environment[SKILL_DISCOVERY_ENV])
|
|
418
|
+
: undefined;
|
|
419
|
+
const skillDiscoveryMode = options.skillDiscoveryMode ?? environmentSkillDiscoveryMode;
|
|
156
420
|
const files = [];
|
|
421
|
+
const planning = { directories: new Map() };
|
|
422
|
+
const hermesProfile = clients.includes('hermes')
|
|
423
|
+
? await resolveHermesProfilePaths(pathEnvironment)
|
|
424
|
+
: undefined;
|
|
157
425
|
if (clients.includes('codex')) {
|
|
158
|
-
files.push(await planFile(getCodexConfigPath(pathEnvironment), 'codex', 'mcp-config', (existing) => renderCodexMcpConfig(existing ?? '', command)));
|
|
159
|
-
files.push(await planFile(getCodexInstructionsPath(pathEnvironment), 'codex', 'instructions', (existing) => renderGlobalInstructions(existing ?? '')));
|
|
426
|
+
files.push(await planFile(planning, getCodexConfigPath(pathEnvironment), 'codex', 'mcp-config', (existing) => renderCodexMcpConfig(existing ?? '', command, skillDiscoveryMode)));
|
|
427
|
+
files.push(await planFile(planning, getCodexInstructionsPath(pathEnvironment), 'codex', 'instructions', (existing) => renderGlobalInstructions(existing ?? '')));
|
|
160
428
|
}
|
|
161
429
|
if (clients.includes('opencode')) {
|
|
162
|
-
|
|
163
|
-
files.push(await planFile(
|
|
164
|
-
files.push(await planFile(
|
|
165
|
-
|
|
166
|
-
...(options.opencodeMode === undefined ? {} : { mode: options.opencodeMode }),
|
|
167
|
-
})));
|
|
430
|
+
const selectedConfig = await openCodeConfigPath(planning, pathEnvironment);
|
|
431
|
+
files.push(await planFile(planning, selectedConfig.path, 'opencode', 'mcp-config', (existing) => renderOpenCodeConfig(existing, command, skillDiscoveryMode), selectedConfig.mustRemainAbsent));
|
|
432
|
+
files.push(await planFile(planning, getOpenCodeInstructionsPath(pathEnvironment), 'opencode', 'instructions', (existing) => renderGlobalInstructions(existing ?? '')));
|
|
433
|
+
files.push(await planLegacyOpenCodeGuardCleanup(planning, pathEnvironment));
|
|
168
434
|
}
|
|
169
435
|
if (clients.includes('claude')) {
|
|
170
|
-
files.push(await planFile(getClaudeMcpConfigPath(pathEnvironment), 'claude', 'mcp-config', (existing) => renderClaudeConfig(existing, command)));
|
|
171
|
-
files.push(await planFile(getClaudeInstructionsPath(pathEnvironment), 'claude', 'instructions', (existing) => renderGlobalInstructions(existing ?? '')));
|
|
436
|
+
files.push(await planFile(planning, getClaudeMcpConfigPath(pathEnvironment), 'claude', 'mcp-config', (existing) => renderClaudeConfig(existing, command, skillDiscoveryMode)));
|
|
437
|
+
files.push(await planFile(planning, getClaudeInstructionsPath(pathEnvironment), 'claude', 'instructions', (existing) => renderGlobalInstructions(existing ?? '')));
|
|
438
|
+
files.push(await planLegacyClaudeHookCleanup(planning, pathEnvironment));
|
|
172
439
|
}
|
|
173
440
|
if (clients.includes('hermes')) {
|
|
174
|
-
|
|
441
|
+
if (hermesProfile === undefined)
|
|
442
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Hermes profile was not bound during setup planning');
|
|
443
|
+
files.push(await planFile(planning, hermesProfile.configPath, 'hermes', 'mcp-config', (existing) => renderHermesConfig(existing, command, skillDiscoveryMode)));
|
|
175
444
|
}
|
|
176
445
|
if (standardSkills) {
|
|
177
446
|
const bundledFiles = await loadBundledStandardSkillFiles();
|
|
178
447
|
for (const client of clients) {
|
|
179
|
-
const
|
|
448
|
+
const skillsDirectory = await standardSkillDirectory(client, pathEnvironment, hermesProfile);
|
|
180
449
|
for (const bundled of bundledFiles) {
|
|
181
|
-
files.push(await planFile(
|
|
450
|
+
files.push(await planFile(planning, setupPathJoin(pathEnvironment, skillsDirectory, bundled.skillName, bundled.relativePath), client, 'standard-skill', (existing) => renderStandardSkillFile(existing, bundled)));
|
|
182
451
|
}
|
|
183
452
|
}
|
|
184
453
|
}
|
|
@@ -188,7 +457,9 @@ export async function setupGlobalClients(options = {}) {
|
|
|
188
457
|
databaseAction: options.dryRun ? 'planned' : 'initialized',
|
|
189
458
|
databaseBackupPath: null,
|
|
190
459
|
appliedMigrations: [],
|
|
191
|
-
files: files
|
|
460
|
+
files: files
|
|
461
|
+
.filter((file) => file.report)
|
|
462
|
+
.map(({ path: filePath, action, purpose, client }) => ({ path: filePath, action, purpose, client })),
|
|
192
463
|
standardSkills,
|
|
193
464
|
dryRun: options.dryRun ?? false,
|
|
194
465
|
nextStep: setupNextStep(clients, standardSkills),
|
|
@@ -201,24 +472,85 @@ export async function setupGlobalClients(options = {}) {
|
|
|
201
472
|
});
|
|
202
473
|
result.databaseBackupPath = initialized.backupPath;
|
|
203
474
|
result.appliedMigrations = initialized.applied;
|
|
204
|
-
const database = openConnection(databasePath);
|
|
475
|
+
const database = dependencies.openConnection(databasePath);
|
|
476
|
+
let workspaceInitializationFailed = false;
|
|
477
|
+
let workspaceInitializationError;
|
|
205
478
|
try {
|
|
206
|
-
ensureGlobalWorkspace(database);
|
|
479
|
+
dependencies.ensureGlobalWorkspace(database);
|
|
207
480
|
}
|
|
208
|
-
|
|
481
|
+
catch (error) {
|
|
482
|
+
workspaceInitializationFailed = true;
|
|
483
|
+
workspaceInitializationError = error;
|
|
484
|
+
}
|
|
485
|
+
try {
|
|
209
486
|
database.close();
|
|
210
487
|
}
|
|
211
|
-
|
|
488
|
+
catch (closeError) {
|
|
489
|
+
if (workspaceInitializationFailed) {
|
|
490
|
+
throw new AggregateError([workspaceInitializationError, closeError], 'Global workspace initialization failed and closing the database connection also failed');
|
|
491
|
+
}
|
|
492
|
+
throw closeError;
|
|
493
|
+
}
|
|
494
|
+
if (workspaceInitializationFailed)
|
|
495
|
+
throw workspaceInitializationError;
|
|
496
|
+
const applied = [];
|
|
497
|
+
const createdDirectories = [];
|
|
212
498
|
try {
|
|
499
|
+
await dependencies.beforeCommit();
|
|
500
|
+
await preparePlannedDirectories(files, createdDirectories);
|
|
501
|
+
await assertPlannedFiles(files);
|
|
213
502
|
for (const file of files) {
|
|
214
503
|
if (file.action === 'unchanged')
|
|
215
504
|
continue;
|
|
216
|
-
|
|
217
|
-
|
|
505
|
+
// Record a committed mutation before inspecting its cleanup outcome so
|
|
506
|
+
// rollback never loses ownership of a target that already changed.
|
|
507
|
+
let installed;
|
|
508
|
+
if (file.action === 'deleted') {
|
|
509
|
+
if (file.original === undefined)
|
|
510
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Setup deletion plan is missing original content');
|
|
511
|
+
let outcome;
|
|
512
|
+
try {
|
|
513
|
+
outcome = await dependencies.unlinkRegularFileIfUnchanged(file.path, fileExpectation(file, file.original));
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
if (error instanceof AtomicCommittedUnlinkError) {
|
|
517
|
+
applied.push({ file, installed: undefined });
|
|
518
|
+
}
|
|
519
|
+
throw error;
|
|
520
|
+
}
|
|
521
|
+
applied.push({ file, installed: undefined });
|
|
522
|
+
assertAtomicCleanupComplete(outcome);
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
if (file.content === undefined)
|
|
526
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Setup file plan is missing rendered content');
|
|
527
|
+
let outcome;
|
|
528
|
+
try {
|
|
529
|
+
outcome = await dependencies.atomicWriteTextIfUnchanged(file.path, file.content, fileExpectation(file, file.original), file.mode);
|
|
530
|
+
}
|
|
531
|
+
catch (error) {
|
|
532
|
+
if (error instanceof AtomicCommittedMutationError) {
|
|
533
|
+
applied.push({ file, installed: error.outcome.installed });
|
|
534
|
+
}
|
|
535
|
+
else if (error instanceof AtomicCommittedUnlinkError) {
|
|
536
|
+
applied.push({ file, installed: undefined });
|
|
537
|
+
}
|
|
538
|
+
throw error;
|
|
539
|
+
}
|
|
540
|
+
installed = outcome.installed;
|
|
541
|
+
applied.push({ file, installed });
|
|
542
|
+
assertAtomicCleanupComplete(outcome);
|
|
543
|
+
}
|
|
218
544
|
}
|
|
545
|
+
await assertPlannedFiles(files, applied);
|
|
219
546
|
}
|
|
220
547
|
catch (error) {
|
|
221
|
-
await restoreFiles(
|
|
548
|
+
const restorationFailures = await restoreFiles(applied, dependencies);
|
|
549
|
+
const directoryRestorationFailures = await removeCreatedDirectories(createdDirectories);
|
|
550
|
+
const failures = [...restorationFailures, ...directoryRestorationFailures];
|
|
551
|
+
if (failures.length > 0) {
|
|
552
|
+
throw new AggregateError([error, ...failures], 'Setup failed and filesystem restoration also failed');
|
|
553
|
+
}
|
|
222
554
|
throw error;
|
|
223
555
|
}
|
|
224
556
|
return result;
|