cc-codeconductor 1.2.0 → 1.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/README.md +30 -10
- package/dist/core/config/codeconductor-config.d.ts +2 -1
- package/dist/core/presets/package-paths.d.ts +1 -0
- package/dist/core/runner/runner-target.d.ts +32 -0
- package/dist/index.js +1615 -546
- package/dist/library.js +75 -14
- package/dist/validation/schemas.d.ts +197 -35
- package/package.json +4 -1
- package/presets/agy/AGENTS.md +1 -1
- package/presets/agy/hooks.json +3 -3
- package/presets/agy/scripts/invoke-hook.cjs +21 -17
- package/presets/agy/workflows/cc-api-contract.md +4 -0
- package/presets/agy/workflows/cc-ask.md +10 -10
- package/presets/agy/workflows/cc-council.md +4 -0
- package/presets/agy/workflows/cc-db-migration.md +4 -0
- package/presets/agy/workflows/cc-explore.md +2 -2
- package/presets/agy/workflows/cc-feature.md +4 -0
- package/presets/agy/workflows/cc-fix.md +4 -0
- package/presets/agy/workflows/cc-handoff.md +1 -1
- package/presets/agy/workflows/cc-prototype.md +1 -1
- package/presets/agy/workflows/cc-refactor.md +5 -1
- package/presets/agy/workflows/cc-review.md +5 -1
- package/presets/agy/workflows/cc-security.md +4 -0
- package/presets/agy/workflows/cc-spec-mutation.md +4 -0
- package/presets/agy/workflows/cc-tdd-cycle.md +1 -1
- package/presets/agy/workflows/cc-test-plan.md +5 -1
- package/presets/claude/commands/cc/api-contract.md +5 -1
- package/presets/claude/commands/cc/ask.md +1 -1
- package/presets/claude/commands/cc/backlog.md +1 -1
- package/presets/claude/commands/cc/clarify.md +1 -1
- package/presets/claude/commands/cc/council.md +4 -0
- package/presets/claude/commands/cc/db-migration.md +5 -1
- package/presets/claude/commands/cc/explore.md +1 -1
- package/presets/claude/commands/cc/feature.md +5 -1
- package/presets/claude/commands/cc/fix.md +5 -1
- package/presets/claude/commands/cc/handoff.md +1 -1
- package/presets/claude/commands/cc/iterative.md +1 -1
- package/presets/claude/commands/cc/openspec.md +1 -1
- package/presets/claude/commands/cc/prototype.md +1 -1
- package/presets/claude/commands/cc/refactor.md +5 -1
- package/presets/claude/commands/cc/review.md +5 -1
- package/presets/claude/commands/cc/scorecard.md +1 -1
- package/presets/claude/commands/cc/security.md +5 -1
- package/presets/claude/commands/cc/spec-mutation.md +5 -1
- package/presets/claude/commands/cc/tdd-cycle.md +1 -1
- package/presets/claude/commands/cc/test-plan.md +5 -1
- package/presets/claude/commands/cc/triage.md +1 -1
- package/presets/claude/skills/android/SKILL.md +0 -1
- package/presets/claude/skills/api-versioning/SKILL.md +0 -1
- package/presets/claude/skills/django-orm/SKILL.md +0 -1
- package/presets/claude/skills/django-testing/SKILL.md +0 -1
- package/presets/claude/skills/jpa-postgres/SKILL.md +0 -1
- package/presets/claude/skills/pagespeed-perf/SKILL.md +1 -2
- package/presets/claude/skills/python/SKILL.md +0 -1
- package/presets/claude/skills/python-django-stack/SKILL.md +0 -1
- package/presets/claude/skills/python-fastapi-stack/SKILL.md +0 -1
- package/presets/claude/skills/security/SKILL.md +0 -1
- package/presets/claude/skills/spring-boot-feature/SKILL.md +0 -1
- package/presets/claude/skills/spring-boot-kotlin/SKILL.md +0 -1
- package/presets/claude/skills/sqlalchemy/SKILL.md +0 -1
- package/presets/claude/skills/testing-strategy/SKILL.md +0 -1
- package/presets/codex/AGENTS.md +3 -2
- package/presets/codex/commands/cc-ask.md +10 -10
- package/presets/codex/skills/android/SKILL.md +0 -1
- package/presets/codex/skills/api-versioning/SKILL.md +0 -1
- package/presets/codex/skills/cc-api-contract/SKILL.md +11 -7
- package/presets/codex/skills/cc-backlog/SKILL.md +1 -1
- package/presets/codex/skills/cc-clarify/SKILL.md +1 -1
- package/presets/codex/skills/cc-council/SKILL.md +4 -0
- package/presets/codex/skills/cc-db-migration/SKILL.md +11 -7
- package/presets/codex/skills/cc-explore/SKILL.md +3 -3
- package/presets/codex/skills/cc-feature/SKILL.md +16 -8
- package/presets/codex/skills/cc-fix/SKILL.md +14 -7
- package/presets/codex/skills/cc-handoff/SKILL.md +2 -2
- package/presets/codex/skills/cc-iterative/SKILL.md +8 -8
- package/presets/codex/skills/cc-openspec/SKILL.md +2 -2
- package/presets/codex/skills/cc-prototype/SKILL.md +2 -2
- package/presets/codex/skills/cc-refactor/SKILL.md +8 -4
- package/presets/codex/skills/cc-review/SKILL.md +6 -2
- package/presets/codex/skills/cc-scorecard/SKILL.md +1 -1
- package/presets/codex/skills/cc-security/SKILL.md +5 -1
- package/presets/codex/skills/cc-spec-mutation/SKILL.md +7 -3
- package/presets/codex/skills/cc-tdd-cycle/SKILL.md +6 -6
- package/presets/codex/skills/cc-test-plan/SKILL.md +6 -2
- package/presets/codex/skills/cc-triage/SKILL.md +1 -1
- package/presets/codex/skills/django-orm/SKILL.md +0 -1
- package/presets/codex/skills/django-testing/SKILL.md +0 -1
- package/presets/codex/skills/jpa-postgres/SKILL.md +0 -1
- package/presets/codex/skills/pagespeed-perf/SKILL.md +1 -2
- package/presets/codex/skills/python/SKILL.md +0 -1
- package/presets/codex/skills/python-django-stack/SKILL.md +0 -1
- package/presets/codex/skills/python-fastapi-stack/SKILL.md +0 -1
- package/presets/codex/skills/spring-boot-feature/SKILL.md +0 -1
- package/presets/codex/skills/spring-boot-kotlin/SKILL.md +0 -1
- package/presets/codex/skills/sqlalchemy/SKILL.md +0 -1
- package/presets/codex/skills/testing-strategy/SKILL.md +0 -1
- package/presets/cursor/agents/architect.md +1 -1
- package/presets/cursor/agents/complexity-auditor.md +1 -1
- package/presets/cursor/agents/contract-builder.md +1 -1
- package/presets/cursor/agents/docs.md +1 -1
- package/presets/cursor/agents/goal-planner.md +1 -1
- package/presets/cursor/agents/implementer.md +2 -2
- package/presets/cursor/agents/orchestrator.md +3 -3
- package/presets/cursor/agents/reviewer.md +4 -4
- package/presets/cursor/agents/security-reviewer.md +1 -1
- package/presets/cursor/agents/task-coach.md +1 -1
- package/presets/cursor/agents/tester.md +1 -1
- package/presets/cursor/commands/cc/api-contract.md +5 -1
- package/presets/cursor/commands/cc/ask.md +1 -1
- package/presets/cursor/commands/cc/backlog.md +1 -1
- package/presets/cursor/commands/cc/clarify.md +1 -1
- package/presets/cursor/commands/cc/council.md +4 -0
- package/presets/cursor/commands/cc/db-migration.md +5 -1
- package/presets/cursor/commands/cc/explore.md +1 -1
- package/presets/cursor/commands/cc/feature.md +5 -1
- package/presets/cursor/commands/cc/fix.md +5 -1
- package/presets/cursor/commands/cc/handoff.md +1 -1
- package/presets/cursor/commands/cc/iterative.md +1 -1
- package/presets/cursor/commands/cc/openspec.md +1 -1
- package/presets/cursor/commands/cc/prototype.md +1 -1
- package/presets/cursor/commands/cc/refactor.md +5 -1
- package/presets/cursor/commands/cc/review.md +5 -1
- package/presets/cursor/commands/cc/scorecard.md +1 -1
- package/presets/cursor/commands/cc/security.md +5 -1
- package/presets/cursor/commands/cc/spec-mutation.md +5 -1
- package/presets/cursor/commands/cc/tdd-cycle.md +1 -1
- package/presets/cursor/commands/cc/test-plan.md +5 -1
- package/presets/cursor/commands/cc/triage.md +1 -1
- package/presets/cursor/skills/android/SKILL.md +0 -1
- package/presets/cursor/skills/api-versioning/SKILL.md +0 -1
- package/presets/cursor/skills/astro/SKILL.md +0 -1
- package/presets/cursor/skills/auth-token-inspector/SKILL.md +0 -1
- package/presets/cursor/skills/code-review/SKILL.md +0 -1
- package/presets/cursor/skills/django-orm/SKILL.md +0 -1
- package/presets/cursor/skills/django-testing/SKILL.md +0 -1
- package/presets/cursor/skills/django-uv/SKILL.md +0 -1
- package/presets/cursor/skills/drizzle-schema-architect/SKILL.md +0 -1
- package/presets/cursor/skills/fastapi-pydantic-strict/SKILL.md +0 -1
- package/presets/cursor/skills/jpa-nplusone-detector/SKILL.md +0 -1
- package/presets/cursor/skills/jpa-postgres/SKILL.md +0 -1
- package/presets/cursor/skills/livewire-alpine-bridge/SKILL.md +0 -1
- package/presets/cursor/skills/nextjs-typescript/SKILL.md +0 -1
- package/presets/cursor/skills/pagespeed-perf/SKILL.md +1 -2
- package/presets/cursor/skills/python/SKILL.md +0 -1
- package/presets/cursor/skills/python-django-stack/SKILL.md +0 -1
- package/presets/cursor/skills/python-fastapi-stack/SKILL.md +0 -1
- package/presets/cursor/skills/security/SKILL.md +0 -1
- package/presets/cursor/skills/seo-analytics-injector/SKILL.md +0 -1
- package/presets/cursor/skills/spring-auth-auditor/SKILL.md +0 -1
- package/presets/cursor/skills/spring-boot-feature/SKILL.md +0 -1
- package/presets/cursor/skills/spring-boot-kotlin/SKILL.md +0 -1
- package/presets/cursor/skills/spring-boot-testing-strategy/SKILL.md +0 -1
- package/presets/cursor/skills/sqlalchemy/SKILL.md +0 -1
- package/presets/cursor/skills/tailwind-responsive-auditor/SKILL.md +0 -1
- package/presets/cursor/skills/tdd-mutation-tester/SKILL.md +0 -1
- package/presets/gemini/GEMINI.md +38 -0
- package/presets/gemini/commands/cc/api-contract.toml +10 -6
- package/presets/gemini/commands/cc/ask.toml +1 -1
- package/presets/gemini/commands/cc/backlog.toml +1 -1
- package/presets/gemini/commands/cc/clarify.toml +1 -1
- package/presets/gemini/commands/cc/council.toml +4 -0
- package/presets/gemini/commands/cc/db-migration.toml +10 -6
- package/presets/gemini/commands/cc/explore.toml +1 -1
- package/presets/gemini/commands/cc/feature.toml +11 -7
- package/presets/gemini/commands/cc/fix.toml +13 -9
- package/presets/gemini/commands/cc/handoff.toml +1 -1
- package/presets/gemini/commands/cc/iterative.toml +7 -7
- package/presets/gemini/commands/cc/openspec.toml +1 -1
- package/presets/gemini/commands/cc/prototype.toml +1 -1
- package/presets/gemini/commands/cc/refactor.toml +8 -4
- package/presets/gemini/commands/cc/review.toml +5 -4
- package/presets/gemini/commands/cc/scorecard.toml +1 -1
- package/presets/gemini/commands/cc/security.toml +5 -1
- package/presets/gemini/commands/cc/spec-mutation.toml +5 -1
- package/presets/gemini/commands/cc/tdd-cycle.toml +5 -8
- package/presets/gemini/commands/cc/test-plan.toml +6 -2
- package/presets/gemini/commands/cc/triage.toml +1 -1
- package/presets/gemini/settings.json +3 -0
- package/presets/opencode/agents/docs.md +1 -1
- package/presets/opencode/agents/reviewer.md +1 -1
- package/presets/opencode/commands/cc-api-contract.md +4 -0
- package/presets/opencode/commands/cc-ask.md +10 -10
- package/presets/opencode/commands/cc-council.md +4 -0
- package/presets/opencode/commands/cc-db-migration.md +4 -0
- package/presets/opencode/commands/cc-explore.md +2 -2
- package/presets/opencode/commands/cc-feature.md +4 -0
- package/presets/opencode/commands/cc-fix.md +4 -0
- package/presets/opencode/commands/cc-handoff.md +1 -1
- package/presets/opencode/commands/cc-prototype.md +1 -1
- package/presets/opencode/commands/cc-refactor.md +5 -1
- package/presets/opencode/commands/cc-review.md +5 -1
- package/presets/opencode/commands/cc-security.md +4 -0
- package/presets/opencode/commands/cc-spec-mutation.md +4 -0
- package/presets/opencode/commands/cc-tdd-cycle.md +1 -1
- package/presets/opencode/commands/cc-test-plan.md +5 -1
- package/presets/opencode/prompts/v1.0.0/README.md +1 -1
- package/presets/opencode/prompts/v1.0.0/docs.md +1 -1
- package/presets/opencode/prompts/v1.0.0/reviewer.md +1 -1
- package/presets/opencode/skills/android/SKILL.md +0 -1
- package/presets/opencode/skills/api-versioning/SKILL.md +0 -1
- package/presets/opencode/skills/astro/SKILL.md +0 -1
- package/presets/opencode/skills/auth-token-inspector/SKILL.md +0 -1
- package/presets/opencode/skills/code-review/SKILL.md +0 -1
- package/presets/opencode/skills/django-orm/SKILL.md +0 -1
- package/presets/opencode/skills/django-testing/SKILL.md +0 -1
- package/presets/opencode/skills/django-uv/SKILL.md +0 -1
- package/presets/opencode/skills/drizzle-schema-architect/SKILL.md +0 -1
- package/presets/opencode/skills/fastapi-pydantic-strict/SKILL.md +0 -1
- package/presets/opencode/skills/jpa-nplusone-detector/SKILL.md +0 -1
- package/presets/opencode/skills/jpa-postgres/SKILL.md +0 -1
- package/presets/opencode/skills/livewire-alpine-bridge/SKILL.md +0 -1
- package/presets/opencode/skills/nextjs-typescript/SKILL.md +0 -1
- package/presets/opencode/skills/pagespeed-perf/SKILL.md +1 -2
- package/presets/opencode/skills/python/SKILL.md +0 -1
- package/presets/opencode/skills/python-django-stack/SKILL.md +0 -1
- package/presets/opencode/skills/python-fastapi-stack/SKILL.md +0 -1
- package/presets/opencode/skills/security/SKILL.md +0 -1
- package/presets/opencode/skills/seo-analytics-injector/SKILL.md +0 -1
- package/presets/opencode/skills/spring-auth-auditor/SKILL.md +0 -1
- package/presets/opencode/skills/spring-boot-feature/SKILL.md +0 -1
- package/presets/opencode/skills/spring-boot-kotlin/SKILL.md +0 -1
- package/presets/opencode/skills/spring-boot-testing-strategy/SKILL.md +0 -1
- package/presets/opencode/skills/sqlalchemy/SKILL.md +0 -1
- package/presets/opencode/skills/tailwind-responsive-auditor/SKILL.md +0 -1
- package/presets/opencode/skills/tdd-mutation-tester/SKILL.md +0 -1
- package/presets/pi/AGENTS.md +43 -0
- package/presets/pi/settings.json +3 -0
- package/presets/seo-hotel/skills/astro-seo/SKILL.md +0 -1
- package/presets/seo-hotel/skills/geo-readiness/SKILL.md +0 -1
- package/presets/seo-hotel/skills/off-page/SKILL.md +0 -1
- package/presets/seo-hotel/skills/schema-validator/SKILL.md +0 -1
- package/presets/seo-hotel/skills/seo-audit/SKILL.md +0 -1
- package/presets/shared/invoke-hook.cjs +21 -17
- package/src/presets/council/council.yml +12 -9
- package/src/presets/manifests/agy.yml +1 -1
- package/src/presets/manifests/gemini.yml +11 -11
- package/src/presets/manifests/pi.yml +25 -0
- package/src/presets/models/agy.yml +2 -128
- package/src/presets/models/claude.yml +2 -144
- package/src/presets/models/codex.yml +2 -144
- package/src/presets/models/cursor.yml +2 -144
- package/src/presets/models/gemini.yml +2 -144
- package/src/presets/models/opencode.yml +3 -101
- package/src/presets/models/pi.yml +5 -0
- package/src/presets/models/roles.yml +193 -0
- package/src/presets/shared-skills.yml +64 -0
- package/src/presets/targets/agy.yml +11 -0
- package/src/presets/targets/claude.yml +12 -0
- package/src/presets/targets/codex.yml +14 -0
- package/src/presets/targets/cursor.yml +11 -0
- package/src/presets/targets/gemini.yml +15 -0
- package/src/presets/targets/opencode.yml +13 -0
- package/src/presets/targets/pi.yml +12 -0
- package/presets/opencode/prompts/v0.1.0/DEPRECATED.md +0 -11
- package/presets/opencode/prompts/v0.1.0/architect.md +0 -213
- package/presets/opencode/prompts/v0.1.0/docs.md +0 -181
- package/presets/opencode/prompts/v0.1.0/implementer.md +0 -154
- package/presets/opencode/prompts/v0.1.0/orchestrator.md +0 -169
- package/presets/opencode/prompts/v0.1.0/repo-explorer.md +0 -102
- package/presets/opencode/prompts/v0.1.0/reviewer.md +0 -183
- package/presets/opencode/prompts/v0.1.0/task-coach.md +0 -142
- package/presets/opencode/prompts/v0.1.0/tester.md +0 -160
- package/presets/opencode/prompts/v0.2.0/DEPRECATED.md +0 -11
- package/presets/opencode/prompts/v0.2.0/architect.md +0 -219
- package/presets/opencode/prompts/v0.2.0/docs.md +0 -187
- package/presets/opencode/prompts/v0.2.0/implementer.md +0 -160
- package/presets/opencode/prompts/v0.2.0/orchestrator.md +0 -238
- package/presets/opencode/prompts/v0.2.0/repo-explorer.md +0 -108
- package/presets/opencode/prompts/v0.2.0/reviewer.md +0 -190
- package/presets/opencode/prompts/v0.2.0/task-coach.md +0 -153
- package/presets/opencode/prompts/v0.2.0/tester.md +0 -249
- package/presets/opencode/prompts/v0.3.0/DEPRECATED.md +0 -11
- package/presets/opencode/prompts/v0.3.0/architect.md +0 -221
- package/presets/opencode/prompts/v0.3.0/docs.md +0 -189
- package/presets/opencode/prompts/v0.3.0/implementer.md +0 -162
- package/presets/opencode/prompts/v0.3.0/orchestrator.md +0 -360
- package/presets/opencode/prompts/v0.3.0/repo-explorer.md +0 -110
- package/presets/opencode/prompts/v0.3.0/reviewer.md +0 -225
- package/presets/opencode/prompts/v0.3.0/task-coach.md +0 -155
- package/presets/opencode/prompts/v0.3.0/tester.md +0 -251
- package/presets/opencode/prompts/v0.4.0/DEPRECATED.md +0 -11
- package/presets/opencode/prompts/v0.4.0/architect.md +0 -221
- package/presets/opencode/prompts/v0.4.0/complexity-auditor.md +0 -89
- package/presets/opencode/prompts/v0.4.0/docs.md +0 -189
- package/presets/opencode/prompts/v0.4.0/implementer.md +0 -162
- package/presets/opencode/prompts/v0.4.0/orchestrator.md +0 -348
- package/presets/opencode/prompts/v0.4.0/repo-explorer.md +0 -110
- package/presets/opencode/prompts/v0.4.0/reviewer.md +0 -225
- package/presets/opencode/prompts/v0.4.0/task-coach.md +0 -155
- package/presets/opencode/prompts/v0.4.0/tester.md +0 -251
- package/presets/opencode/prompts/v0.5.0/architect.md +0 -222
- package/presets/opencode/prompts/v0.5.0/complexity-auditor.md +0 -91
- package/presets/opencode/prompts/v0.5.0/contract-builder.md +0 -84
- package/presets/opencode/prompts/v0.5.0/docs.md +0 -190
- package/presets/opencode/prompts/v0.5.0/goal-planner.md +0 -80
- package/presets/opencode/prompts/v0.5.0/implementer.md +0 -171
- package/presets/opencode/prompts/v0.5.0/orchestrator.md +0 -388
- package/presets/opencode/prompts/v0.5.0/repo-explorer.md +0 -111
- package/presets/opencode/prompts/v0.5.0/reviewer.md +0 -248
- package/presets/opencode/prompts/v0.5.0/security-reviewer.md +0 -123
- package/presets/opencode/prompts/v0.5.0/task-coach.md +0 -156
- package/presets/opencode/prompts/v0.5.0/tester.md +0 -252
- package/presets/opencode/prompts/v0.6.0/implementer.md +0 -35
- package/presets/opencode/prompts/v0.6.0/planner.md +0 -36
- package/presets/opencode/prompts/v0.6.0/reviewer.md +0 -40
- package/presets/shared/__pycache__/mutation_runner.cpython-314.pyc +0 -0
package/dist/index.js
CHANGED
|
@@ -83,7 +83,7 @@ var package_default;
|
|
|
83
83
|
var init_package = __esm(() => {
|
|
84
84
|
package_default = {
|
|
85
85
|
name: "cc-codeconductor",
|
|
86
|
-
version: "1.
|
|
86
|
+
version: "1.3.0",
|
|
87
87
|
description: "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
|
|
88
88
|
keywords: [
|
|
89
89
|
"ai",
|
|
@@ -137,6 +137,9 @@ var init_package = __esm(() => {
|
|
|
137
137
|
lint: "bun run scripts/lint.ts",
|
|
138
138
|
"check:coverage": "bun run scripts/check-coverage.ts",
|
|
139
139
|
"check:prompt-changelog": "bun run scripts/check-prompt-changelog.ts",
|
|
140
|
+
"check:drift": "bun run scripts/check-drift.ts",
|
|
141
|
+
"render:commands": "bun run scripts/render-agent-commands.ts",
|
|
142
|
+
"sync:skills": "bun run scripts/sync-shared-skills.ts",
|
|
140
143
|
"release:patch": "bash release.sh patch",
|
|
141
144
|
"release:minor": "bash release.sh minor",
|
|
142
145
|
"release:major": "bash release.sh major",
|
|
@@ -4120,6 +4123,37 @@ var init_zod = __esm(() => {
|
|
|
4120
4123
|
init_external();
|
|
4121
4124
|
});
|
|
4122
4125
|
|
|
4126
|
+
// src/core/runner/runner-target.ts
|
|
4127
|
+
function isRunnerTarget(value) {
|
|
4128
|
+
return RUNNER_TARGETS.includes(value);
|
|
4129
|
+
}
|
|
4130
|
+
function parseRunnerTarget(value) {
|
|
4131
|
+
if (!isRunnerTarget(value)) {
|
|
4132
|
+
throw new Error(`Invalid runner target: ${value}. Valid targets: ${RUNNER_TARGETS.join(", ")}`);
|
|
4133
|
+
}
|
|
4134
|
+
return value;
|
|
4135
|
+
}
|
|
4136
|
+
function getIndividualTargets(target) {
|
|
4137
|
+
if (target === "all") {
|
|
4138
|
+
return [...INDIVIDUAL_TARGETS];
|
|
4139
|
+
}
|
|
4140
|
+
return [target];
|
|
4141
|
+
}
|
|
4142
|
+
var RUNNER_TARGETS, INDIVIDUAL_TARGETS;
|
|
4143
|
+
var init_runner_target = __esm(() => {
|
|
4144
|
+
RUNNER_TARGETS = [
|
|
4145
|
+
"opencode",
|
|
4146
|
+
"claude",
|
|
4147
|
+
"codex",
|
|
4148
|
+
"gemini",
|
|
4149
|
+
"cursor",
|
|
4150
|
+
"agy",
|
|
4151
|
+
"pi",
|
|
4152
|
+
"all"
|
|
4153
|
+
];
|
|
4154
|
+
INDIVIDUAL_TARGETS = ["opencode", "claude", "codex", "gemini", "cursor", "agy", "pi"];
|
|
4155
|
+
});
|
|
4156
|
+
|
|
4123
4157
|
// node_modules/yaml/dist/nodes/identity.js
|
|
4124
4158
|
var require_identity = __commonJS((exports) => {
|
|
4125
4159
|
var ALIAS = Symbol.for("yaml.alias");
|
|
@@ -11119,15 +11153,24 @@ function err(error) {
|
|
|
11119
11153
|
}
|
|
11120
11154
|
|
|
11121
11155
|
// src/core/presets/package-paths.ts
|
|
11156
|
+
var exports_package_paths = {};
|
|
11157
|
+
__export(exports_package_paths, {
|
|
11158
|
+
SRC_PRESETS_DIR: () => SRC_PRESETS_DIR,
|
|
11159
|
+
SKILLS_REGISTRY_PATH: () => SKILLS_REGISTRY_PATH,
|
|
11160
|
+
ROOT_PRESETS_DIR: () => ROOT_PRESETS_DIR,
|
|
11161
|
+
POLICY_PATH: () => POLICY_PATH,
|
|
11162
|
+
PACKAGE_ROOT: () => PACKAGE_ROOT
|
|
11163
|
+
});
|
|
11122
11164
|
import { dirname, resolve, sep } from "node:path";
|
|
11123
11165
|
import { fileURLToPath } from "node:url";
|
|
11124
|
-
var moduleDir, PACKAGE_ROOT, SRC_PRESETS_DIR, ROOT_PRESETS_DIR, POLICY_PATH;
|
|
11166
|
+
var moduleDir, PACKAGE_ROOT, SRC_PRESETS_DIR, ROOT_PRESETS_DIR, POLICY_PATH, SKILLS_REGISTRY_PATH;
|
|
11125
11167
|
var init_package_paths = __esm(() => {
|
|
11126
11168
|
moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
11127
11169
|
PACKAGE_ROOT = moduleDir.endsWith(`${sep}dist`) ? resolve(moduleDir, "..") : resolve(moduleDir, "..", "..", "..");
|
|
11128
11170
|
SRC_PRESETS_DIR = resolve(PACKAGE_ROOT, "src", "presets");
|
|
11129
11171
|
ROOT_PRESETS_DIR = resolve(PACKAGE_ROOT, "presets");
|
|
11130
11172
|
POLICY_PATH = resolve(PACKAGE_ROOT, "policy.yml");
|
|
11173
|
+
SKILLS_REGISTRY_PATH = resolve(PACKAGE_ROOT, "skills-registry.json");
|
|
11131
11174
|
});
|
|
11132
11175
|
|
|
11133
11176
|
// src/core/filesystem/credential-guard.ts
|
|
@@ -11263,6 +11306,9 @@ var exports_schemas = {};
|
|
|
11263
11306
|
__export(exports_schemas, {
|
|
11264
11307
|
validateWorkflowProfile: () => validateWorkflowProfile,
|
|
11265
11308
|
validateTaskOutcome: () => validateTaskOutcome,
|
|
11309
|
+
validateTargetCapabilities: () => validateTargetCapabilities,
|
|
11310
|
+
validateSkillsRegistry: () => validateSkillsRegistry,
|
|
11311
|
+
validateSkillFrontmatter: () => validateSkillFrontmatter,
|
|
11266
11312
|
validateScorecardRecord: () => validateScorecardRecord,
|
|
11267
11313
|
validateRunnerTarget: () => validateRunnerTarget,
|
|
11268
11314
|
validateReviewerOutput: () => validateReviewerOutput,
|
|
@@ -11290,6 +11336,7 @@ __export(exports_schemas, {
|
|
|
11290
11336
|
validateCouncilSpec: () => validateCouncilSpec,
|
|
11291
11337
|
validateConsensusConfig: () => validateConsensusConfig,
|
|
11292
11338
|
validateConfig: () => validateConfig,
|
|
11339
|
+
validateCommandFrontmatter: () => validateCommandFrontmatter,
|
|
11293
11340
|
validateCommandEnvelope: () => validateCommandEnvelope,
|
|
11294
11341
|
validateClaudeAgentFile: () => validateClaudeAgentFile,
|
|
11295
11342
|
validateCanonicalTaskCard: () => validateCanonicalTaskCard,
|
|
@@ -11306,9 +11353,12 @@ __export(exports_schemas, {
|
|
|
11306
11353
|
TaskOutcomeStatusSchema: () => TaskOutcomeStatusSchema,
|
|
11307
11354
|
TaskOutcomeSourceSchema: () => TaskOutcomeSourceSchema,
|
|
11308
11355
|
TaskOutcomeSchema: () => TaskOutcomeSchema,
|
|
11356
|
+
TargetCapabilitiesSchema: () => TargetCapabilitiesSchema,
|
|
11309
11357
|
StrategicMemorySchema: () => StrategicMemorySchema,
|
|
11310
11358
|
SpecAnalyzeReportSchema: () => SpecAnalyzeReportSchema,
|
|
11311
11359
|
SpecAnalyzeFindingSchema: () => SpecAnalyzeFindingSchema,
|
|
11360
|
+
SkillsRegistrySchema: () => SkillsRegistrySchema,
|
|
11361
|
+
SkillFrontmatterSchema: () => SkillFrontmatterSchema,
|
|
11312
11362
|
SentryWebhookSchema: () => SentryWebhookSchema,
|
|
11313
11363
|
SentryStackFrameSchema: () => SentryStackFrameSchema,
|
|
11314
11364
|
ScorecardVerdictSchema: () => ScorecardVerdictSchema,
|
|
@@ -11374,6 +11424,7 @@ __export(exports_schemas, {
|
|
|
11374
11424
|
ConsensusConfigSchema: () => ConsensusConfigSchema,
|
|
11375
11425
|
ConfidenceLevelSchema: () => ConfidenceLevelSchema,
|
|
11376
11426
|
CompileCheckConfigSchema: () => CompileCheckConfigSchema,
|
|
11427
|
+
CommandFrontmatterSchema: () => CommandFrontmatterSchema,
|
|
11377
11428
|
CommandEnvelopeSchema: () => CommandEnvelopeSchema,
|
|
11378
11429
|
CodeConductorConfigSchema: () => CodeConductorConfigSchema,
|
|
11379
11430
|
ClaudeAgentFileSchema: () => ClaudeAgentFileSchema,
|
|
@@ -11397,6 +11448,15 @@ function validateCouncilSpec(data) {
|
|
|
11397
11448
|
function validateProjectProfile(data) {
|
|
11398
11449
|
return ProjectProfileSchema.parse(data);
|
|
11399
11450
|
}
|
|
11451
|
+
function validateSkillFrontmatter(data) {
|
|
11452
|
+
return SkillFrontmatterSchema.parse(data);
|
|
11453
|
+
}
|
|
11454
|
+
function validateCommandFrontmatter(data) {
|
|
11455
|
+
return CommandFrontmatterSchema.parse(data);
|
|
11456
|
+
}
|
|
11457
|
+
function validateTargetCapabilities(data) {
|
|
11458
|
+
return TargetCapabilitiesSchema.parse(data);
|
|
11459
|
+
}
|
|
11400
11460
|
function validateConfig(data) {
|
|
11401
11461
|
return CodeConductorConfigSchema.parse(data);
|
|
11402
11462
|
}
|
|
@@ -11496,9 +11556,13 @@ function validateCanonicalTaskCard(data) {
|
|
|
11496
11556
|
function validateProductEvent(data) {
|
|
11497
11557
|
return ProductEventSchema.parse(data);
|
|
11498
11558
|
}
|
|
11499
|
-
|
|
11559
|
+
function validateSkillsRegistry(data) {
|
|
11560
|
+
return SkillsRegistrySchema.parse(data);
|
|
11561
|
+
}
|
|
11562
|
+
var CouncilAgentSpecSchema, CouncilSpecSchema, ProjectProfileSchema, CompileCheckConfigSchema, LoopConfigSchema, CodeConductorConfigSchema, RunnerTargetSchema, InstallStrategySchema, ManifestEntrySchema, InstallManifestSchema, ToolProviderNamesSchema, PermissionProviderNamesSchema, ModelConfigSchema, SkillFrontmatterSchema, CommandFrontmatterSchema, TargetCapabilitiesSchema, ContractTargetSchema, ContractFormatSchema, AgentContractSchema, CouncilFindingSchema, CouncilVerdictInputSchema, ConsensusConfigSchema, CouncilVerdictSchema, ClaudeAgentFileSchema, OpenCodeAgentFileSchema, SentryStackFrameSchema, SentryWebhookSchema, MemoryPointerSchema, MemoryIndexSchema, GoalTaskSchema, GoalGraphSchema, ConfidenceLevelSchema, ProductNodeTypeSchema, GraphRelationSchema, KnowledgeEntitySchema, DecisionSchema, EvidenceSchema, CanonicalTaskCardStatusSchema, CanonicalTaskCardSchema, ProductGraphNodeSchema, ProductGraphEdgeSchema, ProductGraphSchema, ProductMetaSchema, ProductEventTypeSchema, ProductEventSchema, OperationalStateSchema, StrategicMemorySchema, ImpactReportSchema, BusinessReviewOutputSchema, VerificationReportSchema, BacklogStatusSchema, BacklogTypeSchema, BacklogPrioritySchema, BacklogGlobalSchema, BacklogItemSchema, BacklogDocumentSchema, OpenspecTaskCardPhaseSchema, OpenspecTaskCardStatusSchema, OpenspecTaskCardSchema, OpenspecStateSchema, SpecAnalyzeFindingSchema, SpecAnalyzeReportSchema, WorkflowCommandSchema, CcepOutputFormatSchema, CommandEnvelopeSchema, WorkflowPhaseSchema, WorkflowRiskRuleSchema, WorkflowProfileSchema, ExecutionContextSchema, PlannerOutputSchema, AgentArtifactSchema, AgentOutputSchema, ImplementerTestsSchema, ImplementerOutputSchema, ReviewAxisSchema, ReviewFindingSchema, ReviewerOutputSchema, TechnicalPlanOutputSchema, ScorecardVerdictSchema, ScorecardCriterionIdSchema, ScorecardCriterionSchema, ScorecardRecordSchema, TaskOutcomeSourceSchema, TaskOutcomeStatusSchema, TaskOutcomeSchema, HarnessComponentIdSchema, HarnessComponentLayerSchema, HarnessToggleKindSchema, HarnessCatalogEntrySchema, HarnessCatalogSchema, HarnessOverlaySchema, HarnessExperimentSchema, HarnessSuiteTaskSchema, HarnessSuiteSchema, EvaluationIndexSchema, ExecutionProfileNameSchema, ExecutionProfileSchema, SkillsRegistrySchema;
|
|
11500
11563
|
var init_schemas = __esm(() => {
|
|
11501
11564
|
init_zod();
|
|
11565
|
+
init_runner_target();
|
|
11502
11566
|
CouncilAgentSpecSchema = exports_external.object({
|
|
11503
11567
|
id: exports_external.string(),
|
|
11504
11568
|
role: exports_external.string(),
|
|
@@ -11550,7 +11614,7 @@ var init_schemas = __esm(() => {
|
|
|
11550
11614
|
profile: exports_external.string().optional()
|
|
11551
11615
|
}),
|
|
11552
11616
|
defaults: exports_external.object({
|
|
11553
|
-
target: exports_external.enum(
|
|
11617
|
+
target: exports_external.enum(INDIVIDUAL_TARGETS),
|
|
11554
11618
|
overwrite: exports_external.boolean(),
|
|
11555
11619
|
locale: exports_external.enum(["en", "es"]).optional().default("en")
|
|
11556
11620
|
}),
|
|
@@ -11567,15 +11631,7 @@ var init_schemas = __esm(() => {
|
|
|
11567
11631
|
}),
|
|
11568
11632
|
loop: LoopConfigSchema.optional()
|
|
11569
11633
|
});
|
|
11570
|
-
RunnerTargetSchema = exports_external.enum(
|
|
11571
|
-
"opencode",
|
|
11572
|
-
"claude",
|
|
11573
|
-
"codex",
|
|
11574
|
-
"gemini",
|
|
11575
|
-
"cursor",
|
|
11576
|
-
"agy",
|
|
11577
|
-
"all"
|
|
11578
|
-
]);
|
|
11634
|
+
RunnerTargetSchema = exports_external.enum(RUNNER_TARGETS);
|
|
11579
11635
|
InstallStrategySchema = exports_external.enum([
|
|
11580
11636
|
"overwrite",
|
|
11581
11637
|
"append",
|
|
@@ -11591,13 +11647,13 @@ var init_schemas = __esm(() => {
|
|
|
11591
11647
|
template: exports_external.boolean().optional()
|
|
11592
11648
|
});
|
|
11593
11649
|
InstallManifestSchema = exports_external.object({
|
|
11594
|
-
target: exports_external.enum(
|
|
11650
|
+
target: exports_external.enum(INDIVIDUAL_TARGETS),
|
|
11595
11651
|
entries: exports_external.array(ManifestEntrySchema)
|
|
11596
11652
|
});
|
|
11597
11653
|
ToolProviderNamesSchema = exports_external.record(exports_external.string(), exports_external.string());
|
|
11598
11654
|
PermissionProviderNamesSchema = exports_external.record(exports_external.string(), exports_external.string());
|
|
11599
11655
|
ModelConfigSchema = exports_external.object({
|
|
11600
|
-
target: exports_external.enum(
|
|
11656
|
+
target: exports_external.enum(INDIVIDUAL_TARGETS),
|
|
11601
11657
|
agents: exports_external.record(exports_external.string(), exports_external.object({
|
|
11602
11658
|
claude: exports_external.string().optional(),
|
|
11603
11659
|
opencode: exports_external.string().optional(),
|
|
@@ -11605,11 +11661,37 @@ var init_schemas = __esm(() => {
|
|
|
11605
11661
|
gemini: exports_external.string().optional(),
|
|
11606
11662
|
cursor: exports_external.string().optional(),
|
|
11607
11663
|
agy: exports_external.string().optional(),
|
|
11664
|
+
pi: exports_external.string().optional(),
|
|
11608
11665
|
grok: exports_external.string().optional()
|
|
11609
11666
|
})),
|
|
11610
11667
|
tools: exports_external.record(exports_external.string(), ToolProviderNamesSchema).optional(),
|
|
11611
11668
|
permissions: PermissionProviderNamesSchema.optional()
|
|
11612
11669
|
});
|
|
11670
|
+
SkillFrontmatterSchema = exports_external.object({
|
|
11671
|
+
name: exports_external.string().trim().min(1, "name must not be empty"),
|
|
11672
|
+
description: exports_external.string().trim().min(1, "description must not be empty").max(1024, "description must be 1024 characters or fewer"),
|
|
11673
|
+
id: exports_external.string().trim().min(1).optional()
|
|
11674
|
+
}).passthrough();
|
|
11675
|
+
CommandFrontmatterSchema = exports_external.object({
|
|
11676
|
+
description: exports_external.string().trim().min(1, "description must not be empty").max(1024, "description must be 1024 characters or fewer"),
|
|
11677
|
+
"argument-hint": exports_external.string().trim().min(1).optional(),
|
|
11678
|
+
"allowed-tools": exports_external.string().trim().min(1).optional(),
|
|
11679
|
+
model: exports_external.string().trim().min(1).optional(),
|
|
11680
|
+
"disable-model-invocation": exports_external.boolean().optional()
|
|
11681
|
+
}).passthrough();
|
|
11682
|
+
TargetCapabilitiesSchema = exports_external.object({
|
|
11683
|
+
target: exports_external.enum(INDIVIDUAL_TARGETS),
|
|
11684
|
+
invocation: exports_external.enum(["colon", "hyphen", "dollar"]),
|
|
11685
|
+
commandFormat: exports_external.enum(["markdown", "toml", "skill"]),
|
|
11686
|
+
contextFile: exports_external.string().trim().min(1),
|
|
11687
|
+
subagentInvocationStyle: exports_external.enum(["task-tool", "adopt-role", "invoke-with-context"]).optional(),
|
|
11688
|
+
capabilities: exports_external.object({
|
|
11689
|
+
subagents: exports_external.boolean(),
|
|
11690
|
+
hooks: exports_external.boolean(),
|
|
11691
|
+
mcp: exports_external.boolean(),
|
|
11692
|
+
council: exports_external.boolean()
|
|
11693
|
+
})
|
|
11694
|
+
});
|
|
11613
11695
|
ContractTargetSchema = exports_external.enum([
|
|
11614
11696
|
"claude",
|
|
11615
11697
|
"opencode",
|
|
@@ -12349,13 +12431,19 @@ var init_schemas = __esm(() => {
|
|
|
12349
12431
|
ExecutionProfileNameSchema = exports_external.enum(["balanced", "quality", "economical"]);
|
|
12350
12432
|
ExecutionProfileSchema = exports_external.object({
|
|
12351
12433
|
profile: ExecutionProfileNameSchema.default("balanced"),
|
|
12352
|
-
target: exports_external.enum(
|
|
12434
|
+
target: exports_external.enum(INDIVIDUAL_TARGETS).optional(),
|
|
12353
12435
|
overrides: exports_external.record(exports_external.string(), exports_external.string()).optional().default({}),
|
|
12354
12436
|
subagentPolicy: exports_external.object({
|
|
12355
12437
|
orchestrator: exports_external.enum(["primary", "delegate"]).optional(),
|
|
12356
12438
|
testerReviewer: exports_external.enum(["primary", "delegate"]).optional()
|
|
12357
12439
|
}).optional()
|
|
12358
12440
|
});
|
|
12441
|
+
SkillsRegistrySchema = exports_external.object({
|
|
12442
|
+
version: exports_external.literal(1),
|
|
12443
|
+
skills: exports_external.record(exports_external.string().min(1).regex(/^[a-z0-9\-]+$/), exports_external.object({
|
|
12444
|
+
version: exports_external.string().min(1)
|
|
12445
|
+
}))
|
|
12446
|
+
});
|
|
12359
12447
|
});
|
|
12360
12448
|
|
|
12361
12449
|
// src/core/ccep/profiles.ts
|
|
@@ -13342,6 +13430,8 @@ function resolveAssets(target) {
|
|
|
13342
13430
|
return ["AGENTS.md", ".cursorignore", "rules", "commands", "skills", "agents", "prompts/v1.0.0"];
|
|
13343
13431
|
case "agy":
|
|
13344
13432
|
return ["AGENTS.md", "rules", "workflows", "skills", "prompts/v1.0.0"];
|
|
13433
|
+
case "pi":
|
|
13434
|
+
return ["AGENTS.md", "settings.json", "prompts", "skills", "agents", "prompts/v1.0.0"];
|
|
13345
13435
|
}
|
|
13346
13436
|
}
|
|
13347
13437
|
var CURRENT_PRESET_VERSION = "v1.0.0";
|
|
@@ -13691,6 +13781,9 @@ var init_detect_command = __esm(() => {
|
|
|
13691
13781
|
});
|
|
13692
13782
|
|
|
13693
13783
|
// src/core/lsp/lsp-config-utils.ts
|
|
13784
|
+
function filterSuccessfulLsps(installedLsps) {
|
|
13785
|
+
return installedLsps.filter((lsp) => lsp.status !== "failed");
|
|
13786
|
+
}
|
|
13694
13787
|
function getLanguageServerConfig(lspIds) {
|
|
13695
13788
|
const languageServers = {};
|
|
13696
13789
|
for (const lspId of lspIds) {
|
|
@@ -13721,7 +13814,7 @@ class AgyLspGenerator {
|
|
|
13721
13814
|
name = "agy-lsp";
|
|
13722
13815
|
target = "agy";
|
|
13723
13816
|
generate(installedLsps) {
|
|
13724
|
-
const successfulLsps = installedLsps
|
|
13817
|
+
const successfulLsps = filterSuccessfulLsps(installedLsps);
|
|
13725
13818
|
if (successfulLsps.length === 0) {
|
|
13726
13819
|
return [];
|
|
13727
13820
|
}
|
|
@@ -13764,7 +13857,7 @@ class ClaudeLspGenerator {
|
|
|
13764
13857
|
name = "claude-lsp";
|
|
13765
13858
|
target = "claude";
|
|
13766
13859
|
generate(installedLsps) {
|
|
13767
|
-
const successfulLsps = installedLsps
|
|
13860
|
+
const successfulLsps = filterSuccessfulLsps(installedLsps);
|
|
13768
13861
|
if (successfulLsps.length === 0) {
|
|
13769
13862
|
return [];
|
|
13770
13863
|
}
|
|
@@ -13792,7 +13885,7 @@ class CodexLspGenerator {
|
|
|
13792
13885
|
name = "codex-lsp";
|
|
13793
13886
|
target = "codex";
|
|
13794
13887
|
generate(installedLsps) {
|
|
13795
|
-
const successfulLsps = installedLsps
|
|
13888
|
+
const successfulLsps = filterSuccessfulLsps(installedLsps);
|
|
13796
13889
|
if (successfulLsps.length === 0) {
|
|
13797
13890
|
return [];
|
|
13798
13891
|
}
|
|
@@ -13831,7 +13924,7 @@ class CursorLspGenerator {
|
|
|
13831
13924
|
name = "cursor-lsp";
|
|
13832
13925
|
target = "cursor";
|
|
13833
13926
|
generate(installedLsps) {
|
|
13834
|
-
const successfulLsps = installedLsps
|
|
13927
|
+
const successfulLsps = filterSuccessfulLsps(installedLsps);
|
|
13835
13928
|
if (successfulLsps.length === 0) {
|
|
13836
13929
|
return [];
|
|
13837
13930
|
}
|
|
@@ -13861,7 +13954,7 @@ class GeminiLspGenerator {
|
|
|
13861
13954
|
name = "gemini-lsp";
|
|
13862
13955
|
target = "gemini";
|
|
13863
13956
|
generate(installedLsps) {
|
|
13864
|
-
const successfulLsps = installedLsps
|
|
13957
|
+
const successfulLsps = filterSuccessfulLsps(installedLsps);
|
|
13865
13958
|
if (successfulLsps.length === 0) {
|
|
13866
13959
|
return [];
|
|
13867
13960
|
}
|
|
@@ -13891,7 +13984,7 @@ class OpenCodeLspGenerator {
|
|
|
13891
13984
|
name = "opencode-lsp";
|
|
13892
13985
|
target = "opencode";
|
|
13893
13986
|
generate(installedLsps) {
|
|
13894
|
-
const successfulLsps = installedLsps
|
|
13987
|
+
const successfulLsps = filterSuccessfulLsps(installedLsps);
|
|
13895
13988
|
if (successfulLsps.length === 0) {
|
|
13896
13989
|
return [];
|
|
13897
13990
|
}
|
|
@@ -15214,28 +15307,6 @@ var init_lsp_registry = __esm(() => {
|
|
|
15214
15307
|
}
|
|
15215
15308
|
});
|
|
15216
15309
|
|
|
15217
|
-
// src/core/runner/runner-target.ts
|
|
15218
|
-
function isRunnerTarget(value) {
|
|
15219
|
-
return RUNNER_TARGETS.includes(value);
|
|
15220
|
-
}
|
|
15221
|
-
function parseRunnerTarget(value) {
|
|
15222
|
-
if (!isRunnerTarget(value)) {
|
|
15223
|
-
throw new Error(`Invalid runner target: ${value}. Valid targets: ${RUNNER_TARGETS.join(", ")}`);
|
|
15224
|
-
}
|
|
15225
|
-
return value;
|
|
15226
|
-
}
|
|
15227
|
-
function getIndividualTargets(target) {
|
|
15228
|
-
if (target === "all") {
|
|
15229
|
-
return [...INDIVIDUAL_TARGETS];
|
|
15230
|
-
}
|
|
15231
|
-
return [target];
|
|
15232
|
-
}
|
|
15233
|
-
var RUNNER_TARGETS, INDIVIDUAL_TARGETS;
|
|
15234
|
-
var init_runner_target = __esm(() => {
|
|
15235
|
-
RUNNER_TARGETS = ["opencode", "claude", "codex", "gemini", "cursor", "agy", "all"];
|
|
15236
|
-
INDIVIDUAL_TARGETS = ["opencode", "claude", "codex", "gemini", "cursor", "agy"];
|
|
15237
|
-
});
|
|
15238
|
-
|
|
15239
15310
|
// src/commands/install-lsp.command.ts
|
|
15240
15311
|
var exports_install_lsp_command = {};
|
|
15241
15312
|
__export(exports_install_lsp_command, {
|
|
@@ -15403,56 +15474,39 @@ var init_install_lsp_command = __esm(() => {
|
|
|
15403
15474
|
});
|
|
15404
15475
|
|
|
15405
15476
|
// src/domain/council/council-agent.ts
|
|
15406
|
-
function
|
|
15407
|
-
|
|
15408
|
-
|
|
15409
|
-
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
|
|
15413
|
-
|
|
15414
|
-
|
|
15415
|
-
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
"seo-auditor": `- Audit technical SEO
|
|
15433
|
-
- Check meta tags and headings
|
|
15434
|
-
- Validate crawl directives
|
|
15435
|
-
- Assess page speed signals`,
|
|
15436
|
-
"schema-validator": `- Validate Schema.org markup
|
|
15437
|
-
- Check JSON-LD syntax
|
|
15438
|
-
- Verify required properties
|
|
15439
|
-
- Suggest structured data fixes`,
|
|
15440
|
-
"geo-specialist": `- Assess AI-search readiness
|
|
15441
|
-
- Validate llms.txt
|
|
15442
|
-
- Check citable content
|
|
15443
|
-
- Review GEO optimization`,
|
|
15444
|
-
"content-strategist": `- Plan content marketing
|
|
15445
|
-
- Guide off-page SEO
|
|
15446
|
-
- Suggest backlink strategy
|
|
15447
|
-
- Review hotel copywriting`,
|
|
15448
|
-
"astro-specialist": `- Validate Astro SEO patterns
|
|
15449
|
-
- Check static generation
|
|
15450
|
-
- Review Islands Architecture
|
|
15451
|
-
- Optimize image handling`
|
|
15452
|
-
};
|
|
15453
|
-
return responsibilities[agentId] || "- Provide critical review";
|
|
15477
|
+
function yamlString(value) {
|
|
15478
|
+
return JSON.stringify(value);
|
|
15479
|
+
}
|
|
15480
|
+
function generatePermissionBlock(context) {
|
|
15481
|
+
if (context === "repo-readonly") {
|
|
15482
|
+
return ` read: allow
|
|
15483
|
+
edit: deny
|
|
15484
|
+
bash: deny
|
|
15485
|
+
glob: allow
|
|
15486
|
+
grep: allow
|
|
15487
|
+
webfetch: deny
|
|
15488
|
+
websearch: deny`;
|
|
15489
|
+
}
|
|
15490
|
+
return ` read: deny
|
|
15491
|
+
edit: deny
|
|
15492
|
+
bash: deny
|
|
15493
|
+
glob: deny
|
|
15494
|
+
grep: deny
|
|
15495
|
+
webfetch: deny
|
|
15496
|
+
websearch: deny`;
|
|
15497
|
+
}
|
|
15498
|
+
function profileFor(agentId) {
|
|
15499
|
+
return ROLE_PROFILES[agentId] ?? DEFAULT_PROFILE;
|
|
15500
|
+
}
|
|
15501
|
+
function checklistFor(agentId) {
|
|
15502
|
+
return profileFor(agentId).checklist;
|
|
15454
15503
|
}
|
|
15455
15504
|
function generateAgentContent(agent) {
|
|
15505
|
+
const profile = profileFor(agent.id);
|
|
15506
|
+
const vetoSection = profile.vetoNote ? `
|
|
15507
|
+
## Veto
|
|
15508
|
+
${profile.vetoNote}
|
|
15509
|
+
` : "";
|
|
15456
15510
|
return `# ${agent.role} Agent
|
|
15457
15511
|
|
|
15458
15512
|
## Role
|
|
@@ -15469,9 +15523,172 @@ ${agent.focus.map((f) => `- ${f}`).join(`
|
|
|
15469
15523
|
`)}
|
|
15470
15524
|
|
|
15471
15525
|
## Responsibilities
|
|
15472
|
-
${
|
|
15526
|
+
${profile.responsibilities.map((r) => `- ${r}`).join(`
|
|
15527
|
+
`)}
|
|
15528
|
+
|
|
15529
|
+
## Review Checklist
|
|
15530
|
+
${profile.checklist.map((c) => `- ${c}`).join(`
|
|
15531
|
+
`)}
|
|
15532
|
+
${vetoSection}
|
|
15533
|
+
## Finding Format
|
|
15534
|
+
- **CRITICAL** — blocks the council verdict; must be resolved before merge.
|
|
15535
|
+
- **WARNING** — should be resolved before merge; does not block.
|
|
15536
|
+
- **SUGGESTION** — optional improvement, non-blocking.
|
|
15473
15537
|
`;
|
|
15474
15538
|
}
|
|
15539
|
+
var ROLE_PROFILES, DEFAULT_PROFILE;
|
|
15540
|
+
var init_council_agent = __esm(() => {
|
|
15541
|
+
ROLE_PROFILES = {
|
|
15542
|
+
architect: {
|
|
15543
|
+
responsibilities: [
|
|
15544
|
+
"Analyze code architecture",
|
|
15545
|
+
"Suggest design patterns",
|
|
15546
|
+
"Review code structure",
|
|
15547
|
+
"Propose refactoring"
|
|
15548
|
+
],
|
|
15549
|
+
checklist: [
|
|
15550
|
+
"Does the diff follow existing module boundaries and naming conventions?",
|
|
15551
|
+
"Are there speculative abstractions not required by the current task?",
|
|
15552
|
+
"Does it introduce hidden coupling between previously independent modules?",
|
|
15553
|
+
"Is the chosen approach the simplest one that satisfies the requirement?"
|
|
15554
|
+
]
|
|
15555
|
+
},
|
|
15556
|
+
"security-reviewer": {
|
|
15557
|
+
responsibilities: [
|
|
15558
|
+
"Identify security vulnerabilities",
|
|
15559
|
+
"Review for OWASP Top 10 risks",
|
|
15560
|
+
"Check compliance requirements",
|
|
15561
|
+
"Flag credential, injection, auth, and supply-chain issues"
|
|
15562
|
+
],
|
|
15563
|
+
checklist: [
|
|
15564
|
+
"Injection vectors: SQL, command, template, LDAP?",
|
|
15565
|
+
"Auth: bypass, session fixation, privilege escalation?",
|
|
15566
|
+
"Credentials: hardcoded secrets, tokens in logs, insecure storage?",
|
|
15567
|
+
"Supply chain: untrusted or unpinned dependencies?",
|
|
15568
|
+
"Data exposure: PII in logs, internals leaking through error messages?"
|
|
15569
|
+
],
|
|
15570
|
+
vetoNote: "Any CRITICAL finding here sets `securityVeto: true` — it overrides majority consensus."
|
|
15571
|
+
},
|
|
15572
|
+
product: {
|
|
15573
|
+
responsibilities: [
|
|
15574
|
+
"Understand requirements",
|
|
15575
|
+
"Evaluate UX decisions",
|
|
15576
|
+
"Assess business value",
|
|
15577
|
+
"Prioritize features"
|
|
15578
|
+
],
|
|
15579
|
+
checklist: [
|
|
15580
|
+
"Does the change satisfy the stated requirement and acceptance criteria?",
|
|
15581
|
+
"Is there a user-facing regression or an unclear interaction?",
|
|
15582
|
+
"Is the scope proportional to the business value, not gold-plated?"
|
|
15583
|
+
]
|
|
15584
|
+
},
|
|
15585
|
+
delivery: {
|
|
15586
|
+
responsibilities: [
|
|
15587
|
+
"Review test coverage",
|
|
15588
|
+
"Assess deployment readiness",
|
|
15589
|
+
"Evaluate code quality",
|
|
15590
|
+
"Suggest improvements"
|
|
15591
|
+
],
|
|
15592
|
+
checklist: [
|
|
15593
|
+
"Is test coverage adequate for happy path, edge cases, and error cases?",
|
|
15594
|
+
"Can this ship without a manual follow-up step?",
|
|
15595
|
+
"Is there a rollback path or observability for this change?"
|
|
15596
|
+
]
|
|
15597
|
+
},
|
|
15598
|
+
"data-ops": {
|
|
15599
|
+
responsibilities: [
|
|
15600
|
+
"Review data pipelines",
|
|
15601
|
+
"Assess analytics implementation",
|
|
15602
|
+
"Check data quality",
|
|
15603
|
+
"Suggest improvements"
|
|
15604
|
+
],
|
|
15605
|
+
checklist: [
|
|
15606
|
+
"Does the change affect schemas, migrations, or pipelines safely?",
|
|
15607
|
+
"Is any analytics or tracking impact documented?",
|
|
15608
|
+
"Is backward compatibility preserved for existing data consumers?"
|
|
15609
|
+
]
|
|
15610
|
+
},
|
|
15611
|
+
devil: {
|
|
15612
|
+
responsibilities: [
|
|
15613
|
+
"Challenge assumptions",
|
|
15614
|
+
"Find edge cases",
|
|
15615
|
+
"Identify failure modes",
|
|
15616
|
+
"Stress test solutions"
|
|
15617
|
+
],
|
|
15618
|
+
checklist: [
|
|
15619
|
+
"Assumption: what is being assumed that has not been verified?",
|
|
15620
|
+
"Failure mode: how does this break under load, edge cases, or partial failure?",
|
|
15621
|
+
"Scope: what is being pulled in that the objective does not require?",
|
|
15622
|
+
"Simpler path: was a materially simpler approach dismissed too fast?",
|
|
15623
|
+
"Reversibility: if this is wrong, how expensive is it to undo?"
|
|
15624
|
+
]
|
|
15625
|
+
},
|
|
15626
|
+
"seo-auditor": {
|
|
15627
|
+
responsibilities: [
|
|
15628
|
+
"Audit technical SEO",
|
|
15629
|
+
"Check meta tags and headings",
|
|
15630
|
+
"Validate crawl directives",
|
|
15631
|
+
"Assess page speed signals"
|
|
15632
|
+
],
|
|
15633
|
+
checklist: [
|
|
15634
|
+
"Are meta tags, headings, and crawl directives correct?",
|
|
15635
|
+
"Does the page speed profile regress Core Web Vitals?"
|
|
15636
|
+
]
|
|
15637
|
+
},
|
|
15638
|
+
"schema-validator": {
|
|
15639
|
+
responsibilities: [
|
|
15640
|
+
"Validate Schema.org markup",
|
|
15641
|
+
"Check JSON-LD syntax",
|
|
15642
|
+
"Verify required properties",
|
|
15643
|
+
"Suggest structured data fixes"
|
|
15644
|
+
],
|
|
15645
|
+
checklist: [
|
|
15646
|
+
"Is the JSON-LD syntactically valid and schema.org-compliant?",
|
|
15647
|
+
"Are all required properties for the markup type present?"
|
|
15648
|
+
]
|
|
15649
|
+
},
|
|
15650
|
+
"geo-specialist": {
|
|
15651
|
+
responsibilities: [
|
|
15652
|
+
"Assess AI-search readiness",
|
|
15653
|
+
"Validate llms.txt",
|
|
15654
|
+
"Check citable content",
|
|
15655
|
+
"Review GEO optimization"
|
|
15656
|
+
],
|
|
15657
|
+
checklist: [
|
|
15658
|
+
"Is content structured for passage-level citability?",
|
|
15659
|
+
"Does llms.txt accurately describe crawl permissions?"
|
|
15660
|
+
]
|
|
15661
|
+
},
|
|
15662
|
+
"content-strategist": {
|
|
15663
|
+
responsibilities: [
|
|
15664
|
+
"Plan content marketing",
|
|
15665
|
+
"Guide off-page SEO",
|
|
15666
|
+
"Suggest backlink strategy",
|
|
15667
|
+
"Review hotel copywriting"
|
|
15668
|
+
],
|
|
15669
|
+
checklist: [
|
|
15670
|
+
"Does the content plan align with the target audience and intent?",
|
|
15671
|
+
"Is the backlink strategy realistic and policy-compliant?"
|
|
15672
|
+
]
|
|
15673
|
+
},
|
|
15674
|
+
"astro-specialist": {
|
|
15675
|
+
responsibilities: [
|
|
15676
|
+
"Validate Astro SEO patterns",
|
|
15677
|
+
"Check static generation",
|
|
15678
|
+
"Review Islands Architecture",
|
|
15679
|
+
"Optimize image handling"
|
|
15680
|
+
],
|
|
15681
|
+
checklist: [
|
|
15682
|
+
"Are pages statically generated where possible?",
|
|
15683
|
+
"Is client-side hydration limited to interactive islands?"
|
|
15684
|
+
]
|
|
15685
|
+
}
|
|
15686
|
+
};
|
|
15687
|
+
DEFAULT_PROFILE = {
|
|
15688
|
+
responsibilities: ["Provide critical review"],
|
|
15689
|
+
checklist: ["Does the change satisfy this role’s stated focus areas?"]
|
|
15690
|
+
};
|
|
15691
|
+
});
|
|
15475
15692
|
|
|
15476
15693
|
// src/adapters/agy/agy-council-generator.ts
|
|
15477
15694
|
function generateAgyFiles(spec) {
|
|
@@ -15530,24 +15747,6 @@ ${generatePermissionBlock(agent.context)}
|
|
|
15530
15747
|
|
|
15531
15748
|
${generateAgentContent(agent)}`;
|
|
15532
15749
|
}
|
|
15533
|
-
function generatePermissionBlock(context) {
|
|
15534
|
-
if (context === "repo-readonly") {
|
|
15535
|
-
return ` read: allow
|
|
15536
|
-
edit: deny
|
|
15537
|
-
bash: deny
|
|
15538
|
-
glob: allow
|
|
15539
|
-
grep: allow
|
|
15540
|
-
webfetch: deny
|
|
15541
|
-
websearch: deny`;
|
|
15542
|
-
}
|
|
15543
|
-
return ` read: deny
|
|
15544
|
-
edit: deny
|
|
15545
|
-
bash: deny
|
|
15546
|
-
glob: deny
|
|
15547
|
-
grep: deny
|
|
15548
|
-
webfetch: deny
|
|
15549
|
-
websearch: deny`;
|
|
15550
|
-
}
|
|
15551
15750
|
function generateCouncilWorkflow(spec) {
|
|
15552
15751
|
return `---
|
|
15553
15752
|
name: cc-council
|
|
@@ -15615,10 +15814,9 @@ If APPROVED (no CRITICAL findings):
|
|
|
15615
15814
|
Deliver the complete Council Verdict. The feature is only complete when tests pass and the council explicitly approves the implementation according to the specification.
|
|
15616
15815
|
`;
|
|
15617
15816
|
}
|
|
15618
|
-
|
|
15619
|
-
|
|
15620
|
-
}
|
|
15621
|
-
var init_agy_council_generator = () => {};
|
|
15817
|
+
var init_agy_council_generator = __esm(() => {
|
|
15818
|
+
init_council_agent();
|
|
15819
|
+
});
|
|
15622
15820
|
|
|
15623
15821
|
// src/adapters/agy/agy-installer.ts
|
|
15624
15822
|
var exports_agy_installer = {};
|
|
@@ -15676,7 +15874,12 @@ function generateClaudeFiles(spec) {
|
|
|
15676
15874
|
return files;
|
|
15677
15875
|
}
|
|
15678
15876
|
function generateCouncilSkill2(spec) {
|
|
15679
|
-
return
|
|
15877
|
+
return `---
|
|
15878
|
+
name: council
|
|
15879
|
+
description: ${yamlString(spec.description)}
|
|
15880
|
+
---
|
|
15881
|
+
|
|
15882
|
+
# Council Skill
|
|
15680
15883
|
|
|
15681
15884
|
## Description
|
|
15682
15885
|
${spec.description}
|
|
@@ -15697,7 +15900,7 @@ ${spec.outputContract}
|
|
|
15697
15900
|
}
|
|
15698
15901
|
function generateCouncilCommand(spec) {
|
|
15699
15902
|
return `---
|
|
15700
|
-
description: ${
|
|
15903
|
+
description: ${yamlString(spec.description)}
|
|
15701
15904
|
---
|
|
15702
15905
|
|
|
15703
15906
|
# Council-Driven Workflow
|
|
@@ -15761,10 +15964,9 @@ If APPROVED (no CRITICAL findings):
|
|
|
15761
15964
|
Deliver the complete Council Verdict. The feature is only complete when tests pass and the council explicitly approves the implementation according to the specification.
|
|
15762
15965
|
`;
|
|
15763
15966
|
}
|
|
15764
|
-
|
|
15765
|
-
|
|
15766
|
-
}
|
|
15767
|
-
var init_claude_council_generator = () => {};
|
|
15967
|
+
var init_claude_council_generator = __esm(() => {
|
|
15968
|
+
init_council_agent();
|
|
15969
|
+
});
|
|
15768
15970
|
|
|
15769
15971
|
// src/adapters/claude/claude-installer.ts
|
|
15770
15972
|
var exports_claude_installer = {};
|
|
@@ -15840,16 +16042,17 @@ ${agentTables}
|
|
|
15840
16042
|
}
|
|
15841
16043
|
function generateCodexAgent(agent) {
|
|
15842
16044
|
const focusAreas = agent.focus.join(", ");
|
|
16045
|
+
const checklist = checklistFor(agent.id).join("; ");
|
|
15843
16046
|
return `name = "${agent.role}"
|
|
15844
16047
|
description = "${agent.role} council agent. Focus: ${focusAreas}. Context: ${agent.context}. Model hint: ${agent.modelHint}."
|
|
15845
16048
|
nickname_candidates = ["${agent.role}", "Council ${agent.role}"]
|
|
15846
|
-
developer_instructions = "You are the ${agent.role} council agent. Your focus areas are: ${focusAreas}. Context: ${agent.context}. Apply ${agent.modelHint} reasoning to your analysis."
|
|
16049
|
+
developer_instructions = "You are the ${agent.role} council agent. Your focus areas are: ${focusAreas}. Context: ${agent.context}. Apply ${agent.modelHint} reasoning to your analysis. Review checklist: ${checklist}. Categorize findings as CRITICAL (blocks the verdict), WARNING, or SUGGESTION."
|
|
15847
16050
|
`;
|
|
15848
16051
|
}
|
|
15849
16052
|
function generateCodexSkill(spec) {
|
|
15850
16053
|
return `---
|
|
15851
16054
|
name: council
|
|
15852
|
-
description: ${spec.description}
|
|
16055
|
+
description: ${yamlString(spec.description)}
|
|
15853
16056
|
version: ${spec.version}
|
|
15854
16057
|
---
|
|
15855
16058
|
|
|
@@ -15861,6 +16064,9 @@ ${spec.agents.map((a) => `- **${a.role}** (${a.id}): ${a.focus.join(", ")}`).joi
|
|
|
15861
16064
|
Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
|
|
15862
16065
|
`;
|
|
15863
16066
|
}
|
|
16067
|
+
var init_codex_council_generator = __esm(() => {
|
|
16068
|
+
init_council_agent();
|
|
16069
|
+
});
|
|
15864
16070
|
|
|
15865
16071
|
// src/adapters/codex/codex-installer.ts
|
|
15866
16072
|
var exports_codex_installer = {};
|
|
@@ -15891,115 +16097,367 @@ function createCodexInstaller(spec) {
|
|
|
15891
16097
|
installer.setSpec(spec);
|
|
15892
16098
|
return installer;
|
|
15893
16099
|
}
|
|
15894
|
-
var init_codex_installer = () => {
|
|
16100
|
+
var init_codex_installer = __esm(() => {
|
|
16101
|
+
init_codex_council_generator();
|
|
16102
|
+
});
|
|
15895
16103
|
|
|
15896
|
-
// src/adapters/
|
|
15897
|
-
function
|
|
16104
|
+
// src/adapters/cursor/cursor-council-generator.ts
|
|
16105
|
+
function generateCursorFiles(spec) {
|
|
15898
16106
|
const files = [];
|
|
15899
16107
|
files.push({
|
|
15900
|
-
path: ".
|
|
15901
|
-
content:
|
|
15902
|
-
overwrite: false
|
|
15903
|
-
});
|
|
15904
|
-
files.push({
|
|
15905
|
-
path: ".opencode/agents/council-lead.md",
|
|
15906
|
-
content: generateCouncilLead(spec),
|
|
16108
|
+
path: ".cursor/skills/council/SKILL.md",
|
|
16109
|
+
content: generateCouncilSkill3(spec),
|
|
15907
16110
|
overwrite: false
|
|
15908
16111
|
});
|
|
15909
16112
|
for (const agent of spec.agents) {
|
|
15910
16113
|
files.push({
|
|
15911
|
-
path: `.
|
|
15912
|
-
content:
|
|
16114
|
+
path: `.cursor/agents/council-${agent.id}.md`,
|
|
16115
|
+
content: generateAgentContent(agent),
|
|
15913
16116
|
overwrite: false
|
|
15914
16117
|
});
|
|
15915
16118
|
}
|
|
16119
|
+
files.push({
|
|
16120
|
+
path: ".cursor/commands/cc/council.md",
|
|
16121
|
+
content: generateCouncilCommand2(spec),
|
|
16122
|
+
overwrite: false
|
|
16123
|
+
});
|
|
15916
16124
|
return files;
|
|
15917
16125
|
}
|
|
15918
|
-
function
|
|
16126
|
+
function generateCouncilSkill3(spec) {
|
|
15919
16127
|
return `---
|
|
15920
|
-
|
|
15921
|
-
|
|
15922
|
-
subtask: true
|
|
16128
|
+
name: council
|
|
16129
|
+
description: ${yamlString(spec.description)}
|
|
15923
16130
|
---
|
|
15924
16131
|
|
|
15925
|
-
|
|
16132
|
+
# Council Skill
|
|
16133
|
+
|
|
16134
|
+
## Description
|
|
16135
|
+
${spec.description}
|
|
15926
16136
|
|
|
15927
16137
|
## Version
|
|
15928
16138
|
${spec.version}
|
|
15929
16139
|
|
|
15930
16140
|
## Agents
|
|
15931
|
-
${spec.agents.map((a) => `-
|
|
16141
|
+
${spec.agents.map((a) => `- **${a.role}** (${a.id}): ${a.focus.join(", ")}`).join(`
|
|
15932
16142
|
`)}
|
|
15933
16143
|
|
|
15934
|
-
##
|
|
15935
|
-
|
|
16144
|
+
## Usage
|
|
16145
|
+
Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
|
|
16146
|
+
|
|
16147
|
+
## Context
|
|
16148
|
+
${spec.outputContract}
|
|
15936
16149
|
`;
|
|
15937
16150
|
}
|
|
15938
|
-
function
|
|
16151
|
+
function generateCouncilCommand2(spec) {
|
|
15939
16152
|
return `---
|
|
15940
|
-
description: ${
|
|
15941
|
-
mode: subagent
|
|
15942
|
-
permission:
|
|
15943
|
-
read: allow
|
|
15944
|
-
edit: deny
|
|
15945
|
-
bash: deny
|
|
15946
|
-
glob: allow
|
|
15947
|
-
grep: allow
|
|
15948
|
-
webfetch: deny
|
|
15949
|
-
websearch: deny
|
|
16153
|
+
description: ${yamlString(spec.description)}
|
|
15950
16154
|
---
|
|
15951
16155
|
|
|
15952
|
-
# Council
|
|
16156
|
+
# Council-Driven Workflow
|
|
15953
16157
|
|
|
15954
|
-
|
|
15955
|
-
Coordinates the council and synthesizes perspectives
|
|
16158
|
+
Task request: $ARGUMENTS
|
|
15956
16159
|
|
|
15957
|
-
##
|
|
15958
|
-
${spec.version}
|
|
16160
|
+
## Step 1 — Deliberation & Specification (SDD)
|
|
15959
16161
|
|
|
15960
|
-
|
|
15961
|
-
|
|
15962
|
-
|
|
16162
|
+
Invoke the \`council\` skill to analyze the request before writing any code. The council must act as a steering committee involving \`task-coach\` (Product), \`architect\`, and \`devil\`.
|
|
16163
|
+
|
|
16164
|
+
The council must:
|
|
16165
|
+
1. Clarify the prompt and define the absolute minimum scope (Simplicity Gate).
|
|
16166
|
+
2. Explicitly document all assumptions and resolve ambiguities (Think Before Coding).
|
|
16167
|
+
3. Draft a Task Card & Technical Plan (The Specification).
|
|
16168
|
+
|
|
16169
|
+
**STOP here. Show the agreed Task Card & Technical Plan and wait for human confirmation before continuing.**
|
|
15963
16170
|
|
|
15964
|
-
## Responsibilities
|
|
15965
|
-
- Coordinate agent responses
|
|
15966
|
-
- Synthesize different perspectives
|
|
15967
|
-
- Identify consensus and disagreements
|
|
15968
|
-
- Provide final recommendation
|
|
15969
|
-
`;
|
|
15970
|
-
}
|
|
15971
|
-
function generateOpenCodeAgentContent(agent) {
|
|
15972
|
-
return `---
|
|
15973
|
-
description: ${yamlString3(`${agent.role} council agent. Focus: ${agent.focus.join(", ")}. Context: ${agent.context}. Model hint: ${agent.modelHint}.`)}
|
|
15974
|
-
mode: subagent
|
|
15975
|
-
permission:
|
|
15976
|
-
${generatePermissionBlock2(agent.context)}
|
|
15977
16171
|
---
|
|
15978
16172
|
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
|
|
15983
|
-
|
|
15984
|
-
|
|
15985
|
-
|
|
15986
|
-
|
|
15987
|
-
|
|
15988
|
-
|
|
15989
|
-
|
|
15990
|
-
|
|
15991
|
-
|
|
15992
|
-
|
|
15993
|
-
|
|
15994
|
-
|
|
15995
|
-
|
|
16173
|
+
## Step 2 — Test Definition (TDD)
|
|
16174
|
+
|
|
16175
|
+
Invoke \`tester\` with the approved Task Card & Technical Plan.
|
|
16176
|
+
|
|
16177
|
+
tester must:
|
|
16178
|
+
1. Write failing tests based on the Acceptance Criteria defined in the Task Card.
|
|
16179
|
+
2. Confirm the tests fail as expected (Red state).
|
|
16180
|
+
|
|
16181
|
+
**Goal-Driven Execution (Karpathy)**: Do not proceed until verifiable tests are written and fail for the correct reasons.
|
|
16182
|
+
|
|
16183
|
+
---
|
|
16184
|
+
|
|
16185
|
+
## Step 3 — Surgical Implementation
|
|
16186
|
+
|
|
16187
|
+
Invoke \`implementer\` with the failing tests and the Technical Plan.
|
|
16188
|
+
|
|
16189
|
+
implementer must:
|
|
16190
|
+
1. Write the minimal code required to pass the tests.
|
|
16191
|
+
2. Touch ONLY the files specified in the Technical Plan (Surgical Changes).
|
|
16192
|
+
3. NOT refactor adjacent code, change existing styles, or build speculative features.
|
|
16193
|
+
4. Run the tests. Loop \`implementer\` -> \`tester\` until all tests pass (Green state).
|
|
16194
|
+
|
|
16195
|
+
---
|
|
16196
|
+
|
|
16197
|
+
## Step 4 — Multi-Perspective Council Review
|
|
16198
|
+
|
|
16199
|
+
Invoke the \`council\` skill on the generated diff to perform the final review phase.
|
|
16200
|
+
|
|
16201
|
+
The council will evaluate the diff against the roster's axes (Architecture, Security, Product, Delivery, DataOps, Devil).
|
|
16202
|
+
|
|
16203
|
+
If ANY agent votes CRITICAL (especially due to over-engineering, scope creep, or missing the verifiable goals):
|
|
16204
|
+
- The Review Report status is **BLOCKED**.
|
|
16205
|
+
- Return to Step 3 with the feedback.
|
|
16206
|
+
|
|
16207
|
+
If APPROVED (no CRITICAL findings):
|
|
16208
|
+
- Deliver the final Council Verdict and the diff summary.
|
|
16209
|
+
|
|
16210
|
+
---
|
|
16211
|
+
|
|
16212
|
+
## Completion
|
|
16213
|
+
|
|
16214
|
+
Deliver the complete Council Verdict. The feature is only complete when tests pass and the council explicitly approves the implementation according to the specification.
|
|
16215
|
+
`;
|
|
16216
|
+
}
|
|
16217
|
+
var init_cursor_council_generator = __esm(() => {
|
|
16218
|
+
init_council_agent();
|
|
16219
|
+
});
|
|
16220
|
+
|
|
16221
|
+
// src/adapters/cursor/cursor-installer.ts
|
|
16222
|
+
class CursorInstaller {
|
|
16223
|
+
name = "cursor";
|
|
16224
|
+
target = "cursor";
|
|
16225
|
+
spec = null;
|
|
16226
|
+
setSpec(spec) {
|
|
16227
|
+
this.spec = spec;
|
|
16228
|
+
}
|
|
16229
|
+
async generate() {
|
|
16230
|
+
if (!this.spec) {
|
|
16231
|
+
throw new Error("Council spec not set");
|
|
16232
|
+
}
|
|
16233
|
+
return generateCursorFiles(this.spec);
|
|
16234
|
+
}
|
|
16235
|
+
async isAvailable() {
|
|
16236
|
+
return true;
|
|
16237
|
+
}
|
|
16238
|
+
}
|
|
16239
|
+
function createCursorInstaller(spec) {
|
|
16240
|
+
const installer = new CursorInstaller;
|
|
16241
|
+
installer.setSpec(spec);
|
|
16242
|
+
return installer;
|
|
16243
|
+
}
|
|
16244
|
+
var init_cursor_installer = __esm(() => {
|
|
16245
|
+
init_cursor_council_generator();
|
|
16246
|
+
});
|
|
16247
|
+
|
|
16248
|
+
// src/adapters/gemini/gemini-council-generator.ts
|
|
16249
|
+
function generateGeminiFiles(spec) {
|
|
16250
|
+
const files = [];
|
|
16251
|
+
files.push({
|
|
16252
|
+
path: ".gemini/skills/council/SKILL.md",
|
|
16253
|
+
content: generateCouncilSkill4(spec),
|
|
16254
|
+
overwrite: false
|
|
16255
|
+
});
|
|
16256
|
+
for (const agent of spec.agents) {
|
|
16257
|
+
files.push({
|
|
16258
|
+
path: `.gemini/agents/council-${agent.id}.md`,
|
|
16259
|
+
content: generateAgentContent(agent),
|
|
16260
|
+
overwrite: false
|
|
16261
|
+
});
|
|
16262
|
+
}
|
|
16263
|
+
files.push({
|
|
16264
|
+
path: ".gemini/commands/cc/council.toml",
|
|
16265
|
+
content: generateCouncilToml(spec),
|
|
16266
|
+
overwrite: false
|
|
16267
|
+
});
|
|
16268
|
+
return files;
|
|
16269
|
+
}
|
|
16270
|
+
function generateCouncilSkill4(spec) {
|
|
16271
|
+
return `---
|
|
16272
|
+
name: council
|
|
16273
|
+
description: ${yamlString(spec.description)}
|
|
16274
|
+
---
|
|
16275
|
+
|
|
16276
|
+
# Council Skill
|
|
16277
|
+
|
|
16278
|
+
## Version
|
|
16279
|
+
${spec.version}
|
|
16280
|
+
|
|
16281
|
+
## Agents
|
|
16282
|
+
${spec.agents.map((a) => `- ${a.role} (${a.id}): ${a.focus.join(", ")}`).join(`
|
|
16283
|
+
`)}
|
|
16284
|
+
|
|
16285
|
+
## Usage
|
|
16286
|
+
Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
|
|
16287
|
+
|
|
16288
|
+
## Instructions
|
|
16289
|
+
Coordinate with the council agents and synthesize their perspectives into the configured output contract.
|
|
16290
|
+
|
|
16291
|
+
## Context
|
|
16292
|
+
${spec.outputContract}
|
|
16293
|
+
`;
|
|
16294
|
+
}
|
|
16295
|
+
function generateCouncilToml(spec) {
|
|
16296
|
+
const prompt = tomlEscapePrompt(`## Step 1 — Deliberation & Specification (SDD)
|
|
16297
|
+
|
|
16298
|
+
Invoke the council skill to analyze the request before writing any code. The council must act as a steering committee involving task-coach (Product), architect, and devil.
|
|
16299
|
+
|
|
16300
|
+
The council must:
|
|
16301
|
+
1. Clarify the prompt and define the absolute minimum scope (Simplicity Gate).
|
|
16302
|
+
2. Explicitly document all assumptions and resolve ambiguities (Think Before Coding).
|
|
16303
|
+
3. Draft a Task Card & Technical Plan (The Specification).
|
|
16304
|
+
|
|
16305
|
+
STOP here. Show the agreed Task Card & Technical Plan and wait for human confirmation before continuing.
|
|
16306
|
+
|
|
16307
|
+
---
|
|
16308
|
+
|
|
16309
|
+
## Step 2 — Test Definition (TDD)
|
|
16310
|
+
|
|
16311
|
+
Invoke tester with the approved Task Card & Technical Plan. Write failing tests based on the Acceptance Criteria, then confirm they fail (Red state).
|
|
16312
|
+
|
|
16313
|
+
---
|
|
16314
|
+
|
|
16315
|
+
## Step 3 — Surgical Implementation
|
|
16316
|
+
|
|
16317
|
+
Invoke implementer with the failing tests and the Technical Plan. Write the minimal code required to pass the tests, touching ONLY the files specified in the Technical Plan. Loop implementer -> tester until all tests pass (Green state).
|
|
16318
|
+
|
|
16319
|
+
---
|
|
16320
|
+
|
|
16321
|
+
## Step 4 — Multi-Perspective Council Review
|
|
16322
|
+
|
|
16323
|
+
Invoke the council skill on the generated diff. If ANY agent votes CRITICAL, the Review Report status is BLOCKED and work returns to Step 3. If APPROVED (no CRITICAL findings), deliver the final Council Verdict and the diff summary.
|
|
16324
|
+
|
|
16325
|
+
---
|
|
16326
|
+
|
|
16327
|
+
## Completion
|
|
16328
|
+
|
|
16329
|
+
Deliver the complete Council Verdict. The feature is only complete when tests pass and the council explicitly approves the implementation.
|
|
16330
|
+
|
|
16331
|
+
Task request: {{args}}`);
|
|
16332
|
+
return `description = ${JSON.stringify(spec.description)}
|
|
16333
|
+
|
|
16334
|
+
prompt = """
|
|
16335
|
+
${prompt}
|
|
16336
|
+
"""
|
|
16337
|
+
`;
|
|
16338
|
+
}
|
|
16339
|
+
function tomlEscapePrompt(prompt) {
|
|
16340
|
+
return prompt.replace(/\\/g, "\\\\").replace(/"""/g, "'''");
|
|
16341
|
+
}
|
|
16342
|
+
var init_gemini_council_generator = __esm(() => {
|
|
16343
|
+
init_council_agent();
|
|
16344
|
+
});
|
|
16345
|
+
|
|
16346
|
+
// src/adapters/gemini/gemini-installer.ts
|
|
16347
|
+
class GeminiInstaller {
|
|
16348
|
+
name = "gemini";
|
|
16349
|
+
target = "gemini";
|
|
16350
|
+
spec = null;
|
|
16351
|
+
setSpec(spec) {
|
|
16352
|
+
this.spec = spec;
|
|
16353
|
+
}
|
|
16354
|
+
async generate() {
|
|
16355
|
+
if (!this.spec) {
|
|
16356
|
+
throw new Error("Council spec not set");
|
|
16357
|
+
}
|
|
16358
|
+
return generateGeminiFiles(this.spec);
|
|
16359
|
+
}
|
|
16360
|
+
async isAvailable() {
|
|
16361
|
+
return true;
|
|
16362
|
+
}
|
|
16363
|
+
}
|
|
16364
|
+
function createGeminiInstaller(spec) {
|
|
16365
|
+
const installer = new GeminiInstaller;
|
|
16366
|
+
installer.setSpec(spec);
|
|
16367
|
+
return installer;
|
|
16368
|
+
}
|
|
16369
|
+
var init_gemini_installer = __esm(() => {
|
|
16370
|
+
init_gemini_council_generator();
|
|
16371
|
+
});
|
|
16372
|
+
|
|
16373
|
+
// src/adapters/opencode/opencode-council-generator.ts
|
|
16374
|
+
function generateOpenCodeFiles(spec) {
|
|
16375
|
+
const files = [];
|
|
16376
|
+
files.push({
|
|
16377
|
+
path: ".opencode/commands/cc-council.md",
|
|
16378
|
+
content: generateCouncilCommand3(spec),
|
|
16379
|
+
overwrite: false
|
|
16380
|
+
});
|
|
16381
|
+
files.push({
|
|
16382
|
+
path: ".opencode/agents/council-lead.md",
|
|
16383
|
+
content: generateCouncilLead(spec),
|
|
16384
|
+
overwrite: false
|
|
16385
|
+
});
|
|
16386
|
+
for (const agent of spec.agents) {
|
|
16387
|
+
files.push({
|
|
16388
|
+
path: `.opencode/agents/council-${agent.id}.md`,
|
|
16389
|
+
content: generateOpenCodeAgentContent(agent),
|
|
16390
|
+
overwrite: false
|
|
16391
|
+
});
|
|
16392
|
+
}
|
|
16393
|
+
return files;
|
|
16394
|
+
}
|
|
16395
|
+
function generateCouncilCommand3(spec) {
|
|
16396
|
+
return `---
|
|
16397
|
+
description: ${yamlString(spec.description)}
|
|
16398
|
+
agent: council-lead
|
|
16399
|
+
subtask: true
|
|
16400
|
+
---
|
|
16401
|
+
|
|
16402
|
+
Run the CodeConductor council for multi-perspective analysis.
|
|
16403
|
+
|
|
16404
|
+
## Version
|
|
16405
|
+
${spec.version}
|
|
16406
|
+
|
|
16407
|
+
## Agents
|
|
16408
|
+
${spec.agents.map((a) => `- ${a.role} (${a.id})`).join(`
|
|
16409
|
+
`)}
|
|
16410
|
+
|
|
16411
|
+
## Instructions
|
|
16412
|
+
Coordinate with the council agents and synthesize their perspectives into the configured output contract.
|
|
16413
|
+
`;
|
|
16414
|
+
}
|
|
16415
|
+
function generateCouncilLead(spec) {
|
|
16416
|
+
return `---
|
|
16417
|
+
description: ${yamlString(`${spec.description} Council lead. Coordinates council members and synthesizes recommendations.`)}
|
|
16418
|
+
mode: subagent
|
|
16419
|
+
permission:
|
|
16420
|
+
read: allow
|
|
16421
|
+
edit: deny
|
|
16422
|
+
bash: deny
|
|
16423
|
+
glob: allow
|
|
16424
|
+
grep: allow
|
|
15996
16425
|
webfetch: deny
|
|
15997
|
-
websearch: deny
|
|
16426
|
+
websearch: deny
|
|
16427
|
+
---
|
|
16428
|
+
|
|
16429
|
+
# Council Lead Agent
|
|
16430
|
+
|
|
16431
|
+
## Role
|
|
16432
|
+
Coordinates the council and synthesizes perspectives
|
|
16433
|
+
|
|
16434
|
+
## Version
|
|
16435
|
+
${spec.version}
|
|
16436
|
+
|
|
16437
|
+
## Council Members
|
|
16438
|
+
${spec.agents.map((a) => `- ${a.role}: ${a.focus.join(", ")}`).join(`
|
|
16439
|
+
`)}
|
|
16440
|
+
|
|
16441
|
+
## Responsibilities
|
|
16442
|
+
- Coordinate agent responses
|
|
16443
|
+
- Synthesize different perspectives
|
|
16444
|
+
- Identify consensus and disagreements
|
|
16445
|
+
- Provide final recommendation
|
|
16446
|
+
`;
|
|
15998
16447
|
}
|
|
15999
|
-
function
|
|
16000
|
-
return
|
|
16448
|
+
function generateOpenCodeAgentContent(agent) {
|
|
16449
|
+
return `---
|
|
16450
|
+
description: ${yamlString(`${agent.role} council agent. Focus: ${agent.focus.join(", ")}. Context: ${agent.context}. Model hint: ${agent.modelHint}.`)}
|
|
16451
|
+
mode: subagent
|
|
16452
|
+
permission:
|
|
16453
|
+
${generatePermissionBlock(agent.context)}
|
|
16454
|
+
---
|
|
16455
|
+
|
|
16456
|
+
${generateAgentContent(agent)}`;
|
|
16001
16457
|
}
|
|
16002
|
-
var init_opencode_council_generator = () => {
|
|
16458
|
+
var init_opencode_council_generator = __esm(() => {
|
|
16459
|
+
init_council_agent();
|
|
16460
|
+
});
|
|
16003
16461
|
|
|
16004
16462
|
// src/adapters/opencode/opencode-installer.ts
|
|
16005
16463
|
var exports_opencode_installer = {};
|
|
@@ -16034,6 +16492,150 @@ var init_opencode_installer = __esm(() => {
|
|
|
16034
16492
|
init_opencode_council_generator();
|
|
16035
16493
|
});
|
|
16036
16494
|
|
|
16495
|
+
// src/adapters/pi/pi-council-generator.ts
|
|
16496
|
+
function generatePiFiles(spec) {
|
|
16497
|
+
const files = [];
|
|
16498
|
+
files.push({
|
|
16499
|
+
path: ".agents/skills/council/SKILL.md",
|
|
16500
|
+
content: generateCouncilSkill5(spec),
|
|
16501
|
+
overwrite: false
|
|
16502
|
+
});
|
|
16503
|
+
for (const agent of spec.agents) {
|
|
16504
|
+
files.push({
|
|
16505
|
+
path: `.agents/agents/council-${agent.id}.md`,
|
|
16506
|
+
content: generateAgentContent(agent),
|
|
16507
|
+
overwrite: false
|
|
16508
|
+
});
|
|
16509
|
+
}
|
|
16510
|
+
files.push({
|
|
16511
|
+
path: ".pi/prompts/cc-council.md",
|
|
16512
|
+
content: generateCouncilWorkflow2(spec),
|
|
16513
|
+
overwrite: false
|
|
16514
|
+
});
|
|
16515
|
+
return files;
|
|
16516
|
+
}
|
|
16517
|
+
function generateCouncilSkill5(spec) {
|
|
16518
|
+
return `---
|
|
16519
|
+
name: council
|
|
16520
|
+
description: ${yamlString(spec.description)}
|
|
16521
|
+
---
|
|
16522
|
+
|
|
16523
|
+
# Council Skill
|
|
16524
|
+
|
|
16525
|
+
## Version
|
|
16526
|
+
${spec.version}
|
|
16527
|
+
|
|
16528
|
+
## Agents
|
|
16529
|
+
${spec.agents.map((a) => `- ${a.role} (${a.id}): ${a.focus.join(", ")}`).join(`
|
|
16530
|
+
`)}
|
|
16531
|
+
|
|
16532
|
+
## Usage
|
|
16533
|
+
Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
|
|
16534
|
+
|
|
16535
|
+
## Instructions
|
|
16536
|
+
Coordinate with the council agents and synthesize their perspectives into the configured output contract.
|
|
16537
|
+
|
|
16538
|
+
## Context
|
|
16539
|
+
${spec.outputContract}
|
|
16540
|
+
`;
|
|
16541
|
+
}
|
|
16542
|
+
function generateCouncilWorkflow2(spec) {
|
|
16543
|
+
return `---
|
|
16544
|
+
description: ${yamlString(spec.description)}
|
|
16545
|
+
---
|
|
16546
|
+
|
|
16547
|
+
# Council-Driven Workflow
|
|
16548
|
+
|
|
16549
|
+
Task request: $ARGUMENTS
|
|
16550
|
+
|
|
16551
|
+
## Step 1 — Deliberation & Specification (SDD)
|
|
16552
|
+
|
|
16553
|
+
Invoke the \`council\` skill to analyze the request before writing any code. The council must act as a steering committee involving \`task-coach\` (Product), \`architect\`, and \`devil\`.
|
|
16554
|
+
|
|
16555
|
+
The council must:
|
|
16556
|
+
1. Clarify the prompt and define the absolute minimum scope (Simplicity Gate).
|
|
16557
|
+
2. Explicitly document all assumptions and resolve ambiguities (Think Before Coding).
|
|
16558
|
+
3. Draft a Task Card & Technical Plan (The Specification).
|
|
16559
|
+
|
|
16560
|
+
**STOP here. Show the agreed Task Card & Technical Plan and wait for human confirmation before continuing.**
|
|
16561
|
+
|
|
16562
|
+
---
|
|
16563
|
+
|
|
16564
|
+
## Step 2 — Test Definition (TDD)
|
|
16565
|
+
|
|
16566
|
+
Invoke \`tester\` with the approved Task Card & Technical Plan.
|
|
16567
|
+
|
|
16568
|
+
tester must:
|
|
16569
|
+
1. Write failing tests based on the Acceptance Criteria defined in the Task Card.
|
|
16570
|
+
2. Confirm the tests fail as expected (Red state).
|
|
16571
|
+
|
|
16572
|
+
**Goal-Driven Execution (Karpathy)**: Do not proceed until verifiable tests are written and fail for the correct reasons.
|
|
16573
|
+
|
|
16574
|
+
---
|
|
16575
|
+
|
|
16576
|
+
## Step 3 — Surgical Implementation
|
|
16577
|
+
|
|
16578
|
+
Invoke \`implementer\` with the failing tests and the Technical Plan.
|
|
16579
|
+
|
|
16580
|
+
implementer must:
|
|
16581
|
+
1. Write the minimal code required to pass the tests.
|
|
16582
|
+
2. Touch ONLY the files specified in the Technical Plan (Surgical Changes).
|
|
16583
|
+
3. NOT refactor adjacent code, change existing styles, or build speculative features.
|
|
16584
|
+
4. Run the tests. Loop \`implementer\` -> \`tester\` until all tests pass (Green state).
|
|
16585
|
+
|
|
16586
|
+
---
|
|
16587
|
+
|
|
16588
|
+
## Step 4 — Multi-Perspective Council Review
|
|
16589
|
+
|
|
16590
|
+
Invoke the \`council\` skill on the generated diff to perform the final review phase.
|
|
16591
|
+
|
|
16592
|
+
The council will evaluate the diff against the roster's axes (Architecture, Security, Product, Delivery, DataOps, Devil).
|
|
16593
|
+
|
|
16594
|
+
If ANY agent votes CRITICAL (especially due to over-engineering, scope creep, or missing the verifiable goals):
|
|
16595
|
+
- The Review Report status is **BLOCKED**.
|
|
16596
|
+
- Return to Step 3 with the feedback.
|
|
16597
|
+
|
|
16598
|
+
If APPROVED (no CRITICAL findings):
|
|
16599
|
+
- Deliver the final Council Verdict and the diff summary.
|
|
16600
|
+
|
|
16601
|
+
---
|
|
16602
|
+
|
|
16603
|
+
## Completion
|
|
16604
|
+
|
|
16605
|
+
Deliver the complete Council Verdict. The feature is only complete when tests pass and the council explicitly approves the implementation according to the specification.
|
|
16606
|
+
`;
|
|
16607
|
+
}
|
|
16608
|
+
var init_pi_council_generator = __esm(() => {
|
|
16609
|
+
init_council_agent();
|
|
16610
|
+
});
|
|
16611
|
+
|
|
16612
|
+
// src/adapters/pi/pi-installer.ts
|
|
16613
|
+
class PiInstaller {
|
|
16614
|
+
name = "pi";
|
|
16615
|
+
target = "pi";
|
|
16616
|
+
spec = null;
|
|
16617
|
+
setSpec(spec) {
|
|
16618
|
+
this.spec = spec;
|
|
16619
|
+
}
|
|
16620
|
+
async generate() {
|
|
16621
|
+
if (!this.spec) {
|
|
16622
|
+
throw new Error("Council spec not set");
|
|
16623
|
+
}
|
|
16624
|
+
return generatePiFiles(this.spec);
|
|
16625
|
+
}
|
|
16626
|
+
async isAvailable() {
|
|
16627
|
+
return true;
|
|
16628
|
+
}
|
|
16629
|
+
}
|
|
16630
|
+
function createPiInstaller(spec) {
|
|
16631
|
+
const installer = new PiInstaller;
|
|
16632
|
+
installer.setSpec(spec);
|
|
16633
|
+
return installer;
|
|
16634
|
+
}
|
|
16635
|
+
var init_pi_installer = __esm(() => {
|
|
16636
|
+
init_pi_council_generator();
|
|
16637
|
+
});
|
|
16638
|
+
|
|
16037
16639
|
// src/core/i18n/language-instructions.ts
|
|
16038
16640
|
function getLanguageInstruction(locale) {
|
|
16039
16641
|
const key = SUPPORTED_LOCALES.includes(locale) ? locale : "en";
|
|
@@ -16268,6 +16870,13 @@ async function fileExists4(path) {
|
|
|
16268
16870
|
return false;
|
|
16269
16871
|
}
|
|
16270
16872
|
}
|
|
16873
|
+
function resolveAgyGlobalEntry(entry, homeDir) {
|
|
16874
|
+
const isAntigravityCliSettings = entry.dest.startsWith("antigravity-cli/");
|
|
16875
|
+
return {
|
|
16876
|
+
baseDir: join6(homeDir, ".gemini", ...isAntigravityCliSettings ? [] : ["config"]),
|
|
16877
|
+
entry: isAntigravityCliSettings ? entry : { ...entry, dest: entry.dest.replace(/^\.agents\/?/, "") }
|
|
16878
|
+
};
|
|
16879
|
+
}
|
|
16271
16880
|
async function resolveEntryFiles(entry, presetsDir, baseDir) {
|
|
16272
16881
|
const srcAbsolute = resolve10(presetsDir, entry.src);
|
|
16273
16882
|
try {
|
|
@@ -16440,15 +17049,14 @@ function substituteToolNames(content, modelConfig) {
|
|
|
16440
17049
|
if (!modelConfig.tools && !modelConfig.permissions)
|
|
16441
17050
|
return content;
|
|
16442
17051
|
const target = modelConfig.target;
|
|
16443
|
-
const fmMatch = content.match(
|
|
17052
|
+
const fmMatch = content.match(/^---(\r?\n)([\s\S]*?)\r?\n---/);
|
|
16444
17053
|
if (!fmMatch)
|
|
16445
17054
|
return content;
|
|
16446
|
-
const
|
|
17055
|
+
const eol = fmMatch[1];
|
|
17056
|
+
const frontmatter = fmMatch[2];
|
|
16447
17057
|
if (target === "opencode" && modelConfig.permissions) {
|
|
16448
17058
|
const updatedFrontmatter2 = frontmatter.replace(/^tools:\s*(.+)\r?\n?/m, "");
|
|
16449
|
-
return content.replace(fmMatch[0],
|
|
16450
|
-
${updatedFrontmatter2}
|
|
16451
|
-
---`);
|
|
17059
|
+
return content.replace(fmMatch[0], `---${eol}${updatedFrontmatter2}${eol}---`);
|
|
16452
17060
|
}
|
|
16453
17061
|
if (!modelConfig.tools)
|
|
16454
17062
|
return content;
|
|
@@ -16463,9 +17071,7 @@ ${updatedFrontmatter2}
|
|
|
16463
17071
|
});
|
|
16464
17072
|
return `tools: ${mappedNames.join(", ")}`;
|
|
16465
17073
|
});
|
|
16466
|
-
return content.replace(fmMatch[0],
|
|
16467
|
-
${updatedFrontmatter}
|
|
16468
|
-
---`);
|
|
17074
|
+
return content.replace(fmMatch[0], `---${eol}${updatedFrontmatter}${eol}---`);
|
|
16469
17075
|
}
|
|
16470
17076
|
function injectMcpServers(jsonString, filePath) {
|
|
16471
17077
|
const isAgyMcpConfig = filePath.endsWith("mcp_config.json");
|
|
@@ -16625,11 +17231,9 @@ async function copyFromManifest(manifest, presetsDir, baseDir, isGlobal, dryRun,
|
|
|
16625
17231
|
let resolvedBaseDir = baseDir;
|
|
16626
17232
|
let resolvedEntry = entry;
|
|
16627
17233
|
if (manifest.target === "agy" && isGlobal) {
|
|
16628
|
-
|
|
16629
|
-
|
|
16630
|
-
|
|
16631
|
-
dest: entry.dest.replace(/^\.agents\/?/, "")
|
|
16632
|
-
};
|
|
17234
|
+
const resolved = resolveAgyGlobalEntry(entry, homedir6());
|
|
17235
|
+
resolvedBaseDir = resolved.baseDir;
|
|
17236
|
+
resolvedEntry = resolved.entry;
|
|
16633
17237
|
}
|
|
16634
17238
|
const files = await resolveEntryFiles(resolvedEntry, presetsDir, resolvedBaseDir);
|
|
16635
17239
|
const isTemplate = entry.template === true;
|
|
@@ -16666,18 +17270,31 @@ async function loadManifest(target) {
|
|
|
16666
17270
|
return InstallManifestSchema.parse(data);
|
|
16667
17271
|
}
|
|
16668
17272
|
async function loadModelConfig(target) {
|
|
16669
|
-
const
|
|
16670
|
-
|
|
16671
|
-
|
|
16672
|
-
|
|
17273
|
+
const [rolesRaw, targetRaw] = await Promise.all([
|
|
17274
|
+
readFile6(join7(MODELS_DIR, "roles.yml"), "utf-8"),
|
|
17275
|
+
readFile6(join7(MODELS_DIR, `${target}.yml`), "utf-8")
|
|
17276
|
+
]);
|
|
17277
|
+
const roles = $parse(rolesRaw);
|
|
17278
|
+
const targetData = $parse(targetRaw);
|
|
17279
|
+
return ModelConfigSchema.parse({
|
|
17280
|
+
target: targetData.target,
|
|
17281
|
+
agents: roles.agents,
|
|
17282
|
+
tools: targetData.permissions ? undefined : roles.tools,
|
|
17283
|
+
permissions: targetData.permissions
|
|
17284
|
+
});
|
|
17285
|
+
}
|
|
17286
|
+
async function loadTargetCapabilities(target) {
|
|
17287
|
+
const content = await readFile6(join7(TARGETS_DIR, `${target}.yml`), "utf-8");
|
|
17288
|
+
return TargetCapabilitiesSchema.parse($parse(content));
|
|
16673
17289
|
}
|
|
16674
|
-
var MANIFESTS_DIR, MODELS_DIR, PRESETS_DIR;
|
|
17290
|
+
var MANIFESTS_DIR, MODELS_DIR, TARGETS_DIR, PRESETS_DIR;
|
|
16675
17291
|
var init_manifest_loader = __esm(() => {
|
|
16676
17292
|
init_dist();
|
|
16677
17293
|
init_schemas();
|
|
16678
17294
|
init_package_paths();
|
|
16679
17295
|
MANIFESTS_DIR = join7(SRC_PRESETS_DIR, "manifests");
|
|
16680
17296
|
MODELS_DIR = join7(SRC_PRESETS_DIR, "models");
|
|
17297
|
+
TARGETS_DIR = join7(SRC_PRESETS_DIR, "targets");
|
|
16681
17298
|
PRESETS_DIR = ROOT_PRESETS_DIR;
|
|
16682
17299
|
});
|
|
16683
17300
|
|
|
@@ -16724,14 +17341,55 @@ var init_preset_loader = __esm(() => {
|
|
|
16724
17341
|
init_package_paths();
|
|
16725
17342
|
});
|
|
16726
17343
|
|
|
17344
|
+
// src/core/presets/skill-frontmatter.ts
|
|
17345
|
+
function parseFrontmatterFence(content) {
|
|
17346
|
+
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
17347
|
+
if (!fmMatch) {
|
|
17348
|
+
return { ok: false, error: { kind: "missing", message: "No YAML frontmatter fence found" } };
|
|
17349
|
+
}
|
|
17350
|
+
try {
|
|
17351
|
+
return { ok: true, data: $parse(fmMatch[1]) };
|
|
17352
|
+
} catch (e) {
|
|
17353
|
+
return {
|
|
17354
|
+
ok: false,
|
|
17355
|
+
error: { kind: "invalid-yaml", message: e instanceof Error ? e.message : String(e) }
|
|
17356
|
+
};
|
|
17357
|
+
}
|
|
17358
|
+
}
|
|
17359
|
+
function parseSkillFrontmatter(content) {
|
|
17360
|
+
const fence = parseFrontmatterFence(content);
|
|
17361
|
+
if (!fence.ok)
|
|
17362
|
+
return fence;
|
|
17363
|
+
const result = SkillFrontmatterSchema.safeParse(fence.data);
|
|
17364
|
+
if (!result.success) {
|
|
17365
|
+
return {
|
|
17366
|
+
ok: false,
|
|
17367
|
+
error: {
|
|
17368
|
+
kind: "schema",
|
|
17369
|
+
message: result.error.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")
|
|
17370
|
+
}
|
|
17371
|
+
};
|
|
17372
|
+
}
|
|
17373
|
+
return { ok: true, frontmatter: result.data };
|
|
17374
|
+
}
|
|
17375
|
+
function skillIdentifier(frontmatter) {
|
|
17376
|
+
return frontmatter.id ?? frontmatter.name;
|
|
17377
|
+
}
|
|
17378
|
+
var init_skill_frontmatter = __esm(() => {
|
|
17379
|
+
init_dist();
|
|
17380
|
+
init_schemas();
|
|
17381
|
+
});
|
|
17382
|
+
|
|
16727
17383
|
// src/commands/install.command.ts
|
|
16728
17384
|
var exports_install_command = {};
|
|
16729
17385
|
__export(exports_install_command, {
|
|
17386
|
+
verifyRenderedFiles: () => verifyRenderedFiles,
|
|
16730
17387
|
installPresetCommand: () => installPresetCommand,
|
|
16731
17388
|
installCommand: () => installCommand
|
|
16732
17389
|
});
|
|
17390
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
16733
17391
|
import { homedir as homedir7 } from "node:os";
|
|
16734
|
-
import { resolve as resolve12 } from "node:path";
|
|
17392
|
+
import { basename as basename3, dirname as dirname4, resolve as resolve12, sep as sep4 } from "node:path";
|
|
16735
17393
|
async function installCommand(options) {
|
|
16736
17394
|
const { target, dryRun, force, global: isGlobal, output, projectRoot } = options;
|
|
16737
17395
|
const baseDir = isGlobal ? homedir7() : projectRoot;
|
|
@@ -16767,14 +17425,22 @@ async function installCommand(options) {
|
|
|
16767
17425
|
installer = createCodexInstaller(spec);
|
|
16768
17426
|
break;
|
|
16769
17427
|
case "gemini":
|
|
17428
|
+
installer = createGeminiInstaller(spec);
|
|
17429
|
+
break;
|
|
16770
17430
|
case "agy":
|
|
16771
17431
|
installer = createAgyInstaller(spec);
|
|
16772
17432
|
break;
|
|
17433
|
+
case "cursor":
|
|
17434
|
+
installer = createCursorInstaller(spec);
|
|
17435
|
+
break;
|
|
17436
|
+
case "pi":
|
|
17437
|
+
installer = createPiInstaller(spec);
|
|
17438
|
+
break;
|
|
16773
17439
|
default:
|
|
16774
17440
|
continue;
|
|
16775
17441
|
}
|
|
16776
17442
|
const generatedFiles = await installer.generate();
|
|
16777
|
-
const isAgyGlobal =
|
|
17443
|
+
const isAgyGlobal = t === "agy" && isGlobal;
|
|
16778
17444
|
const targetBase = isAgyGlobal ? resolve12(homedir7(), ".gemini", "config") : baseDir;
|
|
16779
17445
|
const resolvedFiles = generatedFiles.map((f) => ({
|
|
16780
17446
|
...f,
|
|
@@ -16838,6 +17504,40 @@ async function installCommand(options) {
|
|
|
16838
17504
|
};
|
|
16839
17505
|
}
|
|
16840
17506
|
}
|
|
17507
|
+
async function verifyRenderedFiles(manifest, baseDir, results) {
|
|
17508
|
+
const templatePrefixes = manifest.entries.filter((e) => e.template === true).map((e) => resolve12(baseDir, e.dest));
|
|
17509
|
+
const warnings = [];
|
|
17510
|
+
for (const r of results) {
|
|
17511
|
+
if (r.dryRun || r.action === "skipped" || r.action === "error")
|
|
17512
|
+
continue;
|
|
17513
|
+
const isTemplateFile = templatePrefixes.some((p) => r.dest === p || r.dest.startsWith(p + sep4));
|
|
17514
|
+
if (!isTemplateFile)
|
|
17515
|
+
continue;
|
|
17516
|
+
let content;
|
|
17517
|
+
try {
|
|
17518
|
+
content = await readFile8(r.dest, "utf-8");
|
|
17519
|
+
} catch {
|
|
17520
|
+
continue;
|
|
17521
|
+
}
|
|
17522
|
+
const leaked = [...new Set(content.match(/\{\{[A-Z_]+\}\}/g) ?? [])];
|
|
17523
|
+
if (leaked.length > 0) {
|
|
17524
|
+
warnings.push(`${r.dest}: unresolved placeholder(s) ${leaked.join(", ")}`);
|
|
17525
|
+
}
|
|
17526
|
+
if (basename3(r.dest) === "SKILL.md") {
|
|
17527
|
+
const parsed = parseSkillFrontmatter(content);
|
|
17528
|
+
if (!parsed.ok) {
|
|
17529
|
+
warnings.push(`${r.dest}: ${parsed.error.kind} — ${parsed.error.message}`);
|
|
17530
|
+
} else {
|
|
17531
|
+
const dir = basename3(dirname4(r.dest));
|
|
17532
|
+
const ident = skillIdentifier(parsed.frontmatter);
|
|
17533
|
+
if (ident !== dir) {
|
|
17534
|
+
warnings.push(`${r.dest}: identifier "${ident}" does not match its directory "${dir}"`);
|
|
17535
|
+
}
|
|
17536
|
+
}
|
|
17537
|
+
}
|
|
17538
|
+
}
|
|
17539
|
+
return warnings;
|
|
17540
|
+
}
|
|
16841
17541
|
async function installPresetCommand(options) {
|
|
16842
17542
|
const { target, dryRun, force, global: isGlobal, projectRoot } = options;
|
|
16843
17543
|
const baseDir = isGlobal ? homedir7() : projectRoot;
|
|
@@ -16854,6 +17554,7 @@ async function installPresetCommand(options) {
|
|
|
16854
17554
|
}
|
|
16855
17555
|
}
|
|
16856
17556
|
const allFileResults = [];
|
|
17557
|
+
const postInstallWarnings = [];
|
|
16857
17558
|
for (const t of targets) {
|
|
16858
17559
|
const manifest = await loadManifest(t);
|
|
16859
17560
|
const modelConfig = await loadModelConfig(t);
|
|
@@ -16861,6 +17562,9 @@ async function installPresetCommand(options) {
|
|
|
16861
17562
|
for (const r of results) {
|
|
16862
17563
|
allFileResults.push({ target: t, ...r });
|
|
16863
17564
|
}
|
|
17565
|
+
if (!dryRun) {
|
|
17566
|
+
postInstallWarnings.push(...await verifyRenderedFiles(manifest, baseDir, results));
|
|
17567
|
+
}
|
|
16864
17568
|
}
|
|
16865
17569
|
const errors3 = allFileResults.filter((r) => r.action === "error");
|
|
16866
17570
|
return {
|
|
@@ -16872,6 +17576,7 @@ async function installPresetCommand(options) {
|
|
|
16872
17576
|
targets,
|
|
16873
17577
|
global: isGlobal,
|
|
16874
17578
|
dryRun,
|
|
17579
|
+
postInstallWarnings,
|
|
16875
17580
|
locale,
|
|
16876
17581
|
presetResolution,
|
|
16877
17582
|
fileResults: allFileResults
|
|
@@ -16892,7 +17597,10 @@ var init_install_command = __esm(() => {
|
|
|
16892
17597
|
init_agy_installer();
|
|
16893
17598
|
init_claude_installer();
|
|
16894
17599
|
init_codex_installer();
|
|
17600
|
+
init_cursor_installer();
|
|
17601
|
+
init_gemini_installer();
|
|
16895
17602
|
init_opencode_installer();
|
|
17603
|
+
init_pi_installer();
|
|
16896
17604
|
init_config_loader();
|
|
16897
17605
|
init_project_detector();
|
|
16898
17606
|
init_file_writer();
|
|
@@ -16900,12 +17608,13 @@ var init_install_command = __esm(() => {
|
|
|
16900
17608
|
init_manifest_loader();
|
|
16901
17609
|
init_preset_loader();
|
|
16902
17610
|
init_runner_target();
|
|
17611
|
+
init_skill_frontmatter();
|
|
16903
17612
|
});
|
|
16904
17613
|
|
|
16905
17614
|
// src/core/security/target-compatibility.ts
|
|
16906
|
-
import { readFile as
|
|
17615
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
16907
17616
|
async function loadTargetSecurityCompatibility() {
|
|
16908
|
-
const policy = $parse(await
|
|
17617
|
+
const policy = $parse(await readFile9(POLICY_PATH, "utf-8"));
|
|
16909
17618
|
const targets = [
|
|
16910
17619
|
"opencode",
|
|
16911
17620
|
"claude",
|
|
@@ -16939,8 +17648,8 @@ var init_target_compatibility = __esm(() => {
|
|
|
16939
17648
|
});
|
|
16940
17649
|
|
|
16941
17650
|
// src/core/presets/update-checker.ts
|
|
16942
|
-
import { stat as stat2, readFile as
|
|
16943
|
-
import { resolve as resolve13, join as join8 } from "node:path";
|
|
17651
|
+
import { stat as stat2, readFile as readFile10 } from "node:fs/promises";
|
|
17652
|
+
import { resolve as resolve13, join as join8, basename as basename4, dirname as dirname5 } from "node:path";
|
|
16944
17653
|
import { homedir as homedir8 } from "node:os";
|
|
16945
17654
|
function getTargetInstallationPath(target, basePath, isGlobal) {
|
|
16946
17655
|
if (target === "agy") {
|
|
@@ -16978,14 +17687,7 @@ async function validateAgentFileSizes(basePath, isGlobal) {
|
|
|
16978
17687
|
return largeFiles;
|
|
16979
17688
|
}
|
|
16980
17689
|
async function validateAgentMarkers(basePath, isGlobal) {
|
|
16981
|
-
const targetsToCheck =
|
|
16982
|
-
"opencode",
|
|
16983
|
-
"claude",
|
|
16984
|
-
"codex",
|
|
16985
|
-
"gemini",
|
|
16986
|
-
"cursor",
|
|
16987
|
-
"agy"
|
|
16988
|
-
];
|
|
17690
|
+
const targetsToCheck = INDIVIDUAL_TARGETS;
|
|
16989
17691
|
const results = [];
|
|
16990
17692
|
for (const target of targetsToCheck) {
|
|
16991
17693
|
const isInstalled = await isTargetInstalled(target, basePath, isGlobal);
|
|
@@ -17015,7 +17717,7 @@ async function validateAgentMarkers(basePath, isGlobal) {
|
|
|
17015
17717
|
const files = await resolveEntryFiles(resolvedEntry, PRESETS_DIR, targetBaseDir);
|
|
17016
17718
|
for (const { dest } of files) {
|
|
17017
17719
|
try {
|
|
17018
|
-
const content = await
|
|
17720
|
+
const content = await readFile10(dest, "utf-8");
|
|
17019
17721
|
const beginCount = content.split(MANAGED_BEGIN_MARKER).length - 1;
|
|
17020
17722
|
const endCount = content.split(MANAGED_END_MARKER).length - 1;
|
|
17021
17723
|
if (beginCount === 0 && endCount === 0) {
|
|
@@ -17037,10 +17739,63 @@ async function validateAgentMarkers(basePath, isGlobal) {
|
|
|
17037
17739
|
}
|
|
17038
17740
|
return results;
|
|
17039
17741
|
}
|
|
17742
|
+
async function validateSkillFrontmatterFiles(basePath, isGlobal) {
|
|
17743
|
+
const targetsToCheck = INDIVIDUAL_TARGETS;
|
|
17744
|
+
const results = [];
|
|
17745
|
+
for (const target of targetsToCheck) {
|
|
17746
|
+
const isInstalled = await isTargetInstalled(target, basePath, isGlobal);
|
|
17747
|
+
if (!isInstalled)
|
|
17748
|
+
continue;
|
|
17749
|
+
let manifest;
|
|
17750
|
+
try {
|
|
17751
|
+
manifest = await loadManifest(target);
|
|
17752
|
+
} catch {
|
|
17753
|
+
continue;
|
|
17754
|
+
}
|
|
17755
|
+
for (const entry of manifest.entries) {
|
|
17756
|
+
if (!entry.dest.split(/[\\/]/).includes("skills"))
|
|
17757
|
+
continue;
|
|
17758
|
+
let resolvedEntry = entry;
|
|
17759
|
+
let targetBaseDir = basePath;
|
|
17760
|
+
if (target === "agy" && isGlobal) {
|
|
17761
|
+
targetBaseDir = join8(homedir8(), ".gemini", "config");
|
|
17762
|
+
resolvedEntry = {
|
|
17763
|
+
...entry,
|
|
17764
|
+
dest: entry.dest.replace(/^\.agents\/?/, "")
|
|
17765
|
+
};
|
|
17766
|
+
}
|
|
17767
|
+
const files = await resolveEntryFiles(resolvedEntry, PRESETS_DIR, targetBaseDir);
|
|
17768
|
+
for (const { dest } of files) {
|
|
17769
|
+
if (basename4(dest) !== "SKILL.md")
|
|
17770
|
+
continue;
|
|
17771
|
+
let content;
|
|
17772
|
+
try {
|
|
17773
|
+
content = await readFile10(dest, "utf-8");
|
|
17774
|
+
} catch {
|
|
17775
|
+
continue;
|
|
17776
|
+
}
|
|
17777
|
+
const parsed = parseSkillFrontmatter(content);
|
|
17778
|
+
if (!parsed.ok) {
|
|
17779
|
+
results.push({ path: dest, error: `${parsed.error.kind}: ${parsed.error.message}` });
|
|
17780
|
+
continue;
|
|
17781
|
+
}
|
|
17782
|
+
const dir = basename4(dirname5(dest));
|
|
17783
|
+
const ident = skillIdentifier(parsed.frontmatter);
|
|
17784
|
+
if (ident !== dir) {
|
|
17785
|
+
results.push({
|
|
17786
|
+
path: dest,
|
|
17787
|
+
error: `identifier "${ident}" does not match its directory "${dir}"`
|
|
17788
|
+
});
|
|
17789
|
+
}
|
|
17790
|
+
}
|
|
17791
|
+
}
|
|
17792
|
+
}
|
|
17793
|
+
return results;
|
|
17794
|
+
}
|
|
17040
17795
|
async function fileContentDiffers(pathA, pathB) {
|
|
17041
17796
|
try {
|
|
17042
|
-
const contentA = await
|
|
17043
|
-
const contentB = await
|
|
17797
|
+
const contentA = await readFile10(pathA, "utf-8");
|
|
17798
|
+
const contentB = await readFile10(pathB, "utf-8");
|
|
17044
17799
|
return contentA.trim() !== contentB.trim();
|
|
17045
17800
|
} catch {
|
|
17046
17801
|
try {
|
|
@@ -17058,50 +17813,42 @@ async function loadSkillsLock(basePath) {
|
|
|
17058
17813
|
];
|
|
17059
17814
|
for (const p of paths) {
|
|
17060
17815
|
try {
|
|
17061
|
-
const content = await
|
|
17816
|
+
const content = await readFile10(p, "utf-8");
|
|
17062
17817
|
return JSON.parse(content);
|
|
17063
17818
|
} catch {}
|
|
17064
17819
|
}
|
|
17065
17820
|
return null;
|
|
17066
17821
|
}
|
|
17067
|
-
async function
|
|
17068
|
-
|
|
17069
|
-
|
|
17070
|
-
"agy",
|
|
17071
|
-
"claude",
|
|
17072
|
-
"codex",
|
|
17073
|
-
"gemini",
|
|
17074
|
-
"cursor"
|
|
17075
|
-
];
|
|
17076
|
-
for (const target of targets) {
|
|
17077
|
-
const skillPath = resolve13(ROOT_PRESETS_DIR, target, "skills", skillId, "SKILL.md");
|
|
17078
|
-
try {
|
|
17079
|
-
const content = await readFile9(skillPath, "utf-8");
|
|
17080
|
-
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
17081
|
-
if (fmMatch) {
|
|
17082
|
-
const parsed = $parse(fmMatch[1]);
|
|
17083
|
-
if (parsed && parsed.id === skillId && parsed.version) {
|
|
17084
|
-
return String(parsed.version);
|
|
17085
|
-
}
|
|
17086
|
-
}
|
|
17087
|
-
} catch {}
|
|
17822
|
+
async function loadSkillsRegistry() {
|
|
17823
|
+
if (registryLoadAttempted) {
|
|
17824
|
+
return cachedRegistry ?? null;
|
|
17088
17825
|
}
|
|
17826
|
+
registryLoadAttempted = true;
|
|
17827
|
+
try {
|
|
17828
|
+
const content = await readFile10(SKILLS_REGISTRY_PATH, "utf-8");
|
|
17829
|
+
const parsed = JSON.parse(content);
|
|
17830
|
+
const result = SkillsRegistrySchema.safeParse(parsed);
|
|
17831
|
+
if (result.success) {
|
|
17832
|
+
cachedRegistry = result.data;
|
|
17833
|
+
return cachedRegistry;
|
|
17834
|
+
}
|
|
17835
|
+
} catch {}
|
|
17089
17836
|
return null;
|
|
17090
17837
|
}
|
|
17838
|
+
async function getLatestSkillVersion(skillId) {
|
|
17839
|
+
const registry = await loadSkillsRegistry();
|
|
17840
|
+
if (!registry) {
|
|
17841
|
+
return null;
|
|
17842
|
+
}
|
|
17843
|
+
return registry.skills[skillId]?.version ?? null;
|
|
17844
|
+
}
|
|
17091
17845
|
async function checkUpdates(basePath, isGlobal) {
|
|
17092
17846
|
const localCouncil = resolve13(basePath, ".codeconductor", "presets", "council.yml");
|
|
17093
17847
|
const bundledCouncil = resolve13(SRC_PRESETS_DIR, "council", "council.yml");
|
|
17094
17848
|
const councilHasUpdate = await fileContentDiffers(localCouncil, bundledCouncil);
|
|
17095
17849
|
const localPolicy = resolve13(basePath, ".codeconductor", "presets", "policy.yml");
|
|
17096
17850
|
const policyHasUpdate = await fileContentDiffers(localPolicy, POLICY_PATH);
|
|
17097
|
-
const targetsToCheck =
|
|
17098
|
-
"opencode",
|
|
17099
|
-
"claude",
|
|
17100
|
-
"codex",
|
|
17101
|
-
"gemini",
|
|
17102
|
-
"cursor",
|
|
17103
|
-
"agy"
|
|
17104
|
-
];
|
|
17851
|
+
const targetsToCheck = INDIVIDUAL_TARGETS;
|
|
17105
17852
|
const targetResults = [];
|
|
17106
17853
|
let locale = "en";
|
|
17107
17854
|
try {
|
|
@@ -17142,14 +17889,14 @@ async function checkUpdates(basePath, isGlobal) {
|
|
|
17142
17889
|
for (const { src, dest } of files) {
|
|
17143
17890
|
let expectedContent;
|
|
17144
17891
|
try {
|
|
17145
|
-
const srcContent = await
|
|
17892
|
+
const srcContent = await readFile10(src, "utf-8");
|
|
17146
17893
|
expectedContent = isTemplate && modelConfig ? renderTemplate(srcContent, modelConfig, src, locale) : srcContent;
|
|
17147
17894
|
} catch {
|
|
17148
17895
|
continue;
|
|
17149
17896
|
}
|
|
17150
17897
|
let destContent;
|
|
17151
17898
|
try {
|
|
17152
|
-
destContent = await
|
|
17899
|
+
destContent = await readFile10(dest, "utf-8");
|
|
17153
17900
|
} catch {
|
|
17154
17901
|
changedFiles.push(dest);
|
|
17155
17902
|
continue;
|
|
@@ -17227,7 +17974,7 @@ async function checkUpdates(basePath, isGlobal) {
|
|
|
17227
17974
|
const dest = resolve13(targetBase, targetPath);
|
|
17228
17975
|
let destContent;
|
|
17229
17976
|
try {
|
|
17230
|
-
destContent = await
|
|
17977
|
+
destContent = await readFile10(dest, "utf-8");
|
|
17231
17978
|
if (destContent.trim() !== f.content.trim()) {
|
|
17232
17979
|
changedFiles.push(dest);
|
|
17233
17980
|
}
|
|
@@ -17283,12 +18030,15 @@ async function checkUpdates(basePath, isGlobal) {
|
|
|
17283
18030
|
skills: skillResults
|
|
17284
18031
|
};
|
|
17285
18032
|
}
|
|
18033
|
+
var cachedRegistry, registryLoadAttempted = false;
|
|
17286
18034
|
var init_update_checker = __esm(() => {
|
|
17287
|
-
init_dist();
|
|
17288
18035
|
init_manifest_loader();
|
|
17289
18036
|
init_file_copier();
|
|
18037
|
+
init_skill_frontmatter();
|
|
17290
18038
|
init_config_loader();
|
|
17291
18039
|
init_package_paths();
|
|
18040
|
+
init_schemas();
|
|
18041
|
+
init_runner_target();
|
|
17292
18042
|
init_complementary_detector();
|
|
17293
18043
|
});
|
|
17294
18044
|
|
|
@@ -17449,6 +18199,122 @@ async function doctorCommand(options) {
|
|
|
17449
18199
|
message: "All agent files have valid managed markers"
|
|
17450
18200
|
});
|
|
17451
18201
|
}
|
|
18202
|
+
const manifestErrors = [];
|
|
18203
|
+
for (const target of INDIVIDUAL_TARGETS) {
|
|
18204
|
+
try {
|
|
18205
|
+
await loadManifest(target);
|
|
18206
|
+
} catch (e) {
|
|
18207
|
+
manifestErrors.push(`${target}: ${e instanceof Error ? e.message : String(e)}`);
|
|
18208
|
+
}
|
|
18209
|
+
}
|
|
18210
|
+
if (manifestErrors.length > 0) {
|
|
18211
|
+
checks.push({
|
|
18212
|
+
name: "manifest-schema",
|
|
18213
|
+
status: "fail",
|
|
18214
|
+
message: `Invalid manifest(s): ${manifestErrors.join("; ")}`
|
|
18215
|
+
});
|
|
18216
|
+
} else {
|
|
18217
|
+
checks.push({
|
|
18218
|
+
name: "manifest-schema",
|
|
18219
|
+
status: "pass",
|
|
18220
|
+
message: `All ${INDIVIDUAL_TARGETS.length} target manifests are valid`
|
|
18221
|
+
});
|
|
18222
|
+
}
|
|
18223
|
+
const targetCapabilityErrors = [];
|
|
18224
|
+
for (const target of INDIVIDUAL_TARGETS) {
|
|
18225
|
+
try {
|
|
18226
|
+
await loadTargetCapabilities(target);
|
|
18227
|
+
} catch (e) {
|
|
18228
|
+
targetCapabilityErrors.push(`${target}: ${e instanceof Error ? e.message : String(e)}`);
|
|
18229
|
+
}
|
|
18230
|
+
}
|
|
18231
|
+
if (targetCapabilityErrors.length > 0) {
|
|
18232
|
+
checks.push({
|
|
18233
|
+
name: "target-capabilities",
|
|
18234
|
+
status: "fail",
|
|
18235
|
+
message: `Invalid target capability file(s): ${targetCapabilityErrors.join("; ")}`
|
|
18236
|
+
});
|
|
18237
|
+
} else {
|
|
18238
|
+
checks.push({
|
|
18239
|
+
name: "target-capabilities",
|
|
18240
|
+
status: "pass",
|
|
18241
|
+
message: `All ${INDIVIDUAL_TARGETS.length} target capability files are valid`
|
|
18242
|
+
});
|
|
18243
|
+
}
|
|
18244
|
+
const { readFile: readFile11 } = await import("node:fs/promises");
|
|
18245
|
+
const { SkillsRegistrySchema: SkillsRegistrySchema2 } = await Promise.resolve().then(() => (init_schemas(), exports_schemas));
|
|
18246
|
+
const { SKILLS_REGISTRY_PATH: SKILLS_REGISTRY_PATH2 } = await Promise.resolve().then(() => (init_package_paths(), exports_package_paths));
|
|
18247
|
+
try {
|
|
18248
|
+
const registryContent = await readFile11(SKILLS_REGISTRY_PATH2, "utf-8");
|
|
18249
|
+
const registryData = JSON.parse(registryContent);
|
|
18250
|
+
const registryResult = SkillsRegistrySchema2.safeParse(registryData);
|
|
18251
|
+
if (registryResult.success) {
|
|
18252
|
+
const skillCount = Object.keys(registryResult.data.skills).length;
|
|
18253
|
+
checks.push({
|
|
18254
|
+
name: "skills-registry",
|
|
18255
|
+
status: "pass",
|
|
18256
|
+
message: `Skills registry is valid (${skillCount} skills)`
|
|
18257
|
+
});
|
|
18258
|
+
} else {
|
|
18259
|
+
checks.push({
|
|
18260
|
+
name: "skills-registry",
|
|
18261
|
+
status: "fail",
|
|
18262
|
+
message: `Skills registry validation failed: ${registryResult.error.message}`
|
|
18263
|
+
});
|
|
18264
|
+
}
|
|
18265
|
+
} catch (e) {
|
|
18266
|
+
checks.push({
|
|
18267
|
+
name: "skills-registry",
|
|
18268
|
+
status: "fail",
|
|
18269
|
+
message: `Skills registry error: ${e instanceof Error ? e.message : String(e)}`
|
|
18270
|
+
});
|
|
18271
|
+
}
|
|
18272
|
+
const modelConfigs = await Promise.all(INDIVIDUAL_TARGETS.map(async (target) => {
|
|
18273
|
+
try {
|
|
18274
|
+
const agents = (await loadModelConfig(target)).agents;
|
|
18275
|
+
return { target, agents };
|
|
18276
|
+
} catch {
|
|
18277
|
+
return null;
|
|
18278
|
+
}
|
|
18279
|
+
}));
|
|
18280
|
+
const loadedConfigs = modelConfigs.filter((c) => c !== null);
|
|
18281
|
+
const allRoles = new Set(loadedConfigs.flatMap((c) => Object.keys(c.agents)));
|
|
18282
|
+
const roleGaps = [];
|
|
18283
|
+
for (const role of allRoles) {
|
|
18284
|
+
const missingIn = loadedConfigs.filter((c) => !(role in c.agents)).map((c) => c.target);
|
|
18285
|
+
if (missingIn.length > 0) {
|
|
18286
|
+
roleGaps.push(`${role} missing in ${missingIn.join(", ")}`);
|
|
18287
|
+
}
|
|
18288
|
+
}
|
|
18289
|
+
if (roleGaps.length > 0) {
|
|
18290
|
+
checks.push({
|
|
18291
|
+
name: "model-config-parity",
|
|
18292
|
+
status: "warn",
|
|
18293
|
+
message: `Role parity gaps across target model configs: ${roleGaps.join("; ")}`
|
|
18294
|
+
});
|
|
18295
|
+
} else {
|
|
18296
|
+
checks.push({
|
|
18297
|
+
name: "model-config-parity",
|
|
18298
|
+
status: "pass",
|
|
18299
|
+
message: `All ${allRoles.size} agent roles are defined for every target`
|
|
18300
|
+
});
|
|
18301
|
+
}
|
|
18302
|
+
const skillFrontmatterLocal = await validateSkillFrontmatterFiles(projectRoot, false);
|
|
18303
|
+
const skillFrontmatterGlobal = await validateSkillFrontmatterFiles(homedir9(), true);
|
|
18304
|
+
const allSkillFrontmatterErrors = [...skillFrontmatterLocal, ...skillFrontmatterGlobal];
|
|
18305
|
+
if (allSkillFrontmatterErrors.length > 0) {
|
|
18306
|
+
checks.push({
|
|
18307
|
+
name: "skill-frontmatter",
|
|
18308
|
+
status: "warn",
|
|
18309
|
+
message: `Invalid skill frontmatter: ${allSkillFrontmatterErrors.map((f) => `${f.path} (${f.error})`).join(", ")}`
|
|
18310
|
+
});
|
|
18311
|
+
} else {
|
|
18312
|
+
checks.push({
|
|
18313
|
+
name: "skill-frontmatter",
|
|
18314
|
+
status: "pass",
|
|
18315
|
+
message: "All installed skills have valid frontmatter"
|
|
18316
|
+
});
|
|
18317
|
+
}
|
|
17452
18318
|
const securityCompatibility = await loadTargetSecurityCompatibility();
|
|
17453
18319
|
for (const compatibility of securityCompatibility) {
|
|
17454
18320
|
checks.push({
|
|
@@ -17462,8 +18328,8 @@ async function doctorCommand(options) {
|
|
|
17462
18328
|
const graphPath = join9(projectRoot, ".codeconductor", "product-graph.json");
|
|
17463
18329
|
if (existsSync3(graphPath)) {
|
|
17464
18330
|
try {
|
|
17465
|
-
const { readFile:
|
|
17466
|
-
const raw = await
|
|
18331
|
+
const { readFile: readFile12 } = await import("node:fs/promises");
|
|
18332
|
+
const raw = await readFile12(graphPath, "utf-8");
|
|
17467
18333
|
const graph = ProductGraphSchema2.parse(JSON.parse(raw));
|
|
17468
18334
|
checks.push({
|
|
17469
18335
|
name: "product-graph",
|
|
@@ -17543,6 +18409,8 @@ var init_doctor_command = __esm(() => {
|
|
|
17543
18409
|
init_config_loader();
|
|
17544
18410
|
init_target_compatibility();
|
|
17545
18411
|
init_update_checker();
|
|
18412
|
+
init_manifest_loader();
|
|
18413
|
+
init_runner_target();
|
|
17546
18414
|
});
|
|
17547
18415
|
|
|
17548
18416
|
// src/commands/update.command.ts
|
|
@@ -17551,8 +18419,8 @@ __export(exports_update_command, {
|
|
|
17551
18419
|
updateCommand: () => updateCommand
|
|
17552
18420
|
});
|
|
17553
18421
|
import { homedir as homedir10 } from "node:os";
|
|
17554
|
-
import { resolve as resolve14, dirname as
|
|
17555
|
-
import { mkdir as mkdir6, readFile as
|
|
18422
|
+
import { resolve as resolve14, dirname as dirname6 } from "node:path";
|
|
18423
|
+
import { mkdir as mkdir6, readFile as readFile11, writeFile as writeFile5, stat as stat3 } from "node:fs/promises";
|
|
17556
18424
|
async function updateCommand(options) {
|
|
17557
18425
|
const { dryRun, force, global: isGlobal, output, projectRoot } = options;
|
|
17558
18426
|
const basePath = isGlobal ? homedir10() : projectRoot;
|
|
@@ -17620,8 +18488,8 @@ async function updateCommand(options) {
|
|
|
17620
18488
|
const localCouncil = resolve14(basePath, ".codeconductor", "presets", "council.yml");
|
|
17621
18489
|
const bundledCouncil = resolve14(SRC_PRESETS_DIR, "council", "council.yml");
|
|
17622
18490
|
try {
|
|
17623
|
-
const content = await
|
|
17624
|
-
await mkdir6(
|
|
18491
|
+
const content = await readFile11(bundledCouncil, "utf-8");
|
|
18492
|
+
await mkdir6(dirname6(localCouncil), { recursive: true });
|
|
17625
18493
|
await writeFile5(localCouncil, content, "utf-8");
|
|
17626
18494
|
updated.push(localCouncil);
|
|
17627
18495
|
} catch (e) {
|
|
@@ -17631,8 +18499,8 @@ async function updateCommand(options) {
|
|
|
17631
18499
|
if (updateResults.policy) {
|
|
17632
18500
|
const localPolicy = resolve14(basePath, ".codeconductor", "presets", "policy.yml");
|
|
17633
18501
|
try {
|
|
17634
|
-
const content = await
|
|
17635
|
-
await mkdir6(
|
|
18502
|
+
const content = await readFile11(POLICY_PATH, "utf-8");
|
|
18503
|
+
await mkdir6(dirname6(localPolicy), { recursive: true });
|
|
17636
18504
|
await writeFile5(localPolicy, content, "utf-8");
|
|
17637
18505
|
updated.push(localPolicy);
|
|
17638
18506
|
} catch (e) {
|
|
@@ -17723,7 +18591,7 @@ async function updateCommand(options) {
|
|
|
17723
18591
|
}
|
|
17724
18592
|
} catch {}
|
|
17725
18593
|
try {
|
|
17726
|
-
await mkdir6(
|
|
18594
|
+
await mkdir6(dirname6(lockDest), { recursive: true });
|
|
17727
18595
|
await writeFile5(lockDest, JSON.stringify(newSkillsLock, null, 2), "utf-8");
|
|
17728
18596
|
updated.push(lockDest);
|
|
17729
18597
|
} catch (e) {
|
|
@@ -17759,6 +18627,179 @@ var init_update_command = __esm(() => {
|
|
|
17759
18627
|
init_package_paths();
|
|
17760
18628
|
});
|
|
17761
18629
|
|
|
18630
|
+
// src/commands/migrate.command.ts
|
|
18631
|
+
var exports_migrate_command = {};
|
|
18632
|
+
__export(exports_migrate_command, {
|
|
18633
|
+
migratePermissionRules: () => migratePermissionRules,
|
|
18634
|
+
migrateCommand: () => migrateCommand,
|
|
18635
|
+
findOrphanedPromptVersions: () => findOrphanedPromptVersions
|
|
18636
|
+
});
|
|
18637
|
+
import { readFile as readFile12, readdir as readdir3, rm as rm2, writeFile as writeFile6 } from "node:fs/promises";
|
|
18638
|
+
import { homedir as homedir11 } from "node:os";
|
|
18639
|
+
import { join as join10, resolve as resolve15 } from "node:path";
|
|
18640
|
+
function migratePermissionRules(settings) {
|
|
18641
|
+
const permissions = settings.permissions;
|
|
18642
|
+
if (typeof permissions !== "object" || permissions === null) {
|
|
18643
|
+
return { settings, changes: [], duplicatesRemoved: [] };
|
|
18644
|
+
}
|
|
18645
|
+
const changes = [];
|
|
18646
|
+
const duplicatesRemoved = [];
|
|
18647
|
+
const nextPermissions = { ...permissions };
|
|
18648
|
+
for (const list of PERMISSION_LISTS) {
|
|
18649
|
+
const rules = nextPermissions[list];
|
|
18650
|
+
if (!Array.isArray(rules))
|
|
18651
|
+
continue;
|
|
18652
|
+
const rewritten = rules.map((rule) => {
|
|
18653
|
+
if (typeof rule !== "string")
|
|
18654
|
+
return rule;
|
|
18655
|
+
const match = rule.match(WRITE_RULE);
|
|
18656
|
+
if (!match)
|
|
18657
|
+
return rule;
|
|
18658
|
+
const to = `Edit(${match[1]})`;
|
|
18659
|
+
changes.push({ list, from: rule, to });
|
|
18660
|
+
return to;
|
|
18661
|
+
});
|
|
18662
|
+
const seen = new Set;
|
|
18663
|
+
const deduped = [];
|
|
18664
|
+
for (const rule of rewritten) {
|
|
18665
|
+
const key = typeof rule === "string" ? rule : JSON.stringify(rule);
|
|
18666
|
+
if (seen.has(key)) {
|
|
18667
|
+
if (typeof rule === "string")
|
|
18668
|
+
duplicatesRemoved.push(rule);
|
|
18669
|
+
continue;
|
|
18670
|
+
}
|
|
18671
|
+
seen.add(key);
|
|
18672
|
+
deduped.push(rule);
|
|
18673
|
+
}
|
|
18674
|
+
nextPermissions[list] = deduped;
|
|
18675
|
+
}
|
|
18676
|
+
return {
|
|
18677
|
+
settings: { ...settings, permissions: nextPermissions },
|
|
18678
|
+
changes,
|
|
18679
|
+
duplicatesRemoved
|
|
18680
|
+
};
|
|
18681
|
+
}
|
|
18682
|
+
function resolveSettingsPath(options) {
|
|
18683
|
+
if (options.file)
|
|
18684
|
+
return resolve15(options.projectRoot, options.file);
|
|
18685
|
+
const base = options.global ? homedir11() : options.projectRoot;
|
|
18686
|
+
return join10(base, ".claude", "settings.json");
|
|
18687
|
+
}
|
|
18688
|
+
async function findOrphanedPromptVersions(basePath, isGlobal) {
|
|
18689
|
+
const found = [];
|
|
18690
|
+
const seenDirs = new Set;
|
|
18691
|
+
for (const target of INDIVIDUAL_TARGETS) {
|
|
18692
|
+
const installed = await isTargetInstalled(target, basePath, isGlobal);
|
|
18693
|
+
if (!installed)
|
|
18694
|
+
continue;
|
|
18695
|
+
const installPath = getTargetInstallationPath(target, basePath, isGlobal);
|
|
18696
|
+
const promptsDir = join10(installPath, "prompts");
|
|
18697
|
+
if (seenDirs.has(promptsDir))
|
|
18698
|
+
continue;
|
|
18699
|
+
seenDirs.add(promptsDir);
|
|
18700
|
+
let entries;
|
|
18701
|
+
try {
|
|
18702
|
+
entries = await readdir3(promptsDir, { withFileTypes: true });
|
|
18703
|
+
} catch {
|
|
18704
|
+
continue;
|
|
18705
|
+
}
|
|
18706
|
+
for (const entry of entries) {
|
|
18707
|
+
if (!entry.isDirectory() || !VERSION_DIR_NAME.test(entry.name))
|
|
18708
|
+
continue;
|
|
18709
|
+
if (entry.name === CURRENT_PRESET_VERSION)
|
|
18710
|
+
continue;
|
|
18711
|
+
found.push({ target, path: join10(promptsDir, entry.name), version: entry.name });
|
|
18712
|
+
}
|
|
18713
|
+
}
|
|
18714
|
+
return found;
|
|
18715
|
+
}
|
|
18716
|
+
async function migrateCommand(options) {
|
|
18717
|
+
const settingsPath = resolveSettingsPath(options);
|
|
18718
|
+
let raw = null;
|
|
18719
|
+
try {
|
|
18720
|
+
raw = await readFile12(settingsPath, "utf-8");
|
|
18721
|
+
} catch (error) {
|
|
18722
|
+
if (error.code !== "ENOENT") {
|
|
18723
|
+
return {
|
|
18724
|
+
code: 1,
|
|
18725
|
+
data: {
|
|
18726
|
+
success: false,
|
|
18727
|
+
command: "migrate",
|
|
18728
|
+
errors: [`Could not read ${settingsPath}: ${String(error)}`]
|
|
18729
|
+
}
|
|
18730
|
+
};
|
|
18731
|
+
}
|
|
18732
|
+
}
|
|
18733
|
+
let rewritten = [];
|
|
18734
|
+
let duplicatesRemoved = [];
|
|
18735
|
+
let settingsChanged = false;
|
|
18736
|
+
if (raw !== null) {
|
|
18737
|
+
let settings;
|
|
18738
|
+
try {
|
|
18739
|
+
settings = JSON.parse(raw);
|
|
18740
|
+
} catch (error) {
|
|
18741
|
+
return {
|
|
18742
|
+
code: 1,
|
|
18743
|
+
data: {
|
|
18744
|
+
success: false,
|
|
18745
|
+
command: "migrate",
|
|
18746
|
+
errors: [`${settingsPath} is not valid JSON: ${String(error)}`]
|
|
18747
|
+
}
|
|
18748
|
+
};
|
|
18749
|
+
}
|
|
18750
|
+
const migration = migratePermissionRules(settings);
|
|
18751
|
+
rewritten = migration.changes;
|
|
18752
|
+
duplicatesRemoved = migration.duplicatesRemoved;
|
|
18753
|
+
settingsChanged = migration.changes.length > 0 || migration.duplicatesRemoved.length > 0;
|
|
18754
|
+
if (settingsChanged && !options.dryRun) {
|
|
18755
|
+
await writeFile6(settingsPath, `${JSON.stringify(migration.settings, null, 2)}
|
|
18756
|
+
`, "utf-8");
|
|
18757
|
+
}
|
|
18758
|
+
}
|
|
18759
|
+
const basePath = options.global ? homedir11() : options.projectRoot;
|
|
18760
|
+
const orphanedPromptVersions = await findOrphanedPromptVersions(basePath, options.global);
|
|
18761
|
+
let orphanedPromptVersionsRemoved = false;
|
|
18762
|
+
if (orphanedPromptVersions.length > 0 && !options.dryRun) {
|
|
18763
|
+
for (const dir of orphanedPromptVersions) {
|
|
18764
|
+
await rm2(dir.path, { recursive: true, force: true });
|
|
18765
|
+
}
|
|
18766
|
+
orphanedPromptVersionsRemoved = true;
|
|
18767
|
+
}
|
|
18768
|
+
const changed = settingsChanged && !options.dryRun || orphanedPromptVersionsRemoved;
|
|
18769
|
+
let message;
|
|
18770
|
+
if (!settingsChanged && orphanedPromptVersions.length === 0) {
|
|
18771
|
+
message = raw === null ? "No settings.json found and no orphaned prompt version directories found — nothing to migrate." : "No Write(path) permission rules and no orphaned prompt version directories found — nothing to migrate.";
|
|
18772
|
+
}
|
|
18773
|
+
return {
|
|
18774
|
+
code: 0,
|
|
18775
|
+
data: {
|
|
18776
|
+
success: true,
|
|
18777
|
+
command: "migrate",
|
|
18778
|
+
file: settingsPath,
|
|
18779
|
+
settingsFileFound: raw !== null,
|
|
18780
|
+
changed,
|
|
18781
|
+
dryRun: options.dryRun,
|
|
18782
|
+
rewritten: rewritten.map((c) => ({ list: c.list, from: c.from, to: c.to })),
|
|
18783
|
+
duplicatesRemoved,
|
|
18784
|
+
orphanedPromptVersions: orphanedPromptVersions.map((d) => ({
|
|
18785
|
+
target: d.target,
|
|
18786
|
+
path: d.path,
|
|
18787
|
+
version: d.version
|
|
18788
|
+
})),
|
|
18789
|
+
orphanedPromptVersionsRemoved,
|
|
18790
|
+
...message ? { message } : {}
|
|
18791
|
+
}
|
|
18792
|
+
};
|
|
18793
|
+
}
|
|
18794
|
+
var PERMISSION_LISTS, WRITE_RULE, VERSION_DIR_NAME;
|
|
18795
|
+
var init_migrate_command = __esm(() => {
|
|
18796
|
+
init_update_checker();
|
|
18797
|
+
init_runner_target();
|
|
18798
|
+
PERMISSION_LISTS = ["allow", "deny", "ask"];
|
|
18799
|
+
WRITE_RULE = /^Write\((.+)\)$/;
|
|
18800
|
+
VERSION_DIR_NAME = /^v\d+\.\d+\.\d+$/;
|
|
18801
|
+
});
|
|
18802
|
+
|
|
17762
18803
|
// src/core/ask/recommend-flow.ts
|
|
17763
18804
|
function includesAny(haystack, needles) {
|
|
17764
18805
|
return needles.some((n) => haystack.includes(n));
|
|
@@ -17948,8 +18989,8 @@ var exports_help_command = {};
|
|
|
17948
18989
|
__export(exports_help_command, {
|
|
17949
18990
|
helpCommand: () => helpCommand
|
|
17950
18991
|
});
|
|
17951
|
-
import { readdir as
|
|
17952
|
-
import { join as
|
|
18992
|
+
import { readdir as readdir4 } from "node:fs/promises";
|
|
18993
|
+
import { join as join11 } from "node:path";
|
|
17953
18994
|
async function scanPresetDir(projectRoot, target) {
|
|
17954
18995
|
const inventory = {
|
|
17955
18996
|
target,
|
|
@@ -17958,13 +18999,13 @@ async function scanPresetDir(projectRoot, target) {
|
|
|
17958
18999
|
agents: [],
|
|
17959
19000
|
workflows: []
|
|
17960
19001
|
};
|
|
17961
|
-
const presetDir =
|
|
19002
|
+
const presetDir = join11(projectRoot, "presets", target);
|
|
17962
19003
|
try {
|
|
17963
|
-
const entries = await
|
|
19004
|
+
const entries = await readdir4(presetDir, { withFileTypes: true });
|
|
17964
19005
|
for (const entry of entries) {
|
|
17965
19006
|
if (entry.isDirectory()) {
|
|
17966
|
-
const subDir =
|
|
17967
|
-
const subEntries = await
|
|
19007
|
+
const subDir = join11(presetDir, entry.name);
|
|
19008
|
+
const subEntries = await readdir4(subDir, { withFileTypes: true });
|
|
17968
19009
|
for (const sub of subEntries) {
|
|
17969
19010
|
if (sub.isFile()) {
|
|
17970
19011
|
const itemName = sub.name.replace(/\.[^.]+$/, "");
|
|
@@ -18089,14 +19130,14 @@ var exports_debt_harvest_command = {};
|
|
|
18089
19130
|
__export(exports_debt_harvest_command, {
|
|
18090
19131
|
debtHarvestCommand: () => debtHarvestCommand
|
|
18091
19132
|
});
|
|
18092
|
-
import { readdir as
|
|
18093
|
-
import { join as
|
|
19133
|
+
import { readdir as readdir5, readFile as readFile13, writeFile as writeFile7, mkdir as mkdir7 } from "node:fs/promises";
|
|
19134
|
+
import { join as join12, relative as relative4, extname } from "node:path";
|
|
18094
19135
|
async function walkDir(dir, extensions) {
|
|
18095
19136
|
const results = [];
|
|
18096
19137
|
try {
|
|
18097
|
-
const entries = await
|
|
19138
|
+
const entries = await readdir5(dir, { withFileTypes: true });
|
|
18098
19139
|
for (const entry of entries) {
|
|
18099
|
-
const fullPath =
|
|
19140
|
+
const fullPath = join12(dir, entry.name);
|
|
18100
19141
|
if (entry.isDirectory()) {
|
|
18101
19142
|
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
18102
19143
|
continue;
|
|
@@ -18163,19 +19204,19 @@ function renderLedger(entries) {
|
|
|
18163
19204
|
async function debtHarvestCommand(options) {
|
|
18164
19205
|
const { projectRoot, dir = "src", output } = options;
|
|
18165
19206
|
try {
|
|
18166
|
-
const targetDir =
|
|
19207
|
+
const targetDir = join12(projectRoot, dir);
|
|
18167
19208
|
const files = await walkDir(targetDir, SOURCE_EXTENSIONS);
|
|
18168
19209
|
const allEntries = [];
|
|
18169
19210
|
for (const file of files) {
|
|
18170
|
-
const content = await
|
|
19211
|
+
const content = await readFile13(file, "utf-8");
|
|
18171
19212
|
const entries = extractDefers(content, relative4(projectRoot, file));
|
|
18172
19213
|
allEntries.push(...entries);
|
|
18173
19214
|
}
|
|
18174
|
-
const ledgerDir =
|
|
19215
|
+
const ledgerDir = join12(projectRoot, ".codeconductor");
|
|
18175
19216
|
await mkdir7(ledgerDir, { recursive: true });
|
|
18176
|
-
const ledgerPath =
|
|
19217
|
+
const ledgerPath = join12(ledgerDir, "debt-ledger.md");
|
|
18177
19218
|
const ledgerContent = renderLedger(allEntries);
|
|
18178
|
-
await
|
|
19219
|
+
await writeFile7(ledgerPath, ledgerContent, "utf-8");
|
|
18179
19220
|
if (output === "json") {
|
|
18180
19221
|
return {
|
|
18181
19222
|
code: 0,
|
|
@@ -18608,27 +19649,27 @@ var init_goal_planner = __esm(() => {
|
|
|
18608
19649
|
});
|
|
18609
19650
|
|
|
18610
19651
|
// src/core/product-graph/paths.ts
|
|
18611
|
-
import { join as
|
|
19652
|
+
import { join as join13 } from "node:path";
|
|
18612
19653
|
function productGraphPath(projectRoot) {
|
|
18613
|
-
return
|
|
19654
|
+
return join13(projectRoot, PRODUCT_DIR, PRODUCT_GRAPH_FILE);
|
|
18614
19655
|
}
|
|
18615
19656
|
function productMetaPath(projectRoot) {
|
|
18616
|
-
return
|
|
19657
|
+
return join13(projectRoot, PRODUCT_DIR, PRODUCT_META_FILE);
|
|
18617
19658
|
}
|
|
18618
19659
|
function eventsPath(projectRoot) {
|
|
18619
|
-
return
|
|
19660
|
+
return join13(projectRoot, PRODUCT_DIR, EVENTS_FILE);
|
|
18620
19661
|
}
|
|
18621
19662
|
function operationalStatePath(projectRoot) {
|
|
18622
|
-
return
|
|
19663
|
+
return join13(projectRoot, PRODUCT_DIR, OPERATIONAL_STATE_FILE);
|
|
18623
19664
|
}
|
|
18624
19665
|
function strategicPath(projectRoot) {
|
|
18625
|
-
return
|
|
19666
|
+
return join13(projectRoot, PRODUCT_DIR, STRATEGIC_FILE);
|
|
18626
19667
|
}
|
|
18627
19668
|
function productReportPath(projectRoot) {
|
|
18628
|
-
return
|
|
19669
|
+
return join13(projectRoot, PRODUCT_DIR, PRODUCT_REPORT_FILE);
|
|
18629
19670
|
}
|
|
18630
19671
|
function evidenceDir(projectRoot) {
|
|
18631
|
-
return
|
|
19672
|
+
return join13(projectRoot, PRODUCT_DIR, EVIDENCE_DIR);
|
|
18632
19673
|
}
|
|
18633
19674
|
var PRODUCT_DIR = ".codeconductor", PRODUCT_GRAPH_FILE = "product-graph.json", PRODUCT_META_FILE = "product-meta.json", EVENTS_FILE = "events.jsonl", OPERATIONAL_STATE_FILE = "operational-state.json", STRATEGIC_FILE = "strategic.json", PRODUCT_REPORT_FILE = "product-report.md", EVIDENCE_DIR = "evidence";
|
|
18634
19675
|
var init_paths = () => {};
|
|
@@ -18645,11 +19686,11 @@ __export(exports_graph_store, {
|
|
|
18645
19686
|
findPath: () => findPath,
|
|
18646
19687
|
countByType: () => countByType
|
|
18647
19688
|
});
|
|
18648
|
-
import { mkdir as mkdir8, readFile as
|
|
18649
|
-
import { dirname as
|
|
19689
|
+
import { mkdir as mkdir8, readFile as readFile14, writeFile as writeFile8 } from "node:fs/promises";
|
|
19690
|
+
import { dirname as dirname7 } from "node:path";
|
|
18650
19691
|
async function loadGraph(projectRoot) {
|
|
18651
19692
|
try {
|
|
18652
|
-
const raw = await
|
|
19693
|
+
const raw = await readFile14(productGraphPath(projectRoot), "utf-8");
|
|
18653
19694
|
return ok(ProductGraphSchema.parse(JSON.parse(raw)));
|
|
18654
19695
|
} catch (e) {
|
|
18655
19696
|
if (e.code === "ENOENT") {
|
|
@@ -18662,8 +19703,8 @@ async function saveGraph(projectRoot, graph) {
|
|
|
18662
19703
|
try {
|
|
18663
19704
|
const validated = ProductGraphSchema.parse(graph);
|
|
18664
19705
|
const path = productGraphPath(projectRoot);
|
|
18665
|
-
await mkdir8(
|
|
18666
|
-
await
|
|
19706
|
+
await mkdir8(dirname7(path), { recursive: true });
|
|
19707
|
+
await writeFile8(path, JSON.stringify(validated, null, 2), "utf-8");
|
|
18667
19708
|
return ok(undefined);
|
|
18668
19709
|
} catch (e) {
|
|
18669
19710
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -18830,8 +19871,8 @@ __export(exports_goal_state, {
|
|
|
18830
19871
|
markTaskBlocked: () => markTaskBlocked,
|
|
18831
19872
|
loadGoal: () => loadGoal
|
|
18832
19873
|
});
|
|
18833
|
-
import { mkdir as mkdir9, readFile as
|
|
18834
|
-
import { resolve as
|
|
19874
|
+
import { mkdir as mkdir9, readFile as readFile15, writeFile as writeFile9 } from "node:fs/promises";
|
|
19875
|
+
import { resolve as resolve16 } from "node:path";
|
|
18835
19876
|
function validateGoalGraph2(graph) {
|
|
18836
19877
|
const ids = new Set(graph.tasks.map((t) => t.id));
|
|
18837
19878
|
if (ids.size !== graph.tasks.length) {
|
|
@@ -18874,16 +19915,16 @@ async function writeGoal(projectRoot, graph) {
|
|
|
18874
19915
|
const validation = validateGoalGraph2(graph);
|
|
18875
19916
|
if (!validation.success)
|
|
18876
19917
|
return validation;
|
|
18877
|
-
const dir =
|
|
19918
|
+
const dir = resolve16(projectRoot, ".codeconductor");
|
|
18878
19919
|
await mkdir9(dir, { recursive: true });
|
|
18879
19920
|
const yaml = $stringify(graph);
|
|
18880
|
-
await
|
|
19921
|
+
await writeFile9(resolve16(dir, "current-goal.yml"), yaml, "utf-8");
|
|
18881
19922
|
return ok(undefined);
|
|
18882
19923
|
}
|
|
18883
19924
|
async function loadGoal(projectRoot) {
|
|
18884
19925
|
try {
|
|
18885
|
-
const filePath =
|
|
18886
|
-
const content = await
|
|
19926
|
+
const filePath = resolve16(projectRoot, GOAL_FILE);
|
|
19927
|
+
const content = await readFile15(filePath, "utf-8");
|
|
18887
19928
|
const data = $parse(content);
|
|
18888
19929
|
const validated = GoalGraphSchema.parse(data);
|
|
18889
19930
|
return validateGoalGraph2(validated);
|
|
@@ -19045,8 +20086,8 @@ var init_goal_command = __esm(() => {
|
|
|
19045
20086
|
});
|
|
19046
20087
|
|
|
19047
20088
|
// src/core/openspec/backlog-parser.ts
|
|
19048
|
-
import { readFile as
|
|
19049
|
-
import { resolve as
|
|
20089
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
20090
|
+
import { resolve as resolve17 } from "node:path";
|
|
19050
20091
|
function parseBool(value) {
|
|
19051
20092
|
const v = value.trim().toLowerCase();
|
|
19052
20093
|
return v === "yes" || v === "true";
|
|
@@ -19220,8 +20261,8 @@ function parseBacklogMarkdown(content) {
|
|
|
19220
20261
|
}
|
|
19221
20262
|
async function loadBacklog(projectRoot) {
|
|
19222
20263
|
try {
|
|
19223
|
-
const filePath =
|
|
19224
|
-
const content = await
|
|
20264
|
+
const filePath = resolve17(projectRoot, BACKLOG_FILE);
|
|
20265
|
+
const content = await readFile16(filePath, "utf-8");
|
|
19225
20266
|
return parseBacklogMarkdown(content);
|
|
19226
20267
|
} catch (e) {
|
|
19227
20268
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -19270,14 +20311,14 @@ function slugify(text) {
|
|
|
19270
20311
|
}
|
|
19271
20312
|
|
|
19272
20313
|
// src/core/knowledge/source-parsers.ts
|
|
19273
|
-
import { readFile as
|
|
19274
|
-
import { join as
|
|
20314
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
20315
|
+
import { join as join14 } from "node:path";
|
|
19275
20316
|
async function parseAdrFile(filePath) {
|
|
19276
20317
|
try {
|
|
19277
|
-
const content = await
|
|
19278
|
-
const
|
|
19279
|
-
const idMatch =
|
|
19280
|
-
const id = idMatch ? `adr-${idMatch[1]}` : slugify(
|
|
20318
|
+
const content = await readFile17(filePath, "utf-8");
|
|
20319
|
+
const basename5 = filePath.split("/").pop() ?? "";
|
|
20320
|
+
const idMatch = basename5.match(/adr-(\d+)/i);
|
|
20321
|
+
const id = idMatch ? `adr-${idMatch[1]}` : slugify(basename5);
|
|
19281
20322
|
const titleMatch = content.match(/^#\s+ADR-\d+:\s*(.+)$/m);
|
|
19282
20323
|
const statusMatch = content.match(/\*\*Status:\*\*\s*(\w+)/i);
|
|
19283
20324
|
const contextSection = extractSection(content, "Context");
|
|
@@ -19287,7 +20328,7 @@ async function parseAdrFile(filePath) {
|
|
|
19287
20328
|
`).filter((l) => l.trim().startsWith("-") || l.trim().startsWith("*")).map((l) => l.replace(/^[\s*-]+/, "").trim()).filter(Boolean);
|
|
19288
20329
|
return {
|
|
19289
20330
|
id,
|
|
19290
|
-
title: titleMatch?.[1]?.trim() ??
|
|
20331
|
+
title: titleMatch?.[1]?.trim() ?? basename5,
|
|
19291
20332
|
status: statusMatch?.[1]?.toLowerCase() ?? "unknown",
|
|
19292
20333
|
context: contextSection.trim(),
|
|
19293
20334
|
decision: decisionSection.trim(),
|
|
@@ -19323,7 +20364,7 @@ function adrToEntities(adr, source) {
|
|
|
19323
20364
|
}
|
|
19324
20365
|
async function parseReadmeEntities(projectRoot, productName) {
|
|
19325
20366
|
try {
|
|
19326
|
-
const content = await
|
|
20367
|
+
const content = await readFile17(join14(projectRoot, "README.md"), "utf-8");
|
|
19327
20368
|
const firstPara = content.split(`
|
|
19328
20369
|
|
|
19329
20370
|
`).find((p) => p.trim() && !p.startsWith("#") && !p.startsWith(">")) ?? "";
|
|
@@ -19344,7 +20385,7 @@ async function parseReadmeEntities(projectRoot, productName) {
|
|
|
19344
20385
|
}
|
|
19345
20386
|
async function parseGraphifyEntities(projectRoot) {
|
|
19346
20387
|
try {
|
|
19347
|
-
const raw = await
|
|
20388
|
+
const raw = await readFile17(join14(projectRoot, "graphify-out", "graph.json"), "utf-8");
|
|
19348
20389
|
const graph = JSON.parse(raw);
|
|
19349
20390
|
const entities = [];
|
|
19350
20391
|
for (const node2 of graph.nodes ?? []) {
|
|
@@ -19366,16 +20407,16 @@ async function parseGraphifyEntities(projectRoot) {
|
|
|
19366
20407
|
}
|
|
19367
20408
|
}
|
|
19368
20409
|
async function scanSrcComponents(projectRoot) {
|
|
19369
|
-
const { readdir:
|
|
20410
|
+
const { readdir: readdir6 } = await import("node:fs/promises");
|
|
19370
20411
|
const entities = [];
|
|
19371
|
-
const srcDir =
|
|
20412
|
+
const srcDir = join14(projectRoot, "src");
|
|
19372
20413
|
async function walk(dir, prefix) {
|
|
19373
20414
|
try {
|
|
19374
|
-
const entries = await
|
|
20415
|
+
const entries = await readdir6(dir, { withFileTypes: true });
|
|
19375
20416
|
for (const entry of entries) {
|
|
19376
20417
|
if (entry.name.startsWith("."))
|
|
19377
20418
|
continue;
|
|
19378
|
-
const full =
|
|
20419
|
+
const full = join14(dir, entry.name);
|
|
19379
20420
|
if (entry.isDirectory()) {
|
|
19380
20421
|
if (entry.name === "node_modules")
|
|
19381
20422
|
continue;
|
|
@@ -19400,8 +20441,8 @@ async function scanSrcComponents(projectRoot) {
|
|
|
19400
20441
|
var init_source_parsers = () => {};
|
|
19401
20442
|
|
|
19402
20443
|
// src/core/memory/episodic-store.ts
|
|
19403
|
-
import { appendFile, mkdir as mkdir10, readFile as
|
|
19404
|
-
import { resolve as
|
|
20444
|
+
import { appendFile, mkdir as mkdir10, readFile as readFile18 } from "node:fs/promises";
|
|
20445
|
+
import { resolve as resolve18 } from "node:path";
|
|
19405
20446
|
async function appendEvent(projectRoot, event) {
|
|
19406
20447
|
try {
|
|
19407
20448
|
const full = ProductEventSchema.parse({
|
|
@@ -19409,7 +20450,7 @@ async function appendEvent(projectRoot, event) {
|
|
|
19409
20450
|
id: event.id ?? `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
|
|
19410
20451
|
});
|
|
19411
20452
|
const path = eventsPath(projectRoot);
|
|
19412
|
-
await mkdir10(
|
|
20453
|
+
await mkdir10(resolve18(projectRoot, ".codeconductor"), { recursive: true });
|
|
19413
20454
|
await appendFile(path, JSON.stringify(full) + `
|
|
19414
20455
|
`, "utf-8");
|
|
19415
20456
|
return ok(full);
|
|
@@ -19419,7 +20460,7 @@ async function appendEvent(projectRoot, event) {
|
|
|
19419
20460
|
}
|
|
19420
20461
|
async function listEvents(projectRoot, since, type) {
|
|
19421
20462
|
try {
|
|
19422
|
-
const content = await
|
|
20463
|
+
const content = await readFile18(eventsPath(projectRoot), "utf-8");
|
|
19423
20464
|
const events = [];
|
|
19424
20465
|
for (const line of content.split(`
|
|
19425
20466
|
`)) {
|
|
@@ -19447,9 +20488,9 @@ var init_episodic_store = __esm(() => {
|
|
|
19447
20488
|
|
|
19448
20489
|
// src/core/knowledge/ingest-pipeline.ts
|
|
19449
20490
|
import { createHash as createHash2 } from "node:crypto";
|
|
19450
|
-
import { readFile as
|
|
19451
|
-
import { join as
|
|
19452
|
-
import { mkdir as mkdir11, writeFile as
|
|
20491
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
20492
|
+
import { join as join15 } from "node:path";
|
|
20493
|
+
import { mkdir as mkdir11, writeFile as writeFile10 } from "node:fs/promises";
|
|
19453
20494
|
async function mapLimit(items, limit, fn) {
|
|
19454
20495
|
if (items.length === 0)
|
|
19455
20496
|
return [];
|
|
@@ -19469,22 +20510,22 @@ async function mapLimit(items, limit, fn) {
|
|
|
19469
20510
|
}
|
|
19470
20511
|
async function hashFile(path) {
|
|
19471
20512
|
try {
|
|
19472
|
-
const content = await
|
|
20513
|
+
const content = await readFile19(path, "utf-8");
|
|
19473
20514
|
return createHash2("sha256").update(content).digest("hex").slice(0, 16);
|
|
19474
20515
|
} catch {
|
|
19475
20516
|
return null;
|
|
19476
20517
|
}
|
|
19477
20518
|
}
|
|
19478
20519
|
async function collectDeferRisks(projectRoot) {
|
|
19479
|
-
const { readdir:
|
|
20520
|
+
const { readdir: readdir6 } = await import("node:fs/promises");
|
|
19480
20521
|
const files = [];
|
|
19481
20522
|
async function walk(dir) {
|
|
19482
20523
|
try {
|
|
19483
|
-
const entries = await
|
|
20524
|
+
const entries = await readdir6(dir, { withFileTypes: true });
|
|
19484
20525
|
for (const entry of entries) {
|
|
19485
20526
|
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
19486
20527
|
continue;
|
|
19487
|
-
const full =
|
|
20528
|
+
const full = join15(dir, entry.name);
|
|
19488
20529
|
if (entry.isDirectory()) {
|
|
19489
20530
|
await walk(full);
|
|
19490
20531
|
} else if (entry.name.endsWith(".ts")) {
|
|
@@ -19493,10 +20534,10 @@ async function collectDeferRisks(projectRoot) {
|
|
|
19493
20534
|
}
|
|
19494
20535
|
} catch {}
|
|
19495
20536
|
}
|
|
19496
|
-
await walk(
|
|
20537
|
+
await walk(join15(projectRoot, "src"));
|
|
19497
20538
|
const perFile = await mapLimit(files, WALK_READ_CONCURRENCY, async (full) => {
|
|
19498
20539
|
const entities = [];
|
|
19499
|
-
const content = await
|
|
20540
|
+
const content = await readFile19(full, "utf-8");
|
|
19500
20541
|
const rel = full.replace(projectRoot + "/", "");
|
|
19501
20542
|
const deferRe = new RegExp(DEFER_REGEX_SOURCE, "gm");
|
|
19502
20543
|
let match;
|
|
@@ -19555,13 +20596,13 @@ async function parseBacklogEntities(projectRoot) {
|
|
|
19555
20596
|
return entities;
|
|
19556
20597
|
}
|
|
19557
20598
|
async function parseAdrEntities(projectRoot) {
|
|
19558
|
-
const { readdir:
|
|
19559
|
-
const adrDir =
|
|
20599
|
+
const { readdir: readdir6 } = await import("node:fs/promises");
|
|
20600
|
+
const adrDir = join15(projectRoot, "docs", "adr");
|
|
19560
20601
|
const entities = [];
|
|
19561
20602
|
try {
|
|
19562
|
-
const files = (await
|
|
20603
|
+
const files = (await readdir6(adrDir)).filter((file) => file.endsWith(".md"));
|
|
19563
20604
|
const parsed = await Promise.all(files.map(async (file) => {
|
|
19564
|
-
const adr = await parseAdrFile(
|
|
20605
|
+
const adr = await parseAdrFile(join15(adrDir, file));
|
|
19565
20606
|
return adr ? adrToEntities(adr, `docs/adr/${file}`) : [];
|
|
19566
20607
|
}));
|
|
19567
20608
|
entities.push(...parsed.flat());
|
|
@@ -19653,7 +20694,7 @@ async function runIngest(projectRoot, productName) {
|
|
|
19653
20694
|
await saveGraph2(projectRoot, graph);
|
|
19654
20695
|
const sourceHashes = {};
|
|
19655
20696
|
for (const src of ["README.md", "BACKLOG.md", "ROADMAP.md"]) {
|
|
19656
|
-
const h = await hashFile(
|
|
20697
|
+
const h = await hashFile(join15(projectRoot, src));
|
|
19657
20698
|
if (h)
|
|
19658
20699
|
sourceHashes[src] = h;
|
|
19659
20700
|
}
|
|
@@ -19663,8 +20704,8 @@ async function runIngest(projectRoot, productName) {
|
|
|
19663
20704
|
lastIngestAt: new Date().toISOString(),
|
|
19664
20705
|
sourceHashes
|
|
19665
20706
|
};
|
|
19666
|
-
await mkdir11(
|
|
19667
|
-
await
|
|
20707
|
+
await mkdir11(join15(projectRoot, ".codeconductor"), { recursive: true });
|
|
20708
|
+
await writeFile10(productMetaPath(projectRoot), JSON.stringify(ProductMetaSchema.parse(meta), null, 2), "utf-8");
|
|
19668
20709
|
await appendEvent(projectRoot, {
|
|
19669
20710
|
type: "ingest.completed",
|
|
19670
20711
|
timestamp: new Date().toISOString(),
|
|
@@ -19745,11 +20786,11 @@ var init_ingest_command = __esm(() => {
|
|
|
19745
20786
|
});
|
|
19746
20787
|
|
|
19747
20788
|
// src/core/memory/operational-state.ts
|
|
19748
|
-
import { mkdir as mkdir12, readFile as
|
|
19749
|
-
import { resolve as
|
|
20789
|
+
import { mkdir as mkdir12, readFile as readFile20, writeFile as writeFile11 } from "node:fs/promises";
|
|
20790
|
+
import { resolve as resolve19 } from "node:path";
|
|
19750
20791
|
async function loadOperationalState(projectRoot) {
|
|
19751
20792
|
try {
|
|
19752
|
-
const raw = await
|
|
20793
|
+
const raw = await readFile20(operationalStatePath(projectRoot), "utf-8");
|
|
19753
20794
|
return ok(OperationalStateSchema.parse(JSON.parse(raw)));
|
|
19754
20795
|
} catch (e) {
|
|
19755
20796
|
if (e.code === "ENOENT") {
|
|
@@ -19771,8 +20812,8 @@ async function saveOperationalState(projectRoot, state) {
|
|
|
19771
20812
|
updatedAt: new Date().toISOString()
|
|
19772
20813
|
});
|
|
19773
20814
|
const path = operationalStatePath(projectRoot);
|
|
19774
|
-
await mkdir12(
|
|
19775
|
-
await
|
|
20815
|
+
await mkdir12(resolve19(projectRoot, ".codeconductor"), { recursive: true });
|
|
20816
|
+
await writeFile11(path, JSON.stringify(validated, null, 2), "utf-8");
|
|
19776
20817
|
return ok(undefined);
|
|
19777
20818
|
} catch (e) {
|
|
19778
20819
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -19806,11 +20847,11 @@ var init_operational_state = __esm(() => {
|
|
|
19806
20847
|
});
|
|
19807
20848
|
|
|
19808
20849
|
// src/core/memory/strategic-memory.ts
|
|
19809
|
-
import { mkdir as mkdir13, readFile as
|
|
19810
|
-
import { resolve as
|
|
20850
|
+
import { mkdir as mkdir13, readFile as readFile21, writeFile as writeFile12 } from "node:fs/promises";
|
|
20851
|
+
import { resolve as resolve20 } from "node:path";
|
|
19811
20852
|
async function loadStrategicMemory(projectRoot) {
|
|
19812
20853
|
try {
|
|
19813
|
-
const raw = await
|
|
20854
|
+
const raw = await readFile21(strategicPath(projectRoot), "utf-8");
|
|
19814
20855
|
return ok(StrategicMemorySchema.parse(JSON.parse(raw)));
|
|
19815
20856
|
} catch (e) {
|
|
19816
20857
|
if (e.code === "ENOENT") {
|
|
@@ -19831,8 +20872,8 @@ async function saveStrategicMemory(projectRoot, memory) {
|
|
|
19831
20872
|
updatedAt: new Date().toISOString()
|
|
19832
20873
|
});
|
|
19833
20874
|
const path = strategicPath(projectRoot);
|
|
19834
|
-
await mkdir13(
|
|
19835
|
-
await
|
|
20875
|
+
await mkdir13(resolve20(projectRoot, ".codeconductor"), { recursive: true });
|
|
20876
|
+
await writeFile12(path, JSON.stringify(validated, null, 2), "utf-8");
|
|
19836
20877
|
return ok(undefined);
|
|
19837
20878
|
} catch (e) {
|
|
19838
20879
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -19844,8 +20885,8 @@ var init_strategic_memory = __esm(() => {
|
|
|
19844
20885
|
});
|
|
19845
20886
|
|
|
19846
20887
|
// src/core/memory/memory-index.ts
|
|
19847
|
-
import { mkdir as mkdir14, readFile as
|
|
19848
|
-
import { resolve as
|
|
20888
|
+
import { mkdir as mkdir14, readFile as readFile22, writeFile as writeFile13 } from "node:fs/promises";
|
|
20889
|
+
import { resolve as resolve21 } from "node:path";
|
|
19849
20890
|
function parseMarkdown(content) {
|
|
19850
20891
|
const startIdx = content.indexOf(SENTINEL_START);
|
|
19851
20892
|
const endIdx = content.indexOf(SENTINEL_END);
|
|
@@ -19864,8 +20905,8 @@ function parseMarkdown(content) {
|
|
|
19864
20905
|
}
|
|
19865
20906
|
async function loadMemoryIndex(projectRoot) {
|
|
19866
20907
|
try {
|
|
19867
|
-
const filePath =
|
|
19868
|
-
const content = await
|
|
20908
|
+
const filePath = resolve21(projectRoot, MEMORY_FILE);
|
|
20909
|
+
const content = await readFile22(filePath, "utf-8");
|
|
19869
20910
|
const parsed = parseMarkdown(content);
|
|
19870
20911
|
if (!parsed) {
|
|
19871
20912
|
return err(new Error("Failed to parse memory index from memory.md"));
|
|
@@ -19882,28 +20923,28 @@ var init_memory_index = __esm(() => {
|
|
|
19882
20923
|
});
|
|
19883
20924
|
|
|
19884
20925
|
// src/core/evaluation/outcome-store.ts
|
|
19885
|
-
import { appendFile as appendFile2, mkdir as mkdir15, readFile as
|
|
19886
|
-
import { resolve as
|
|
20926
|
+
import { appendFile as appendFile2, mkdir as mkdir15, readFile as readFile23, readdir as readdir6, writeFile as writeFile14 } from "node:fs/promises";
|
|
20927
|
+
import { resolve as resolve22 } from "node:path";
|
|
19887
20928
|
async function ensureEvaluationDir(projectRoot) {
|
|
19888
|
-
const dir =
|
|
20929
|
+
const dir = resolve22(projectRoot, EVAL_DIR);
|
|
19889
20930
|
await mkdir15(dir, { recursive: true });
|
|
19890
|
-
await mkdir15(
|
|
20931
|
+
await mkdir15(resolve22(dir, SCORECARDS_DIR), { recursive: true });
|
|
19891
20932
|
return dir;
|
|
19892
20933
|
}
|
|
19893
20934
|
async function appendOutcome(projectRoot, outcome) {
|
|
19894
20935
|
try {
|
|
19895
20936
|
const dir = await ensureEvaluationDir(projectRoot);
|
|
19896
20937
|
const validated = TaskOutcomeSchema.parse(outcome);
|
|
19897
|
-
await appendFile2(
|
|
20938
|
+
await appendFile2(resolve22(dir, OUTCOMES_FILE), JSON.stringify(validated) + `
|
|
19898
20939
|
`, "utf-8");
|
|
19899
|
-
const indexPath =
|
|
20940
|
+
const indexPath = resolve22(dir, INDEX_FILE);
|
|
19900
20941
|
let index = { version: 1, lastOutcomeId: validated.id };
|
|
19901
20942
|
try {
|
|
19902
|
-
const raw = await
|
|
20943
|
+
const raw = await readFile23(indexPath, "utf-8");
|
|
19903
20944
|
index = EvaluationIndexSchema.parse(JSON.parse(raw));
|
|
19904
20945
|
index.lastOutcomeId = validated.id;
|
|
19905
20946
|
} catch {}
|
|
19906
|
-
await
|
|
20947
|
+
await writeFile14(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
19907
20948
|
return ok(undefined);
|
|
19908
20949
|
} catch (e) {
|
|
19909
20950
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -19911,8 +20952,8 @@ async function appendOutcome(projectRoot, outcome) {
|
|
|
19911
20952
|
}
|
|
19912
20953
|
async function listOutcomes(projectRoot, filter = {}) {
|
|
19913
20954
|
try {
|
|
19914
|
-
const path =
|
|
19915
|
-
const content = await
|
|
20955
|
+
const path = resolve22(projectRoot, EVAL_DIR, OUTCOMES_FILE);
|
|
20956
|
+
const content = await readFile23(path, "utf-8");
|
|
19916
20957
|
const lines = content.split(`
|
|
19917
20958
|
`).filter((l) => l.trim().length > 0);
|
|
19918
20959
|
const outcomes = [];
|
|
@@ -19950,8 +20991,8 @@ async function saveScorecard(projectRoot, record) {
|
|
|
19950
20991
|
try {
|
|
19951
20992
|
const dir = await ensureEvaluationDir(projectRoot);
|
|
19952
20993
|
const validated = ScorecardRecordSchema.parse(record);
|
|
19953
|
-
const filePath =
|
|
19954
|
-
await
|
|
20994
|
+
const filePath = resolve22(dir, SCORECARDS_DIR, `${validated.id}.json`);
|
|
20995
|
+
await writeFile14(filePath, JSON.stringify(validated, null, 2), "utf-8");
|
|
19955
20996
|
return ok(filePath);
|
|
19956
20997
|
} catch (e) {
|
|
19957
20998
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -19959,10 +21000,10 @@ async function saveScorecard(projectRoot, record) {
|
|
|
19959
21000
|
}
|
|
19960
21001
|
async function listScorecards(projectRoot, filter = {}) {
|
|
19961
21002
|
try {
|
|
19962
|
-
const dir =
|
|
21003
|
+
const dir = resolve22(projectRoot, EVAL_DIR, SCORECARDS_DIR);
|
|
19963
21004
|
let files;
|
|
19964
21005
|
try {
|
|
19965
|
-
files = await
|
|
21006
|
+
files = await readdir6(dir);
|
|
19966
21007
|
} catch (e) {
|
|
19967
21008
|
if (e.code === "ENOENT")
|
|
19968
21009
|
return ok([]);
|
|
@@ -19972,7 +21013,7 @@ async function listScorecards(projectRoot, filter = {}) {
|
|
|
19972
21013
|
for (const file of files) {
|
|
19973
21014
|
if (!file.endsWith(".json"))
|
|
19974
21015
|
continue;
|
|
19975
|
-
const parsed = ScorecardRecordSchema.parse(JSON.parse(await
|
|
21016
|
+
const parsed = ScorecardRecordSchema.parse(JSON.parse(await readFile23(resolve22(dir, file), "utf-8")));
|
|
19976
21017
|
if (filter.backlogId && parsed.backlogId !== filter.backlogId)
|
|
19977
21018
|
continue;
|
|
19978
21019
|
if (filter.verdict && parsed.verdict !== filter.verdict)
|
|
@@ -19991,8 +21032,8 @@ async function hasPassingScorecard(projectRoot, backlogId) {
|
|
|
19991
21032
|
}
|
|
19992
21033
|
async function loadScorecard(projectRoot, id) {
|
|
19993
21034
|
try {
|
|
19994
|
-
const filePath =
|
|
19995
|
-
const content = await
|
|
21035
|
+
const filePath = resolve22(projectRoot, EVAL_DIR, SCORECARDS_DIR, `${id}.json`);
|
|
21036
|
+
const content = await readFile23(filePath, "utf-8");
|
|
19996
21037
|
return ok(ScorecardRecordSchema.parse(JSON.parse(content)));
|
|
19997
21038
|
} catch (e) {
|
|
19998
21039
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -20083,11 +21124,11 @@ var init_outcome_store = __esm(() => {
|
|
|
20083
21124
|
});
|
|
20084
21125
|
|
|
20085
21126
|
// src/core/feedback/feedback-ingestor.ts
|
|
20086
|
-
import { readFile as
|
|
20087
|
-
import { join as
|
|
21127
|
+
import { readFile as readFile24 } from "node:fs/promises";
|
|
21128
|
+
import { join as join16 } from "node:path";
|
|
20088
21129
|
async function parseChangelogLearnings(projectRoot) {
|
|
20089
21130
|
try {
|
|
20090
|
-
const content = await
|
|
21131
|
+
const content = await readFile24(join16(projectRoot, "CHANGELOG.md"), "utf-8");
|
|
20091
21132
|
const unreleased = content.match(/## \[Unreleased\]([\s\S]*?)(?=## \[|\n## )/i);
|
|
20092
21133
|
if (!unreleased)
|
|
20093
21134
|
return [];
|
|
@@ -20207,7 +21248,7 @@ var exports_product_command = {};
|
|
|
20207
21248
|
__export(exports_product_command, {
|
|
20208
21249
|
productCommand: () => productCommand
|
|
20209
21250
|
});
|
|
20210
|
-
import { writeFile as
|
|
21251
|
+
import { writeFile as writeFile15 } from "node:fs/promises";
|
|
20211
21252
|
async function productCommand(options) {
|
|
20212
21253
|
const { subcommand, projectRoot, output, query, from, to, since, format } = options;
|
|
20213
21254
|
try {
|
|
@@ -20410,7 +21451,7 @@ async function handleExport(projectRoot, format, output) {
|
|
|
20410
21451
|
...queryNodes(graph.data, "risk").map((n) => `- ${n.name}`)
|
|
20411
21452
|
].join(`
|
|
20412
21453
|
`);
|
|
20413
|
-
await
|
|
21454
|
+
await writeFile15(productReportPath(projectRoot), md, "utf-8");
|
|
20414
21455
|
return {
|
|
20415
21456
|
code: 0,
|
|
20416
21457
|
data: {
|
|
@@ -20613,8 +21654,8 @@ async function runCompileCheck(options) {
|
|
|
20613
21654
|
})();
|
|
20614
21655
|
collectOutput.catch(() => {});
|
|
20615
21656
|
let timeoutId;
|
|
20616
|
-
const timeout = new Promise((
|
|
20617
|
-
timeoutId = setTimeout(() =>
|
|
21657
|
+
const timeout = new Promise((resolve23) => {
|
|
21658
|
+
timeoutId = setTimeout(() => resolve23("timeout"), timeoutMs);
|
|
20618
21659
|
});
|
|
20619
21660
|
try {
|
|
20620
21661
|
const outcome = await Promise.race([collectOutput, timeout]);
|
|
@@ -20684,9 +21725,9 @@ var init_compile_checker = __esm(() => {
|
|
|
20684
21725
|
|
|
20685
21726
|
// src/core/verification/verification-runner.ts
|
|
20686
21727
|
import { existsSync as existsSync3 } from "node:fs";
|
|
20687
|
-
import { readFile as
|
|
20688
|
-
import { dirname as
|
|
20689
|
-
import { mkdir as mkdir16, readdir as
|
|
21728
|
+
import { readFile as readFile25 } from "node:fs/promises";
|
|
21729
|
+
import { dirname as dirname8, join as join17, resolve as resolve23 } from "node:path";
|
|
21730
|
+
import { mkdir as mkdir16, readdir as readdir7, writeFile as writeFile16 } from "node:fs/promises";
|
|
20690
21731
|
function isPassingEvidence(ev) {
|
|
20691
21732
|
switch (ev.type) {
|
|
20692
21733
|
case "verification":
|
|
@@ -20704,8 +21745,8 @@ function isPassingEvidence(ev) {
|
|
|
20704
21745
|
}
|
|
20705
21746
|
}
|
|
20706
21747
|
function evidenceFilePath(evDir, id) {
|
|
20707
|
-
const path =
|
|
20708
|
-
if (
|
|
21748
|
+
const path = resolve23(evDir, `${id.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
|
|
21749
|
+
if (dirname8(path) !== resolve23(evDir)) {
|
|
20709
21750
|
return err(new Error(`Refusing to write evidence for "${id}" outside ${evDir}`));
|
|
20710
21751
|
}
|
|
20711
21752
|
return ok(path);
|
|
@@ -20717,7 +21758,7 @@ async function persistEvidence(projectRoot, evidence) {
|
|
|
20717
21758
|
return evidencePath;
|
|
20718
21759
|
try {
|
|
20719
21760
|
await mkdir16(evDir, { recursive: true });
|
|
20720
|
-
await
|
|
21761
|
+
await writeFile16(evidencePath.data, JSON.stringify(evidence, null, 2), "utf-8");
|
|
20721
21762
|
} catch (e) {
|
|
20722
21763
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
20723
21764
|
}
|
|
@@ -20731,7 +21772,7 @@ async function collectTaskEvidence(projectRoot, taskId) {
|
|
|
20731
21772
|
return ok({ records, invalid });
|
|
20732
21773
|
let files;
|
|
20733
21774
|
try {
|
|
20734
|
-
files = await
|
|
21775
|
+
files = await readdir7(evDir);
|
|
20735
21776
|
} catch (e) {
|
|
20736
21777
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
20737
21778
|
}
|
|
@@ -20739,7 +21780,7 @@ async function collectTaskEvidence(projectRoot, taskId) {
|
|
|
20739
21780
|
if (!file.endsWith(".json"))
|
|
20740
21781
|
continue;
|
|
20741
21782
|
try {
|
|
20742
|
-
const raw = await
|
|
21783
|
+
const raw = await readFile25(join17(evDir, file), "utf-8");
|
|
20743
21784
|
const ev = EvidenceSchema.parse(JSON.parse(raw));
|
|
20744
21785
|
if (ev.relatedTask === taskId)
|
|
20745
21786
|
records.push(ev);
|
|
@@ -22290,9 +23331,9 @@ var init_output_validator = __esm(() => {
|
|
|
22290
23331
|
|
|
22291
23332
|
// src/core/ccep/command-parser.ts
|
|
22292
23333
|
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
|
|
22293
|
-
import { join as
|
|
23334
|
+
import { join as join18 } from "node:path";
|
|
22294
23335
|
function readProjectId(projectRoot) {
|
|
22295
|
-
const packageJsonPath =
|
|
23336
|
+
const packageJsonPath = join18(projectRoot, "package.json");
|
|
22296
23337
|
if (existsSync4(packageJsonPath)) {
|
|
22297
23338
|
try {
|
|
22298
23339
|
const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
@@ -22322,7 +23363,7 @@ function parseCommand(command, userRequest, projectRoot) {
|
|
|
22322
23363
|
maxVariance: "low"
|
|
22323
23364
|
}
|
|
22324
23365
|
};
|
|
22325
|
-
const packageJsonPath =
|
|
23366
|
+
const packageJsonPath = join18(projectRoot, "package.json");
|
|
22326
23367
|
if (existsSync4(packageJsonPath)) {
|
|
22327
23368
|
try {
|
|
22328
23369
|
const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
@@ -22396,8 +23437,8 @@ var init_workflow_profile_loader = __esm(() => {
|
|
|
22396
23437
|
// src/core/evaluation/harness-catalog.ts
|
|
22397
23438
|
import { createHash as createHash3 } from "node:crypto";
|
|
22398
23439
|
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
22399
|
-
import { copyFile as copyFile2, mkdir as mkdir17, readFile as
|
|
22400
|
-
import { dirname as
|
|
23440
|
+
import { copyFile as copyFile2, mkdir as mkdir17, readFile as readFile26, readdir as readdir8, rm as rm3, writeFile as writeFile17 } from "node:fs/promises";
|
|
23441
|
+
import { dirname as dirname9, join as join19, resolve as resolve24 } from "node:path";
|
|
22401
23442
|
function catalogIds(catalog = DEFAULT_HARNESS_CATALOG) {
|
|
22402
23443
|
return catalog.components.map((c) => c.id);
|
|
22403
23444
|
}
|
|
@@ -22450,20 +23491,20 @@ function harnessFingerprint(disabled, contractVersion, ccepProfile = "feature",
|
|
|
22450
23491
|
return createHash3("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
22451
23492
|
}
|
|
22452
23493
|
async function loadHarnessCatalog(projectRoot) {
|
|
22453
|
-
const overridePath =
|
|
23494
|
+
const overridePath = resolve24(projectRoot, EVAL_DIR2, CATALOG_FILE);
|
|
22454
23495
|
try {
|
|
22455
|
-
const raw = await
|
|
23496
|
+
const raw = await readFile26(overridePath, "utf-8");
|
|
22456
23497
|
return HarnessCatalogSchema.parse($parse(raw));
|
|
22457
23498
|
} catch {
|
|
22458
23499
|
return DEFAULT_HARNESS_CATALOG;
|
|
22459
23500
|
}
|
|
22460
23501
|
}
|
|
22461
23502
|
function activeOverlayPath(projectRoot) {
|
|
22462
|
-
return
|
|
23503
|
+
return resolve24(projectRoot, EVAL_DIR2, ACTIVE_OVERLAY_FILE);
|
|
22463
23504
|
}
|
|
22464
23505
|
async function readActiveOverlay(projectRoot) {
|
|
22465
23506
|
try {
|
|
22466
|
-
const raw = await
|
|
23507
|
+
const raw = await readFile26(activeOverlayPath(projectRoot), "utf-8");
|
|
22467
23508
|
return HarnessOverlaySchema.parse($parse(raw));
|
|
22468
23509
|
} catch {
|
|
22469
23510
|
return null;
|
|
@@ -22517,55 +23558,55 @@ function applyCatalogToProfile(profile, disabled) {
|
|
|
22517
23558
|
return next;
|
|
22518
23559
|
}
|
|
22519
23560
|
async function restoreOverlayBackup(projectRoot) {
|
|
22520
|
-
const backupRoot =
|
|
23561
|
+
const backupRoot = resolve24(projectRoot, EVAL_DIR2, OVERLAY_BACKUP_DIR);
|
|
22521
23562
|
if (!existsSync5(backupRoot))
|
|
22522
23563
|
return;
|
|
22523
|
-
const configBackup =
|
|
22524
|
-
const configDest =
|
|
23564
|
+
const configBackup = join19(backupRoot, "config.yml");
|
|
23565
|
+
const configDest = resolve24(projectRoot, ".codeconductor", "config.yml");
|
|
22525
23566
|
if (existsSync5(configBackup)) {
|
|
22526
|
-
await mkdir17(
|
|
23567
|
+
await mkdir17(dirname9(configDest), { recursive: true });
|
|
22527
23568
|
await copyFile2(configBackup, configDest);
|
|
22528
23569
|
}
|
|
22529
|
-
const workflowsBackup =
|
|
22530
|
-
const workflowsDest =
|
|
23570
|
+
const workflowsBackup = join19(backupRoot, "workflows");
|
|
23571
|
+
const workflowsDest = resolve24(projectRoot, ".codeconductor", "workflows");
|
|
22531
23572
|
if (existsSync5(workflowsBackup)) {
|
|
22532
23573
|
await mkdir17(workflowsDest, { recursive: true });
|
|
22533
|
-
const files = await
|
|
23574
|
+
const files = await readdir8(workflowsBackup);
|
|
22534
23575
|
for (const file of files) {
|
|
22535
|
-
await copyFile2(
|
|
23576
|
+
await copyFile2(join19(workflowsBackup, file), join19(workflowsDest, file));
|
|
22536
23577
|
}
|
|
22537
23578
|
}
|
|
22538
|
-
const overlayBackup =
|
|
23579
|
+
const overlayBackup = join19(backupRoot, ACTIVE_OVERLAY_FILE);
|
|
22539
23580
|
const overlayDest = activeOverlayPath(projectRoot);
|
|
22540
23581
|
if (existsSync5(overlayBackup)) {
|
|
22541
23582
|
await copyFile2(overlayBackup, overlayDest);
|
|
22542
23583
|
} else if (existsSync5(overlayDest)) {
|
|
22543
|
-
await
|
|
23584
|
+
await rm3(overlayDest, { force: true });
|
|
22544
23585
|
}
|
|
22545
23586
|
}
|
|
22546
23587
|
async function snapshotForBackup(projectRoot) {
|
|
22547
|
-
const backupRoot =
|
|
23588
|
+
const backupRoot = resolve24(projectRoot, EVAL_DIR2, OVERLAY_BACKUP_DIR);
|
|
22548
23589
|
if (existsSync5(backupRoot))
|
|
22549
23590
|
return;
|
|
22550
23591
|
await mkdir17(backupRoot, { recursive: true });
|
|
22551
|
-
const configPath =
|
|
23592
|
+
const configPath = resolve24(projectRoot, ".codeconductor", "config.yml");
|
|
22552
23593
|
if (existsSync5(configPath)) {
|
|
22553
|
-
await copyFile2(configPath,
|
|
23594
|
+
await copyFile2(configPath, join19(backupRoot, "config.yml"));
|
|
22554
23595
|
}
|
|
22555
|
-
const workflowsDir =
|
|
23596
|
+
const workflowsDir = resolve24(projectRoot, ".codeconductor", "workflows");
|
|
22556
23597
|
if (existsSync5(workflowsDir)) {
|
|
22557
|
-
const dest =
|
|
23598
|
+
const dest = join19(backupRoot, "workflows");
|
|
22558
23599
|
await mkdir17(dest, { recursive: true });
|
|
22559
|
-
const files = await
|
|
23600
|
+
const files = await readdir8(workflowsDir);
|
|
22560
23601
|
for (const file of files) {
|
|
22561
23602
|
if (file.endsWith(".yml")) {
|
|
22562
|
-
await copyFile2(
|
|
23603
|
+
await copyFile2(join19(workflowsDir, file), join19(dest, file));
|
|
22563
23604
|
}
|
|
22564
23605
|
}
|
|
22565
23606
|
}
|
|
22566
23607
|
const overlay = activeOverlayPath(projectRoot);
|
|
22567
23608
|
if (existsSync5(overlay)) {
|
|
22568
|
-
await copyFile2(overlay,
|
|
23609
|
+
await copyFile2(overlay, join19(backupRoot, ACTIVE_OVERLAY_FILE));
|
|
22569
23610
|
}
|
|
22570
23611
|
}
|
|
22571
23612
|
async function applyHarnessOverlay(projectRoot, disabled, options = {}) {
|
|
@@ -22574,13 +23615,13 @@ async function applyHarnessOverlay(projectRoot, disabled, options = {}) {
|
|
|
22574
23615
|
await restoreOverlayBackup(projectRoot);
|
|
22575
23616
|
await snapshotForBackup(projectRoot);
|
|
22576
23617
|
}
|
|
22577
|
-
const workflowsDir =
|
|
23618
|
+
const workflowsDir = resolve24(projectRoot, ".codeconductor", "workflows");
|
|
22578
23619
|
await mkdir17(workflowsDir, { recursive: true });
|
|
22579
|
-
await mkdir17(
|
|
23620
|
+
await mkdir17(resolve24(projectRoot, EVAL_DIR2), { recursive: true });
|
|
22580
23621
|
for (const command of WORKFLOW_OVERLAY_COMMANDS) {
|
|
22581
23622
|
const base = loadWorkflowProfile(command);
|
|
22582
23623
|
const next = applyCatalogToProfile(base, disabled);
|
|
22583
|
-
await
|
|
23624
|
+
await writeFile17(join19(workflowsDir, `${command}.yml`), $stringify(next), "utf-8");
|
|
22584
23625
|
}
|
|
22585
23626
|
const needsConfig = disabled.includes("compile_loop") || disabled.includes("council");
|
|
22586
23627
|
if (needsConfig) {
|
|
@@ -22608,7 +23649,7 @@ async function applyHarnessOverlay(projectRoot, disabled, options = {}) {
|
|
|
22608
23649
|
contractVersion: options.contractVersion,
|
|
22609
23650
|
ccepProfile: options.ccepProfile ?? "feature"
|
|
22610
23651
|
});
|
|
22611
|
-
await
|
|
23652
|
+
await writeFile17(activeOverlayPath(projectRoot), $stringify(overlay), "utf-8");
|
|
22612
23653
|
return ok(overlay);
|
|
22613
23654
|
} catch (e) {
|
|
22614
23655
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -22720,8 +23761,8 @@ var init_harness_catalog = __esm(() => {
|
|
|
22720
23761
|
|
|
22721
23762
|
// src/core/ccep/context-resolver.ts
|
|
22722
23763
|
import { existsSync as existsSync6 } from "node:fs";
|
|
22723
|
-
import { readFile as
|
|
22724
|
-
import { join as
|
|
23764
|
+
import { readFile as readFile27 } from "node:fs/promises";
|
|
23765
|
+
import { join as join20 } from "node:path";
|
|
22725
23766
|
async function loadProductKnowledge(projectRoot) {
|
|
22726
23767
|
if (isProductGraphDisabled(projectRoot)) {
|
|
22727
23768
|
return {};
|
|
@@ -22731,7 +23772,7 @@ async function loadProductKnowledge(projectRoot) {
|
|
|
22731
23772
|
return {};
|
|
22732
23773
|
}
|
|
22733
23774
|
try {
|
|
22734
|
-
const raw = await
|
|
23775
|
+
const raw = await readFile27(graphPath, "utf-8");
|
|
22735
23776
|
const graph = ProductGraphSchema.parse(JSON.parse(raw));
|
|
22736
23777
|
return {
|
|
22737
23778
|
productName: graph.productName,
|
|
@@ -22747,7 +23788,7 @@ async function loadProductKnowledge(projectRoot) {
|
|
|
22747
23788
|
}
|
|
22748
23789
|
async function resolveAstSource(projectRoot) {
|
|
22749
23790
|
if (isProductGraphDisabled(projectRoot)) {
|
|
22750
|
-
const graphifyPath2 =
|
|
23791
|
+
const graphifyPath2 = join20(projectRoot, "graphify-out", "graph.json");
|
|
22751
23792
|
if (existsSync6(graphifyPath2)) {
|
|
22752
23793
|
return { source: "graphify", confidence: "medium" };
|
|
22753
23794
|
}
|
|
@@ -22757,7 +23798,7 @@ async function resolveAstSource(projectRoot) {
|
|
|
22757
23798
|
if (existsSync6(graphPath)) {
|
|
22758
23799
|
return { source: "product-graph", confidence: "high" };
|
|
22759
23800
|
}
|
|
22760
|
-
const graphifyPath =
|
|
23801
|
+
const graphifyPath = join20(projectRoot, "graphify-out", "graph.json");
|
|
22761
23802
|
if (existsSync6(graphifyPath)) {
|
|
22762
23803
|
return { source: "graphify", confidence: "medium" };
|
|
22763
23804
|
}
|
|
@@ -23795,8 +24836,8 @@ var init_backlog_validator = __esm(() => {
|
|
|
23795
24836
|
|
|
23796
24837
|
// src/core/openspec/openspec-state.ts
|
|
23797
24838
|
import { createHash as createHash4 } from "node:crypto";
|
|
23798
|
-
import { mkdir as mkdir18, readFile as
|
|
23799
|
-
import { resolve as
|
|
24839
|
+
import { mkdir as mkdir18, readFile as readFile28, rename as rename2, writeFile as writeFile18 } from "node:fs/promises";
|
|
24840
|
+
import { resolve as resolve25 } from "node:path";
|
|
23800
24841
|
function canTransition(from, to) {
|
|
23801
24842
|
return ALLOWED_TRANSITIONS[from]?.includes(to) ?? false;
|
|
23802
24843
|
}
|
|
@@ -23817,13 +24858,13 @@ function applyBacklogTransition(content, itemId, from, to, progress) {
|
|
|
23817
24858
|
}
|
|
23818
24859
|
async function writeFileAtomic(path, content) {
|
|
23819
24860
|
const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
23820
|
-
await
|
|
24861
|
+
await writeFile18(tmp, content, "utf-8");
|
|
23821
24862
|
await rename2(tmp, path);
|
|
23822
24863
|
}
|
|
23823
24864
|
async function loadOpenspecState(projectRoot) {
|
|
23824
24865
|
try {
|
|
23825
|
-
const filePath =
|
|
23826
|
-
const content = await
|
|
24866
|
+
const filePath = resolve25(projectRoot, STATE_FILE);
|
|
24867
|
+
const content = await readFile28(filePath, "utf-8");
|
|
23827
24868
|
const data = JSON.parse(content);
|
|
23828
24869
|
return ok(OpenspecStateSchema.parse(data));
|
|
23829
24870
|
} catch (e) {
|
|
@@ -23840,10 +24881,10 @@ async function loadOpenspecState(projectRoot) {
|
|
|
23840
24881
|
}
|
|
23841
24882
|
async function writeOpenspecState(projectRoot, state) {
|
|
23842
24883
|
try {
|
|
23843
|
-
const dir =
|
|
24884
|
+
const dir = resolve25(projectRoot, ".codeconductor");
|
|
23844
24885
|
await mkdir18(dir, { recursive: true });
|
|
23845
24886
|
const validated = OpenspecStateSchema.parse(state);
|
|
23846
|
-
await writeFileAtomic(
|
|
24887
|
+
await writeFileAtomic(resolve25(dir, "openspec-state.json"), JSON.stringify(validated, null, 2));
|
|
23847
24888
|
return ok(undefined);
|
|
23848
24889
|
} catch (e) {
|
|
23849
24890
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -23948,8 +24989,8 @@ var init_openspec_state = __esm(() => {
|
|
|
23948
24989
|
|
|
23949
24990
|
// src/core/openspec/backlog-scanner.ts
|
|
23950
24991
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
23951
|
-
import { readFile as
|
|
23952
|
-
import { resolve as
|
|
24992
|
+
import { readFile as readFile29 } from "node:fs/promises";
|
|
24993
|
+
import { resolve as resolve26 } from "node:path";
|
|
23953
24994
|
function itemSnapshot(items) {
|
|
23954
24995
|
const snap = {};
|
|
23955
24996
|
for (const item of items) {
|
|
@@ -23959,8 +25000,8 @@ function itemSnapshot(items) {
|
|
|
23959
25000
|
}
|
|
23960
25001
|
async function scanBacklog(projectRoot, previousSnapshot = {}) {
|
|
23961
25002
|
try {
|
|
23962
|
-
const filePath =
|
|
23963
|
-
const content = await
|
|
25003
|
+
const filePath = resolve26(projectRoot, BACKLOG_FILENAME);
|
|
25004
|
+
const content = await readFile29(filePath, "utf-8");
|
|
23964
25005
|
const hash = hashContent(content);
|
|
23965
25006
|
let fileChanged = true;
|
|
23966
25007
|
try {
|
|
@@ -24197,8 +25238,8 @@ var init_backlog_planner = __esm(() => {
|
|
|
24197
25238
|
});
|
|
24198
25239
|
|
|
24199
25240
|
// src/core/openspec/openspec-generator.ts
|
|
24200
|
-
import { mkdir as mkdir19, rename as rename3, writeFile as
|
|
24201
|
-
import { basename as
|
|
25241
|
+
import { mkdir as mkdir19, rename as rename3, writeFile as writeFile19 } from "node:fs/promises";
|
|
25242
|
+
import { basename as basename5, resolve as resolve27 } from "node:path";
|
|
24202
25243
|
function pad3(n) {
|
|
24203
25244
|
return String(n).padStart(3, "0");
|
|
24204
25245
|
}
|
|
@@ -24274,8 +25315,8 @@ ${blocks.join(`
|
|
|
24274
25315
|
`;
|
|
24275
25316
|
}
|
|
24276
25317
|
async function writeTasksMarkdown(projectRoot, changePath, cards, options = {}) {
|
|
24277
|
-
await mkdir19(
|
|
24278
|
-
await
|
|
25318
|
+
await mkdir19(resolve27(projectRoot, changePath), { recursive: true });
|
|
25319
|
+
await writeFile19(resolve27(projectRoot, changePath, "tasks.md"), tasksContent(cards, options), "utf-8");
|
|
24279
25320
|
}
|
|
24280
25321
|
function tasksContent(cards, options = {}) {
|
|
24281
25322
|
const criteria = options.acceptanceCriteria ?? [];
|
|
@@ -24320,38 +25361,38 @@ function tasksContent(cards, options = {}) {
|
|
|
24320
25361
|
}
|
|
24321
25362
|
async function generateOpenspecChange(projectRoot, item, taskCards, options = {}) {
|
|
24322
25363
|
const slug = buildChangeSlug(item);
|
|
24323
|
-
const changeDir =
|
|
24324
|
-
await mkdir19(
|
|
25364
|
+
const changeDir = resolve27(projectRoot, "openspec", "changes", slug);
|
|
25365
|
+
await mkdir19(resolve27(changeDir, "specs"), { recursive: true });
|
|
24325
25366
|
const taskOpts = {
|
|
24326
25367
|
tddRequired: options.tddRequired,
|
|
24327
25368
|
acceptanceCriteria: options.acceptanceCriteria ?? item.acceptanceCriteria
|
|
24328
25369
|
};
|
|
24329
|
-
await
|
|
24330
|
-
await
|
|
24331
|
-
await
|
|
24332
|
-
await
|
|
25370
|
+
await writeFile19(resolve27(changeDir, "proposal.md"), proposalContent(item), "utf-8");
|
|
25371
|
+
await writeFile19(resolve27(changeDir, "design.md"), designContent(item), "utf-8");
|
|
25372
|
+
await writeFile19(resolve27(changeDir, "tasks.md"), tasksContent(taskCards, taskOpts), "utf-8");
|
|
25373
|
+
await writeFile19(resolve27(changeDir, "specs", "delta.md"), specDelta(item), "utf-8");
|
|
24333
25374
|
return `openspec/changes/${slug}`;
|
|
24334
25375
|
}
|
|
24335
25376
|
async function archiveChangeFolder(projectRoot, changePath) {
|
|
24336
|
-
const src =
|
|
24337
|
-
const slug =
|
|
24338
|
-
const destDir =
|
|
25377
|
+
const src = resolve27(projectRoot, changePath);
|
|
25378
|
+
const slug = basename5(changePath);
|
|
25379
|
+
const destDir = resolve27(projectRoot, "openspec", "changes", "archive");
|
|
24339
25380
|
await mkdir19(destDir, { recursive: true });
|
|
24340
|
-
const dest =
|
|
25381
|
+
const dest = resolve27(destDir, slug);
|
|
24341
25382
|
await rename3(src, dest);
|
|
24342
25383
|
return `openspec/changes/archive/${slug}`;
|
|
24343
25384
|
}
|
|
24344
25385
|
async function ensureOpenspecConfig(projectRoot) {
|
|
24345
|
-
const configPath =
|
|
25386
|
+
const configPath = resolve27(projectRoot, "openspec", "config.yaml");
|
|
24346
25387
|
try {
|
|
24347
25388
|
const { access: access7 } = await import("node:fs/promises");
|
|
24348
25389
|
await access7(configPath);
|
|
24349
25390
|
} catch {
|
|
24350
|
-
await mkdir19(
|
|
25391
|
+
await mkdir19(resolve27(projectRoot, "openspec"), { recursive: true });
|
|
24351
25392
|
const stub = `# OpenSpec project config (CodeConductor native compatible)
|
|
24352
25393
|
schema: spec-driven
|
|
24353
25394
|
`;
|
|
24354
|
-
await
|
|
25395
|
+
await writeFile19(configPath, stub, "utf-8");
|
|
24355
25396
|
}
|
|
24356
25397
|
}
|
|
24357
25398
|
var init_openspec_generator = __esm(() => {
|
|
@@ -24359,8 +25400,8 @@ var init_openspec_generator = __esm(() => {
|
|
|
24359
25400
|
});
|
|
24360
25401
|
|
|
24361
25402
|
// src/core/openspec/spec-quality.ts
|
|
24362
|
-
import { readdir as
|
|
24363
|
-
import { join as
|
|
25403
|
+
import { readdir as readdir9, readFile as readFile30 } from "node:fs/promises";
|
|
25404
|
+
import { join as join21, relative as relative5, resolve as resolve28 } from "node:path";
|
|
24364
25405
|
function uniqueIds(matches) {
|
|
24365
25406
|
return [...new Set(matches ?? [])];
|
|
24366
25407
|
}
|
|
@@ -24477,12 +25518,12 @@ async function walkMarkdown(dir) {
|
|
|
24477
25518
|
const out = [];
|
|
24478
25519
|
let entries;
|
|
24479
25520
|
try {
|
|
24480
|
-
entries = await
|
|
25521
|
+
entries = await readdir9(dir, { withFileTypes: true });
|
|
24481
25522
|
} catch {
|
|
24482
25523
|
return out;
|
|
24483
25524
|
}
|
|
24484
25525
|
for (const entry of entries) {
|
|
24485
|
-
const full =
|
|
25526
|
+
const full = join21(dir, entry.name);
|
|
24486
25527
|
if (entry.isDirectory()) {
|
|
24487
25528
|
out.push(...await walkMarkdown(full));
|
|
24488
25529
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -24492,8 +25533,8 @@ async function walkMarkdown(dir) {
|
|
|
24492
25533
|
return out;
|
|
24493
25534
|
}
|
|
24494
25535
|
async function assessChangeFolder(projectRoot, changePath) {
|
|
24495
|
-
const root =
|
|
24496
|
-
const changeRoot =
|
|
25536
|
+
const root = resolve28(projectRoot);
|
|
25537
|
+
const changeRoot = resolve28(root, changePath);
|
|
24497
25538
|
if (!changeRoot.startsWith(root)) {
|
|
24498
25539
|
return {
|
|
24499
25540
|
valid: false,
|
|
@@ -24511,18 +25552,18 @@ async function assessChangeFolder(projectRoot, changePath) {
|
|
|
24511
25552
|
successCriteria: []
|
|
24512
25553
|
};
|
|
24513
25554
|
}
|
|
24514
|
-
const specDir =
|
|
25555
|
+
const specDir = join21(changeRoot, "specs");
|
|
24515
25556
|
const specFiles = await walkMarkdown(specDir);
|
|
24516
|
-
const extra = ["proposal.md", "design.md"].map((name) =>
|
|
25557
|
+
const extra = ["proposal.md", "design.md"].map((name) => join21(changeRoot, name));
|
|
24517
25558
|
const reports = [];
|
|
24518
25559
|
for (const file of specFiles) {
|
|
24519
|
-
const content = await
|
|
25560
|
+
const content = await readFile30(file, "utf-8");
|
|
24520
25561
|
reports.push(assessSpecMarkdown(content, relative5(root, file).replace(/\\/g, "/")));
|
|
24521
25562
|
}
|
|
24522
25563
|
for (const file of extra) {
|
|
24523
25564
|
let content;
|
|
24524
25565
|
try {
|
|
24525
|
-
content = await
|
|
25566
|
+
content = await readFile30(file, "utf-8");
|
|
24526
25567
|
} catch {
|
|
24527
25568
|
continue;
|
|
24528
25569
|
}
|
|
@@ -24577,8 +25618,8 @@ var init_spec_quality = __esm(() => {
|
|
|
24577
25618
|
});
|
|
24578
25619
|
|
|
24579
25620
|
// src/core/openspec/spec-analyzer.ts
|
|
24580
|
-
import { readFile as
|
|
24581
|
-
import { join as
|
|
25621
|
+
import { readFile as readFile31 } from "node:fs/promises";
|
|
25622
|
+
import { join as join22, resolve as resolve29 } from "node:path";
|
|
24582
25623
|
function unique(ids) {
|
|
24583
25624
|
return [...new Set(ids)];
|
|
24584
25625
|
}
|
|
@@ -24673,23 +25714,23 @@ function analyzeSpecArtifacts(input) {
|
|
|
24673
25714
|
};
|
|
24674
25715
|
}
|
|
24675
25716
|
async function analyzeChangeFolder(projectRoot, changePath, options) {
|
|
24676
|
-
const changeRoot =
|
|
24677
|
-
const specPath =
|
|
25717
|
+
const changeRoot = resolve29(projectRoot, changePath);
|
|
25718
|
+
const specPath = join22(changeRoot, "specs", "delta.md");
|
|
24678
25719
|
let specMarkdown = "";
|
|
24679
25720
|
try {
|
|
24680
|
-
specMarkdown = await
|
|
25721
|
+
specMarkdown = await readFile31(specPath, "utf-8");
|
|
24681
25722
|
} catch {
|
|
24682
25723
|
specMarkdown = "";
|
|
24683
25724
|
}
|
|
24684
25725
|
let tasksMarkdown = "";
|
|
24685
25726
|
try {
|
|
24686
|
-
tasksMarkdown = await
|
|
25727
|
+
tasksMarkdown = await readFile31(join22(changeRoot, "tasks.md"), "utf-8");
|
|
24687
25728
|
} catch {
|
|
24688
25729
|
tasksMarkdown = "";
|
|
24689
25730
|
}
|
|
24690
25731
|
let designMarkdown;
|
|
24691
25732
|
try {
|
|
24692
|
-
designMarkdown = await
|
|
25733
|
+
designMarkdown = await readFile31(join22(changeRoot, "design.md"), "utf-8");
|
|
24693
25734
|
} catch {
|
|
24694
25735
|
designMarkdown = undefined;
|
|
24695
25736
|
}
|
|
@@ -24712,8 +25753,8 @@ var exports_openspec_command = {};
|
|
|
24712
25753
|
__export(exports_openspec_command, {
|
|
24713
25754
|
openspecCommand: () => openspecCommand
|
|
24714
25755
|
});
|
|
24715
|
-
import { readFile as
|
|
24716
|
-
import { resolve as
|
|
25756
|
+
import { readFile as readFile32 } from "node:fs/promises";
|
|
25757
|
+
import { resolve as resolve30 } from "node:path";
|
|
24717
25758
|
async function openspecCommand(options) {
|
|
24718
25759
|
const { subcommand, itemId, projectRoot, output, reason } = options;
|
|
24719
25760
|
switch (subcommand) {
|
|
@@ -24757,7 +25798,7 @@ function fail(command, errors3, extra = {}) {
|
|
|
24757
25798
|
};
|
|
24758
25799
|
}
|
|
24759
25800
|
async function persistBacklog(projectRoot, content) {
|
|
24760
|
-
await writeFileAtomic(
|
|
25801
|
+
await writeFileAtomic(resolve30(projectRoot, BACKLOG_FILENAME), content);
|
|
24761
25802
|
}
|
|
24762
25803
|
async function persistState(projectRoot, state) {
|
|
24763
25804
|
const written = await writeOpenspecState(projectRoot, state);
|
|
@@ -24767,7 +25808,7 @@ async function persistState(projectRoot, state) {
|
|
|
24767
25808
|
return { ok: true };
|
|
24768
25809
|
}
|
|
24769
25810
|
async function readBacklogMarkdown(projectRoot) {
|
|
24770
|
-
return
|
|
25811
|
+
return readFile32(resolve30(projectRoot, BACKLOG_FILENAME), "utf-8");
|
|
24771
25812
|
}
|
|
24772
25813
|
async function transitionItem(projectRoot, item, to, progress) {
|
|
24773
25814
|
const content = await readBacklogMarkdown(projectRoot);
|
|
@@ -24965,7 +26006,7 @@ async function handleAnalyze(projectRoot, itemId) {
|
|
|
24965
26006
|
const policyParts = [];
|
|
24966
26007
|
for (const name of ["AGENTS.md", "BACKLOG.md"]) {
|
|
24967
26008
|
try {
|
|
24968
|
-
policyParts.push(await
|
|
26009
|
+
policyParts.push(await readFile32(resolve30(projectRoot, name), "utf-8"));
|
|
24969
26010
|
} catch {}
|
|
24970
26011
|
}
|
|
24971
26012
|
const cards = itemCards(stateResult.data, targetId);
|
|
@@ -25479,7 +26520,7 @@ __export(exports_hook_command, {
|
|
|
25479
26520
|
});
|
|
25480
26521
|
import { spawnSync } from "node:child_process";
|
|
25481
26522
|
import { existsSync as existsSync7 } from "node:fs";
|
|
25482
|
-
import { resolve as
|
|
26523
|
+
import { resolve as resolve31 } from "node:path";
|
|
25483
26524
|
function detectFormat(explicit, stdinText) {
|
|
25484
26525
|
if (explicit)
|
|
25485
26526
|
return explicit;
|
|
@@ -25506,8 +26547,8 @@ function resolvePreToolInput(options, stdinText) {
|
|
|
25506
26547
|
};
|
|
25507
26548
|
}
|
|
25508
26549
|
async function sessionLines(projectRoot) {
|
|
25509
|
-
const backlogPath =
|
|
25510
|
-
const profilePath =
|
|
26550
|
+
const backlogPath = resolve31(projectRoot, "BACKLOG.md");
|
|
26551
|
+
const profilePath = resolve31(projectRoot, ".codeconductor", "evaluation", "execution-profile.yml");
|
|
25511
26552
|
return [
|
|
25512
26553
|
"[CodeConductor] Session start",
|
|
25513
26554
|
"Skills: openspec, backlog, evaluation, testing-tdd — invoke via /cc-* then CLI.",
|
|
@@ -25585,7 +26626,7 @@ var init_scorecard_constants = __esm(() => {
|
|
|
25585
26626
|
{ id: "minimal_diff", label: "Minimal diff (no scope creep)", weight: 0.2 },
|
|
25586
26627
|
{ id: "tests", label: "Tests present and passing", weight: 0.15 },
|
|
25587
26628
|
{ id: "regressions", label: "No regressions introduced", weight: 0.15 },
|
|
25588
|
-
{ id: "conventions", label: "Code follows project conventions", weight: 0.
|
|
26629
|
+
{ id: "conventions", label: "Code follows project conventions", weight: 0.05 },
|
|
25589
26630
|
{ id: "documentation", label: "Documentation updated if required", weight: 0.05 },
|
|
25590
26631
|
{ id: "context_discipline", label: "Context discipline", weight: 0.05 },
|
|
25591
26632
|
{ id: "cc_gain", label: "Complexity diffusion (cc-gain)", weight: 0.05 }
|
|
@@ -25979,12 +27020,20 @@ function collectScorecardSignals(projectRoot, scopeFiles, extra) {
|
|
|
25979
27020
|
const overrides = {};
|
|
25980
27021
|
const scopeViolationCount = extra?.scopeViolationCount;
|
|
25981
27022
|
if (scopeViolationCount && scopeViolationCount > 0) {
|
|
25982
|
-
overrides.
|
|
27023
|
+
overrides.minimal_diff = {
|
|
27024
|
+
score: 0,
|
|
27025
|
+
notes: `Found ${scopeViolationCount} scope violations`,
|
|
27026
|
+
autoSuggested: true
|
|
27027
|
+
};
|
|
25983
27028
|
findings.push(`Scope violation: ${scopeViolationCount} files outside scope.`);
|
|
25984
27029
|
}
|
|
25985
27030
|
const hashMismatch = extra?.hashMismatch;
|
|
25986
27031
|
if (hashMismatch) {
|
|
25987
|
-
overrides.tests = {
|
|
27032
|
+
overrides.tests = {
|
|
27033
|
+
score: 0,
|
|
27034
|
+
notes: "Test tampering detected (hash mismatch)",
|
|
27035
|
+
autoSuggested: true
|
|
27036
|
+
};
|
|
25988
27037
|
findings.push("Test tampering detected via test-freeze hash mismatch.");
|
|
25989
27038
|
}
|
|
25990
27039
|
let diff = "";
|
|
@@ -25999,7 +27048,9 @@ function collectScorecardSignals(projectRoot, scopeFiles, extra) {
|
|
|
25999
27048
|
return { criteriaOverrides: overrides, findings, scopeViolationCount, hashMismatch };
|
|
26000
27049
|
}
|
|
26001
27050
|
if (!diff.trim()) {
|
|
26002
|
-
overrides.minimal_diff
|
|
27051
|
+
if (!overrides.minimal_diff) {
|
|
27052
|
+
overrides.minimal_diff = { score: 2, notes: "No diff detected", autoSuggested: true };
|
|
27053
|
+
}
|
|
26003
27054
|
return { criteriaOverrides: overrides, findings, scopeViolationCount, hashMismatch };
|
|
26004
27055
|
}
|
|
26005
27056
|
const changedFiles = new Set;
|
|
@@ -26018,7 +27069,7 @@ function collectScorecardSignals(projectRoot, scopeFiles, extra) {
|
|
|
26018
27069
|
autoSuggested: true
|
|
26019
27070
|
};
|
|
26020
27071
|
findings.push(`Scope creep detected in ${outOfScope.length} file(s).`);
|
|
26021
|
-
} else {
|
|
27072
|
+
} else if (!overrides.minimal_diff) {
|
|
26022
27073
|
overrides.minimal_diff = { score: 2, notes: "Diff within declared scope", autoSuggested: true };
|
|
26023
27074
|
}
|
|
26024
27075
|
}
|
|
@@ -26082,24 +27133,24 @@ var init_scorecard_signals = __esm(() => {
|
|
|
26082
27133
|
|
|
26083
27134
|
// src/core/evaluation/harness-experiment.ts
|
|
26084
27135
|
import { existsSync as existsSync8 } from "node:fs";
|
|
26085
|
-
import { cp, mkdir as mkdir20, readFile as
|
|
26086
|
-
import { dirname as
|
|
27136
|
+
import { cp, mkdir as mkdir20, readFile as readFile33, readdir as readdir10, writeFile as writeFile20 } from "node:fs/promises";
|
|
27137
|
+
import { dirname as dirname10, join as join23, resolve as resolve32 } from "node:path";
|
|
26087
27138
|
function experimentDir(projectRoot, experimentId) {
|
|
26088
|
-
return
|
|
27139
|
+
return resolve32(projectRoot, EVAL_DIR2, EXPERIMENTS_DIR, experimentId);
|
|
26089
27140
|
}
|
|
26090
27141
|
function experimentYamlPath(projectRoot, experimentId) {
|
|
26091
|
-
return
|
|
27142
|
+
return join23(experimentDir(projectRoot, experimentId), "experiment.yml");
|
|
26092
27143
|
}
|
|
26093
27144
|
async function loadHarnessSuite(projectRoot, suiteId, suitePath) {
|
|
26094
27145
|
const candidates = suitePath ? [suitePath] : [
|
|
26095
|
-
|
|
26096
|
-
|
|
27146
|
+
resolve32(projectRoot, "eval", "suites", suiteId, "suite.yml"),
|
|
27147
|
+
resolve32(projectRoot, EVAL_DIR2, "suites", suiteId, "suite.yml")
|
|
26097
27148
|
];
|
|
26098
27149
|
for (const path of candidates) {
|
|
26099
27150
|
if (!existsSync8(path))
|
|
26100
27151
|
continue;
|
|
26101
27152
|
try {
|
|
26102
|
-
const suite = HarnessSuiteSchema.parse($parse(await
|
|
27153
|
+
const suite = HarnessSuiteSchema.parse($parse(await readFile33(path, "utf-8")));
|
|
26103
27154
|
return ok({ ...suite, path });
|
|
26104
27155
|
} catch (e) {
|
|
26105
27156
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -26109,7 +27160,7 @@ async function loadHarnessSuite(projectRoot, suiteId, suitePath) {
|
|
|
26109
27160
|
}
|
|
26110
27161
|
async function loadExperiment(projectRoot, experimentId) {
|
|
26111
27162
|
try {
|
|
26112
|
-
const raw = await
|
|
27163
|
+
const raw = await readFile33(experimentYamlPath(projectRoot, experimentId), "utf-8");
|
|
26113
27164
|
return ok(HarnessExperimentSchema.parse($parse(raw)));
|
|
26114
27165
|
} catch (e) {
|
|
26115
27166
|
if (e.code === "ENOENT") {
|
|
@@ -26119,10 +27170,10 @@ async function loadExperiment(projectRoot, experimentId) {
|
|
|
26119
27170
|
}
|
|
26120
27171
|
}
|
|
26121
27172
|
async function listExperiments(projectRoot) {
|
|
26122
|
-
const root =
|
|
27173
|
+
const root = resolve32(projectRoot, EVAL_DIR2, EXPERIMENTS_DIR);
|
|
26123
27174
|
if (!existsSync8(root))
|
|
26124
27175
|
return [];
|
|
26125
|
-
const ids = await
|
|
27176
|
+
const ids = await readdir10(root);
|
|
26126
27177
|
const experiments = [];
|
|
26127
27178
|
for (const id of ids) {
|
|
26128
27179
|
const loaded = await loadExperiment(projectRoot, id);
|
|
@@ -26198,7 +27249,7 @@ function generateExperimentId(suiteId, now = new Date) {
|
|
|
26198
27249
|
return `abl-${date}-${suiteId}-${rand}`;
|
|
26199
27250
|
}
|
|
26200
27251
|
async function copyFixture(suitePath, fixtureDir, dest) {
|
|
26201
|
-
const source = fixtureDir ?
|
|
27252
|
+
const source = fixtureDir ? resolve32(dirname10(suitePath), fixtureDir) : join23(dirname10(suitePath), "fixture");
|
|
26202
27253
|
await mkdir20(dest, { recursive: true });
|
|
26203
27254
|
if (existsSync8(source)) {
|
|
26204
27255
|
await cp(source, dest, { recursive: true });
|
|
@@ -26222,11 +27273,11 @@ async function startHarnessExperiment(projectRoot, options) {
|
|
|
26222
27273
|
};
|
|
26223
27274
|
const root = experimentDir(projectRoot, experimentId);
|
|
26224
27275
|
await mkdir20(root, { recursive: true });
|
|
26225
|
-
await
|
|
26226
|
-
await
|
|
27276
|
+
await writeFile20(experimentYamlPath(projectRoot, experimentId), $stringify(experiment), "utf-8");
|
|
27277
|
+
await writeFile20(join23(root, "EXPERIMENT.md"), formatExperimentMarkdown(experiment), "utf-8");
|
|
26227
27278
|
for (const task of suite.data.tasks) {
|
|
26228
27279
|
for (const variantId of variants) {
|
|
26229
|
-
const runRoot =
|
|
27280
|
+
const runRoot = join23(root, "runs", task.id, variantDirName(variantId));
|
|
26230
27281
|
await copyFixture(suite.data.path, suite.data.fixtureDir, runRoot);
|
|
26231
27282
|
await writeConfig(runRoot, structuredClone(DEFAULT_CONFIG), true);
|
|
26232
27283
|
const disabled = variantId === "baseline" ? [] : options.components.filter((id) => variantIdFor(id) === variantId);
|
|
@@ -26238,7 +27289,7 @@ async function startHarnessExperiment(projectRoot, options) {
|
|
|
26238
27289
|
});
|
|
26239
27290
|
if (!overlay.success)
|
|
26240
27291
|
return overlay;
|
|
26241
|
-
await
|
|
27292
|
+
await writeFile20(join23(runRoot, "TASK.md"), formatTaskCard(task, experimentId, variantId), "utf-8");
|
|
26242
27293
|
}
|
|
26243
27294
|
}
|
|
26244
27295
|
return ok(experiment);
|
|
@@ -26273,7 +27324,7 @@ var init_harness_experiment = __esm(() => {
|
|
|
26273
27324
|
// src/core/evaluation/suite-run.ts
|
|
26274
27325
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
26275
27326
|
import { existsSync as existsSync9 } from "node:fs";
|
|
26276
|
-
import { resolve as
|
|
27327
|
+
import { resolve as resolve33 } from "node:path";
|
|
26277
27328
|
async function runHarnessSuiteTasks(projectRoot, suiteId, suitePath) {
|
|
26278
27329
|
const suite = await loadHarnessSuite(projectRoot, suiteId, suitePath);
|
|
26279
27330
|
if (!suite.success) {
|
|
@@ -26333,7 +27384,7 @@ function runTaskCommand(projectRoot, task) {
|
|
|
26333
27384
|
if (parts.length === 0) {
|
|
26334
27385
|
return { ok: false, detail: "Empty testCommand" };
|
|
26335
27386
|
}
|
|
26336
|
-
const bin = parts[0] === "bun" && existsSync9(
|
|
27387
|
+
const bin = parts[0] === "bun" && existsSync9(resolve33(projectRoot, "src/cli/main.ts")) ? "bun" : parts[0];
|
|
26337
27388
|
const args = parts[0] === "bun" ? parts.slice(1) : parts.slice(1);
|
|
26338
27389
|
const result = spawnSync2(bin, args, {
|
|
26339
27390
|
cwd: projectRoot,
|
|
@@ -26384,11 +27435,11 @@ var init_suite_run = __esm(() => {
|
|
|
26384
27435
|
});
|
|
26385
27436
|
|
|
26386
27437
|
// src/core/evaluation/execution-profile.ts
|
|
26387
|
-
import { readFile as
|
|
26388
|
-
import { resolve as
|
|
27438
|
+
import { readFile as readFile34 } from "node:fs/promises";
|
|
27439
|
+
import { resolve as resolve34 } from "node:path";
|
|
26389
27440
|
async function loadExecutionProfile(projectRoot, defaultTarget = "opencode") {
|
|
26390
27441
|
try {
|
|
26391
|
-
const content = await
|
|
27442
|
+
const content = await readFile34(resolve34(projectRoot, PROFILE_FILE), "utf-8");
|
|
26392
27443
|
const data = $parse(content);
|
|
26393
27444
|
return ExecutionProfileSchema.parse(data);
|
|
26394
27445
|
} catch {
|
|
@@ -26468,14 +27519,14 @@ var init_execution_profile = __esm(() => {
|
|
|
26468
27519
|
});
|
|
26469
27520
|
|
|
26470
27521
|
// src/core/evaluation/prompt-diff.ts
|
|
26471
|
-
import { readFile as
|
|
26472
|
-
import { join as
|
|
27522
|
+
import { readFile as readFile35, readdir as readdir11 } from "node:fs/promises";
|
|
27523
|
+
import { join as join24, resolve as resolve35 } from "node:path";
|
|
26473
27524
|
function normalizeVersion(v) {
|
|
26474
27525
|
return v.startsWith("v") ? v : `v${v}`;
|
|
26475
27526
|
}
|
|
26476
27527
|
async function listPromptFiles(dir) {
|
|
26477
27528
|
try {
|
|
26478
|
-
const entries = await
|
|
27529
|
+
const entries = await readdir11(dir, { withFileTypes: true });
|
|
26479
27530
|
return entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => e.name);
|
|
26480
27531
|
} catch {
|
|
26481
27532
|
return [];
|
|
@@ -26518,30 +27569,30 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
|
|
|
26518
27569
|
const fromV = normalizeVersion(fromVersion);
|
|
26519
27570
|
const toV = normalizeVersion(toVersion);
|
|
26520
27571
|
const searchRoots = [
|
|
26521
|
-
|
|
26522
|
-
|
|
26523
|
-
|
|
27572
|
+
resolve35(options.projectRoot ?? PACKAGE_ROOT, ".agents", "prompts"),
|
|
27573
|
+
join24(ROOT_PRESETS_DIR, target, "prompts"),
|
|
27574
|
+
join24(ROOT_PRESETS_DIR, "opencode", "prompts")
|
|
26524
27575
|
];
|
|
26525
27576
|
let fromDir = "";
|
|
26526
27577
|
let toDir = "";
|
|
26527
27578
|
for (const root of searchRoots) {
|
|
26528
|
-
const f =
|
|
26529
|
-
const t =
|
|
27579
|
+
const f = join24(root, fromV);
|
|
27580
|
+
const t = join24(root, toV);
|
|
26530
27581
|
try {
|
|
26531
|
-
await
|
|
27582
|
+
await readFile35(join24(f, "orchestrator.md"), "utf-8");
|
|
26532
27583
|
fromDir = f;
|
|
26533
27584
|
toDir = t;
|
|
26534
27585
|
break;
|
|
26535
27586
|
} catch {}
|
|
26536
27587
|
}
|
|
26537
27588
|
if (!fromDir) {
|
|
26538
|
-
fromDir =
|
|
26539
|
-
toDir =
|
|
27589
|
+
fromDir = join24(ROOT_PRESETS_DIR, "opencode", "prompts", fromV);
|
|
27590
|
+
toDir = join24(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
|
|
26540
27591
|
} else {
|
|
26541
27592
|
try {
|
|
26542
|
-
await
|
|
27593
|
+
await readFile35(join24(toDir, "orchestrator.md"), "utf-8");
|
|
26543
27594
|
} catch {
|
|
26544
|
-
toDir =
|
|
27595
|
+
toDir = join24(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
|
|
26545
27596
|
}
|
|
26546
27597
|
}
|
|
26547
27598
|
const fromFiles = await listPromptFiles(fromDir);
|
|
@@ -26559,12 +27610,12 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
|
|
|
26559
27610
|
let oldText = "";
|
|
26560
27611
|
let newText = "";
|
|
26561
27612
|
try {
|
|
26562
|
-
oldText = await
|
|
27613
|
+
oldText = await readFile35(join24(fromDir, name), "utf-8");
|
|
26563
27614
|
} catch {
|
|
26564
27615
|
oldText = "";
|
|
26565
27616
|
}
|
|
26566
27617
|
try {
|
|
26567
|
-
newText = await
|
|
27618
|
+
newText = await readFile35(join24(toDir, name), "utf-8");
|
|
26568
27619
|
} catch {
|
|
26569
27620
|
newText = "";
|
|
26570
27621
|
}
|
|
@@ -26604,12 +27655,12 @@ var init_prompt_diff = __esm(() => {
|
|
|
26604
27655
|
|
|
26605
27656
|
// src/core/evaluation/regression-checklist.ts
|
|
26606
27657
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
26607
|
-
import { mkdir as mkdir21, readFile as
|
|
26608
|
-
import { dirname as
|
|
27658
|
+
import { mkdir as mkdir21, readFile as readFile36, writeFile as writeFile21 } from "node:fs/promises";
|
|
27659
|
+
import { dirname as dirname11, resolve as resolve36 } from "node:path";
|
|
26609
27660
|
async function loadRegressionChecklist() {
|
|
26610
27661
|
try {
|
|
26611
|
-
const path =
|
|
26612
|
-
const content = await
|
|
27662
|
+
const path = resolve36(ROOT_PRESETS_DIR, "templates", "regression-checklist.yml");
|
|
27663
|
+
const content = await readFile36(path, "utf-8");
|
|
26613
27664
|
const data = $parse(content);
|
|
26614
27665
|
return data.checks ?? [];
|
|
26615
27666
|
} catch {
|
|
@@ -26664,9 +27715,9 @@ async function runRegressionChecklist(projectRoot, options = {}) {
|
|
|
26664
27715
|
checks,
|
|
26665
27716
|
timestamp: new Date().toISOString()
|
|
26666
27717
|
};
|
|
26667
|
-
const outPath =
|
|
26668
|
-
await mkdir21(
|
|
26669
|
-
await
|
|
27718
|
+
const outPath = resolve36(projectRoot, ".codeconductor/evaluation/regression-last.json");
|
|
27719
|
+
await mkdir21(dirname11(outPath), { recursive: true });
|
|
27720
|
+
await writeFile21(outPath, JSON.stringify(report, null, 2), "utf-8");
|
|
26670
27721
|
return ok(report);
|
|
26671
27722
|
} catch (e) {
|
|
26672
27723
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -26708,8 +27759,8 @@ var init_model_comparison = __esm(() => {
|
|
|
26708
27759
|
});
|
|
26709
27760
|
|
|
26710
27761
|
// src/core/evaluation/cost-quality-matrix.ts
|
|
26711
|
-
import { writeFile as
|
|
26712
|
-
import { resolve as
|
|
27762
|
+
import { writeFile as writeFile22 } from "node:fs/promises";
|
|
27763
|
+
import { resolve as resolve37 } from "node:path";
|
|
26713
27764
|
async function buildCostQualityMatrix(projectRoot, outcomes) {
|
|
26714
27765
|
const agg = aggregateOutcomes(outcomes);
|
|
26715
27766
|
const rows = Object.entries(agg.byModel).map(([model, entry]) => {
|
|
@@ -26729,7 +27780,7 @@ async function buildCostQualityMatrix(projectRoot, outcomes) {
|
|
|
26729
27780
|
rows
|
|
26730
27781
|
};
|
|
26731
27782
|
const dir = await ensureEvaluationDir(projectRoot);
|
|
26732
|
-
await
|
|
27783
|
+
await writeFile22(resolve37(dir, "matrix.yml"), $stringify(matrix), "utf-8");
|
|
26733
27784
|
return matrix;
|
|
26734
27785
|
}
|
|
26735
27786
|
function formatMatrixMarkdown(matrix) {
|
|
@@ -26753,8 +27804,8 @@ var init_cost_quality_matrix = __esm(() => {
|
|
|
26753
27804
|
});
|
|
26754
27805
|
|
|
26755
27806
|
// src/core/evaluation/ablation-report.ts
|
|
26756
|
-
import { mkdir as mkdir22, writeFile as
|
|
26757
|
-
import { resolve as
|
|
27807
|
+
import { mkdir as mkdir22, writeFile as writeFile23 } from "node:fs/promises";
|
|
27808
|
+
import { resolve as resolve38 } from "node:path";
|
|
26758
27809
|
function isPass(o) {
|
|
26759
27810
|
return o.verdict === "PASS" || o.status === "pass";
|
|
26760
27811
|
}
|
|
@@ -26922,10 +27973,10 @@ function formatAblationMarkdown(report) {
|
|
|
26922
27973
|
`);
|
|
26923
27974
|
}
|
|
26924
27975
|
async function persistAblationReport(projectRoot, markdown) {
|
|
26925
|
-
const dir =
|
|
27976
|
+
const dir = resolve38(projectRoot, EVAL_DIR2);
|
|
26926
27977
|
await mkdir22(dir, { recursive: true });
|
|
26927
|
-
const path =
|
|
26928
|
-
await
|
|
27978
|
+
const path = resolve38(dir, "ablation-last.md");
|
|
27979
|
+
await writeFile23(path, markdown, "utf-8");
|
|
26929
27980
|
return path;
|
|
26930
27981
|
}
|
|
26931
27982
|
var SCORE_THRESHOLD = 0.1, PASS_RATE_THRESHOLD = 0.05;
|
|
@@ -26939,8 +27990,8 @@ var exports_scorecard_command = {};
|
|
|
26939
27990
|
__export(exports_scorecard_command, {
|
|
26940
27991
|
scorecardCommand: () => scorecardCommand
|
|
26941
27992
|
});
|
|
26942
|
-
import { readFile as
|
|
26943
|
-
import { resolve as
|
|
27993
|
+
import { readFile as readFile37 } from "node:fs/promises";
|
|
27994
|
+
import { resolve as resolve39 } from "node:path";
|
|
26944
27995
|
function contractVersion() {
|
|
26945
27996
|
return package_default.version;
|
|
26946
27997
|
}
|
|
@@ -27221,13 +28272,13 @@ async function handleCompareModels(projectRoot, options) {
|
|
|
27221
28272
|
outcomes = outcomes.filter((o) => options.modelsFilter.includes(o.model));
|
|
27222
28273
|
}
|
|
27223
28274
|
const markdown = generateModelComparisonMarkdown(outcomes, options.modelsFilter);
|
|
27224
|
-
const templatePath =
|
|
28275
|
+
const templatePath = resolve39(projectRoot, ".codeconductor/evaluation/model-comparison-last.md");
|
|
27225
28276
|
try {
|
|
27226
|
-
await
|
|
28277
|
+
await readFile37(templatePath);
|
|
27227
28278
|
} catch {}
|
|
27228
|
-
const { writeFile:
|
|
27229
|
-
await mkdir23(
|
|
27230
|
-
await
|
|
28279
|
+
const { writeFile: writeFile24, mkdir: mkdir23 } = await import("node:fs/promises");
|
|
28280
|
+
await mkdir23(resolve39(projectRoot, ".codeconductor/evaluation"), { recursive: true });
|
|
28281
|
+
await writeFile24(templatePath, markdown, "utf-8");
|
|
27231
28282
|
return {
|
|
27232
28283
|
code: 0,
|
|
27233
28284
|
data: {
|
|
@@ -28696,7 +29747,7 @@ var exports_seo_audit_command = {};
|
|
|
28696
29747
|
__export(exports_seo_audit_command, {
|
|
28697
29748
|
seoAuditCommand: () => seoAuditCommand
|
|
28698
29749
|
});
|
|
28699
|
-
import { join as
|
|
29750
|
+
import { join as join25 } from "node:path";
|
|
28700
29751
|
async function seoAuditCommand(options) {
|
|
28701
29752
|
const { url, sitemap, format, failOn, delay: delay2, output, followRedirects, force } = options;
|
|
28702
29753
|
if (!url && !sitemap) {
|
|
@@ -28709,7 +29760,7 @@ async function seoAuditCommand(options) {
|
|
|
28709
29760
|
}
|
|
28710
29761
|
};
|
|
28711
29762
|
}
|
|
28712
|
-
const defaultMarkdownPath = output === undefined && format === "markdown" ?
|
|
29763
|
+
const defaultMarkdownPath = output === undefined && format === "markdown" ? join25("seo-reports", `audit-report-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19)}.md`) : undefined;
|
|
28713
29764
|
const outputPathToWrite = output ?? defaultMarkdownPath;
|
|
28714
29765
|
if (outputPathToWrite !== undefined) {
|
|
28715
29766
|
const preflightError = await preflightContainedOutput(options.projectRoot, outputPathToWrite, { force });
|
|
@@ -28978,6 +30029,7 @@ init_errors();
|
|
|
28978
30029
|
// src/cli/router.ts
|
|
28979
30030
|
init_package();
|
|
28980
30031
|
init_zod();
|
|
30032
|
+
init_runner_target();
|
|
28981
30033
|
var OutputModeSchema = exports_external.enum(["json", "human"]);
|
|
28982
30034
|
var SeoFormatSchema = exports_external.enum(["cli", "json", "markdown"]);
|
|
28983
30035
|
var SeoFailOnSchema = exports_external.enum(["error", "warning", "never"]);
|
|
@@ -29094,6 +30146,10 @@ Published commands (package ${package_default.version}):
|
|
|
29094
30146
|
seo llms Generate llms.txt from a URL or sitemap
|
|
29095
30147
|
doctor Validate configuration and generated files
|
|
29096
30148
|
update Update installed presets
|
|
30149
|
+
migrate Repair leftover artifacts a reinstall can't fix:
|
|
30150
|
+
rewrite invalid Write(path) permission rules to
|
|
30151
|
+
Edit(path) and dedupe, and delete orphaned
|
|
30152
|
+
.{target}/prompts/v{old}/ directories
|
|
29097
30153
|
help Show general CLI usage and command list
|
|
29098
30154
|
ask Recommend a /cc: slash command from a natural-language problem
|
|
29099
30155
|
cc-help Show preset inventory (skills, subagents, commands)
|
|
@@ -29122,7 +30178,7 @@ Options:
|
|
|
29122
30178
|
--output, -o Output mode: human or json
|
|
29123
30179
|
--lang Comma-separated list of languages (e.g., typescript,php,python)
|
|
29124
30180
|
--locale Instruction language for agent files: en (default) | es
|
|
29125
|
-
--target Runner target: opencode, claude, codex, gemini, cursor, agy, all
|
|
30181
|
+
--target Runner target: opencode, claude, codex, gemini, cursor, agy, pi, all
|
|
29126
30182
|
|
|
29127
30183
|
Stack-specific presets (v0.4.0, registered in preset-registry):
|
|
29128
30184
|
ts-next-drizzle Next.js / Astro, Tailwind, Drizzle ORM, Bun, Postgres
|
|
@@ -29169,6 +30225,9 @@ Examples:
|
|
|
29169
30225
|
npx cc-codeconductor install lsp --target claude --dry-run
|
|
29170
30226
|
npx cc-codeconductor doctor
|
|
29171
30227
|
npx cc-codeconductor update --dry-run
|
|
30228
|
+
npx cc-codeconductor migrate --dry-run
|
|
30229
|
+
npx cc-codeconductor migrate --global
|
|
30230
|
+
npx cc-codeconductor migrate --file .claude/settings.local.json
|
|
29172
30231
|
npx cc-codeconductor seo audit --url https://example.com
|
|
29173
30232
|
npx cc-codeconductor seo audit --sitemap https://example.com/sitemap.xml
|
|
29174
30233
|
npx cc-codeconductor seo audit --sitemap https://example.com/sitemap.xml --format markdown
|
|
@@ -29275,7 +30334,7 @@ async function routeCommand(args, projectRoot) {
|
|
|
29275
30334
|
}
|
|
29276
30335
|
case "install": {
|
|
29277
30336
|
const isGlobal = options.global === true || options.global === "true";
|
|
29278
|
-
const VALID_TARGETS =
|
|
30337
|
+
const VALID_TARGETS = RUNNER_TARGETS;
|
|
29279
30338
|
const VALID_INSTALL_SUBCOMMANDS = ["council", "preset", "lsp", ...VALID_TARGETS];
|
|
29280
30339
|
if (subcommand && !VALID_INSTALL_SUBCOMMANDS.includes(subcommand)) {
|
|
29281
30340
|
return unknownSubcommand("install", subcommand, VALID_INSTALL_SUBCOMMANDS);
|
|
@@ -29342,6 +30401,16 @@ async function routeCommand(args, projectRoot) {
|
|
|
29342
30401
|
output: flags.output
|
|
29343
30402
|
});
|
|
29344
30403
|
}
|
|
30404
|
+
case "migrate": {
|
|
30405
|
+
const { migrateCommand: migrateCommand2 } = await Promise.resolve().then(() => (init_migrate_command(), exports_migrate_command));
|
|
30406
|
+
return migrateCommand2({
|
|
30407
|
+
projectRoot,
|
|
30408
|
+
dryRun: flags.dryRun,
|
|
30409
|
+
global: options.global === true || options.global === "true",
|
|
30410
|
+
output: flags.output,
|
|
30411
|
+
file: options.file
|
|
30412
|
+
});
|
|
30413
|
+
}
|
|
29345
30414
|
case "help":
|
|
29346
30415
|
return {
|
|
29347
30416
|
code: 0,
|