cc-codeconductor 1.4.2 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -14
- package/dist/domain/product/entities.d.ts +1 -1
- package/dist/index.js +811 -354
- package/dist/library.js +47 -3
- package/dist/validation/schemas.d.ts +183 -21
- package/docs/generated/cli.md +16 -0
- package/package.json +1 -1
- package/presets/agy/README.md +1 -1
- package/presets/agy/hooks.json +1 -1
- package/presets/agy/scripts/invoke-hook.cjs +20 -5
- package/presets/agy/settings.json +1 -1
- package/presets/agy/skills/api-versioning/SKILL.md +394 -0
- package/presets/agy/skills/astro/SKILL.md +318 -0
- package/presets/agy/skills/auth-token-inspector/SKILL.md +30 -0
- package/presets/agy/skills/cc-pagespeed/SKILL.md +2 -3
- package/presets/agy/skills/code-review/SKILL.md +207 -0
- package/presets/agy/skills/django-orm/SKILL.md +460 -0
- package/presets/agy/skills/django-uv/SKILL.md +405 -0
- package/presets/agy/skills/drizzle-schema-architect/SKILL.md +50 -0
- package/presets/agy/skills/fastapi-pydantic-strict/SKILL.md +43 -0
- package/presets/agy/skills/jpa-nplusone-detector/SKILL.md +45 -0
- package/presets/agy/skills/jpa-postgres/SKILL.md +623 -0
- package/presets/agy/skills/livewire-alpine-bridge/SKILL.md +35 -0
- package/presets/agy/skills/nextjs-typescript/SKILL.md +390 -0
- package/presets/agy/skills/python/SKILL.md +611 -0
- package/presets/agy/skills/seo-analytics-injector/SKILL.md +43 -0
- package/presets/agy/skills/spring-auth-auditor/SKILL.md +29 -0
- package/presets/agy/skills/spring-boot-feature/SKILL.md +563 -0
- package/presets/agy/skills/spring-boot-testing-strategy/SKILL.md +475 -0
- package/presets/agy/skills/tailwind-responsive-auditor/SKILL.md +29 -0
- package/presets/agy/skills/tdd-mutation-tester/SKILL.md +27 -0
- package/presets/agy/workflows/cc-api-contract.md +4 -5
- package/presets/agy/workflows/cc-backlog.md +4 -5
- package/presets/agy/workflows/cc-clarify.md +4 -5
- package/presets/agy/workflows/cc-council.md +4 -5
- package/presets/agy/workflows/cc-db-migration.md +4 -5
- package/presets/agy/workflows/cc-explore.md +4 -5
- package/presets/agy/workflows/cc-feature.md +4 -5
- package/presets/agy/workflows/cc-fix.md +4 -5
- package/presets/agy/workflows/cc-handoff.md +8 -5
- package/presets/agy/workflows/cc-iterative.md +4 -5
- package/presets/agy/workflows/cc-odd.md +4 -3
- package/presets/agy/workflows/cc-openspec.md +5 -6
- package/presets/agy/workflows/cc-pagespeed.md +6 -8
- package/presets/agy/workflows/cc-prototype.md +4 -5
- package/presets/agy/workflows/cc-refactor.md +4 -5
- package/presets/agy/workflows/cc-review.md +35 -5
- package/presets/agy/workflows/cc-scorecard.md +4 -5
- package/presets/agy/workflows/cc-security.md +5 -6
- package/presets/agy/workflows/cc-spec-mutation.md +4 -5
- package/presets/agy/workflows/cc-tdd-cycle.md +4 -5
- package/presets/agy/workflows/cc-test-plan.md +4 -5
- package/presets/agy/workflows/cc-triage.md +4 -5
- package/presets/claude/CLAUDE.md +6 -5
- package/presets/claude/commands/cc/api-contract.md +4 -5
- package/presets/claude/commands/cc/backlog.md +4 -5
- package/presets/claude/commands/cc/clarify.md +4 -5
- package/presets/claude/commands/cc/council.md +4 -5
- package/presets/claude/commands/cc/db-migration.md +4 -5
- package/presets/claude/commands/cc/explore.md +4 -5
- package/presets/claude/commands/cc/feature.md +4 -5
- package/presets/claude/commands/cc/fix.md +4 -5
- package/presets/claude/commands/cc/handoff.md +8 -5
- package/presets/claude/commands/cc/iterative.md +4 -5
- package/presets/claude/commands/cc/odd.md +4 -3
- package/presets/claude/commands/cc/openspec.md +23 -7
- package/presets/claude/commands/cc/pagespeed.md +4 -5
- package/presets/claude/commands/cc/prototype.md +4 -5
- package/presets/claude/commands/cc/refactor.md +4 -5
- package/presets/claude/commands/cc/review.md +37 -5
- package/presets/claude/commands/cc/scorecard.md +4 -5
- package/presets/claude/commands/cc/security.md +4 -5
- package/presets/claude/commands/cc/spec-mutation.md +4 -5
- package/presets/claude/commands/cc/tdd-cycle.md +4 -5
- package/presets/claude/commands/cc/test-plan.md +4 -5
- package/presets/claude/commands/cc/triage.md +4 -5
- package/presets/claude/settings.json +33 -79
- package/presets/claude/skills/android/SKILL.md +1 -1
- package/presets/claude/skills/api-versioning/SKILL.md +1 -1
- package/presets/claude/skills/astro/SKILL.md +318 -0
- package/presets/claude/skills/auth-token-inspector/SKILL.md +30 -0
- package/presets/claude/skills/code-review/SKILL.md +207 -0
- package/presets/claude/skills/django-orm/SKILL.md +1 -1
- package/presets/claude/skills/django-testing/SKILL.md +1 -1
- package/presets/claude/skills/django-uv/SKILL.md +405 -0
- package/presets/claude/skills/drizzle-schema-architect/SKILL.md +50 -0
- package/presets/claude/skills/fastapi-pydantic-strict/SKILL.md +43 -0
- package/presets/claude/skills/jpa-nplusone-detector/SKILL.md +45 -0
- package/presets/claude/skills/jpa-postgres/SKILL.md +1 -1
- package/presets/claude/skills/livewire-alpine-bridge/SKILL.md +35 -0
- package/presets/claude/skills/nextjs-typescript/SKILL.md +390 -0
- package/presets/claude/skills/pagespeed-perf/SKILL.md +1 -1
- package/presets/claude/skills/python/SKILL.md +1 -1
- package/presets/claude/skills/python-django-stack/SKILL.md +1 -1
- package/presets/claude/skills/python-fastapi-stack/SKILL.md +1 -1
- package/presets/claude/skills/security/SKILL.md +1 -1
- package/presets/claude/skills/seo-analytics-injector/SKILL.md +43 -0
- package/presets/claude/skills/spring-auth-auditor/SKILL.md +29 -0
- package/presets/claude/skills/spring-boot-feature/SKILL.md +1 -1
- package/presets/claude/skills/spring-boot-kotlin/SKILL.md +1 -1
- package/presets/claude/skills/spring-boot-testing-strategy/SKILL.md +475 -0
- package/presets/claude/skills/sqlalchemy/SKILL.md +1 -1
- package/presets/claude/skills/tailwind-responsive-auditor/SKILL.md +29 -0
- package/presets/claude/skills/tdd-mutation-tester/SKILL.md +27 -0
- package/presets/claude/skills/testing-strategy/SKILL.md +1 -1
- package/presets/codex/config.toml +2 -0
- package/presets/codex/skills/android/SKILL.md +1 -1
- package/presets/codex/skills/api-versioning/SKILL.md +1 -1
- package/presets/codex/skills/astro/SKILL.md +318 -0
- package/presets/codex/skills/auth-token-inspector/SKILL.md +30 -0
- package/presets/codex/skills/cc-api-contract/SKILL.md +4 -5
- package/presets/codex/skills/cc-backlog/SKILL.md +4 -5
- package/presets/codex/skills/cc-clarify/SKILL.md +4 -5
- package/presets/codex/skills/cc-council/SKILL.md +10 -5
- package/presets/codex/skills/cc-db-migration/SKILL.md +4 -5
- package/presets/codex/skills/cc-explore/SKILL.md +4 -5
- package/presets/codex/skills/cc-feature/SKILL.md +4 -5
- package/presets/codex/skills/cc-fix/SKILL.md +4 -5
- package/presets/codex/skills/cc-handoff/SKILL.md +8 -5
- package/presets/codex/skills/cc-iterative/SKILL.md +4 -5
- package/presets/codex/skills/cc-odd/SKILL.md +4 -3
- package/presets/codex/skills/cc-openspec/SKILL.md +12 -7
- package/presets/codex/skills/cc-pagespeed/SKILL.md +6 -8
- package/presets/codex/skills/cc-prototype/SKILL.md +4 -5
- package/presets/codex/skills/cc-refactor/SKILL.md +4 -5
- package/presets/codex/skills/cc-review/SKILL.md +35 -5
- package/presets/codex/skills/cc-scorecard/SKILL.md +4 -5
- package/presets/codex/skills/cc-security/SKILL.md +5 -6
- package/presets/codex/skills/cc-spec-mutation/SKILL.md +4 -5
- package/presets/codex/skills/cc-tdd-cycle/SKILL.md +4 -5
- package/presets/codex/skills/cc-test-plan/SKILL.md +4 -5
- package/presets/codex/skills/cc-triage/SKILL.md +4 -5
- package/presets/codex/skills/code-review/SKILL.md +207 -0
- package/presets/codex/skills/django-orm/SKILL.md +1 -1
- package/presets/codex/skills/django-testing/SKILL.md +1 -1
- package/presets/codex/skills/django-uv/SKILL.md +405 -0
- package/presets/codex/skills/drizzle-schema-architect/SKILL.md +50 -0
- package/presets/codex/skills/fastapi-pydantic-strict/SKILL.md +43 -0
- package/presets/codex/skills/jpa-nplusone-detector/SKILL.md +45 -0
- package/presets/codex/skills/jpa-postgres/SKILL.md +1 -1
- package/presets/codex/skills/livewire-alpine-bridge/SKILL.md +35 -0
- package/presets/codex/skills/nextjs-typescript/SKILL.md +390 -0
- package/presets/codex/skills/pagespeed-perf/SKILL.md +1 -1
- package/presets/codex/skills/python/SKILL.md +1 -1
- package/presets/codex/skills/python-django-stack/SKILL.md +1 -1
- package/presets/codex/skills/python-fastapi-stack/SKILL.md +1 -1
- package/presets/codex/skills/security-ai-llm/SKILL.md +43 -0
- package/presets/codex/skills/security-blue-team/SKILL.md +43 -0
- package/presets/codex/skills/security-cloud/SKILL.md +43 -0
- package/presets/codex/skills/security-crypto/SKILL.md +43 -0
- package/presets/codex/skills/security-exploit-dev/SKILL.md +45 -0
- package/presets/codex/skills/security-grc/SKILL.md +43 -0
- package/presets/codex/skills/security-incident-response/SKILL.md +45 -0
- package/presets/codex/skills/security-log-analysis/SKILL.md +43 -0
- package/presets/codex/skills/security-malware-analysis/SKILL.md +44 -0
- package/presets/codex/skills/security-mobile/SKILL.md +43 -0
- package/presets/codex/skills/security-network/SKILL.md +43 -0
- package/presets/codex/skills/security-ot-ics/SKILL.md +43 -0
- package/presets/codex/skills/security-recon/SKILL.md +45 -0
- package/presets/codex/skills/security-red-team/SKILL.md +44 -0
- package/presets/codex/skills/security-reverse-engineering/SKILL.md +44 -0
- package/presets/codex/skills/security-soc-automation/SKILL.md +43 -0
- package/presets/codex/skills/security-threat-hunting/SKILL.md +43 -0
- package/presets/codex/skills/security-vuln-assessment/SKILL.md +45 -0
- package/presets/codex/skills/security-web/SKILL.md +44 -0
- package/presets/codex/skills/seo-analytics-injector/SKILL.md +43 -0
- package/presets/codex/skills/spring-auth-auditor/SKILL.md +29 -0
- package/presets/codex/skills/spring-boot-feature/SKILL.md +2 -2
- package/presets/codex/skills/spring-boot-kotlin/SKILL.md +1 -1
- package/presets/codex/skills/spring-boot-testing-strategy/SKILL.md +475 -0
- package/presets/codex/skills/sqlalchemy/SKILL.md +1 -1
- package/presets/codex/skills/tailwind-responsive-auditor/SKILL.md +29 -0
- package/presets/codex/skills/tdd-mutation-tester/SKILL.md +27 -0
- package/presets/codex/skills/testing-strategy/SKILL.md +1 -1
- package/presets/cursor/commands/cc/api-contract.md +4 -5
- package/presets/cursor/commands/cc/backlog.md +4 -5
- package/presets/cursor/commands/cc/clarify.md +4 -5
- package/presets/cursor/commands/cc/council.md +4 -5
- package/presets/cursor/commands/cc/db-migration.md +4 -5
- package/presets/cursor/commands/cc/explore.md +4 -5
- package/presets/cursor/commands/cc/feature.md +4 -5
- package/presets/cursor/commands/cc/fix.md +4 -5
- package/presets/cursor/commands/cc/handoff.md +8 -5
- package/presets/cursor/commands/cc/iterative.md +4 -5
- package/presets/cursor/commands/cc/odd.md +4 -3
- package/presets/cursor/commands/cc/openspec.md +6 -7
- package/presets/cursor/commands/cc/pagespeed.md +6 -8
- package/presets/cursor/commands/cc/prototype.md +4 -5
- package/presets/cursor/commands/cc/refactor.md +4 -5
- package/presets/cursor/commands/cc/review.md +35 -5
- package/presets/cursor/commands/cc/scorecard.md +4 -5
- package/presets/cursor/commands/cc/security.md +5 -6
- package/presets/cursor/commands/cc/spec-mutation.md +4 -5
- package/presets/cursor/commands/cc/tdd-cycle.md +4 -5
- package/presets/cursor/commands/cc/test-plan.md +4 -5
- package/presets/cursor/commands/cc/triage.md +4 -5
- package/presets/cursor/skills/android/SKILL.md +1 -1
- package/presets/cursor/skills/api-versioning/SKILL.md +2 -1
- package/presets/cursor/skills/astro/SKILL.md +1 -1
- package/presets/cursor/skills/auth-token-inspector/SKILL.md +1 -1
- package/presets/cursor/skills/code-review/SKILL.md +1 -1
- package/presets/cursor/skills/django-orm/SKILL.md +3 -5
- package/presets/cursor/skills/django-testing/SKILL.md +1 -1
- package/presets/cursor/skills/django-uv/SKILL.md +1 -1
- package/presets/cursor/skills/drizzle-schema-architect/SKILL.md +1 -1
- package/presets/cursor/skills/fastapi-pydantic-strict/SKILL.md +1 -1
- package/presets/cursor/skills/jpa-nplusone-detector/SKILL.md +1 -1
- package/presets/cursor/skills/jpa-postgres/SKILL.md +2 -4
- package/presets/cursor/skills/livewire-alpine-bridge/SKILL.md +1 -1
- package/presets/cursor/skills/nextjs-typescript/SKILL.md +1 -1
- package/presets/cursor/skills/pagespeed-perf/SKILL.md +1 -1
- package/presets/cursor/skills/python/SKILL.md +6 -7
- package/presets/cursor/skills/python-django-stack/SKILL.md +1 -1
- package/presets/cursor/skills/python-fastapi-stack/SKILL.md +1 -1
- package/presets/cursor/skills/security/SKILL.md +1 -1
- package/presets/cursor/skills/seo-analytics-injector/SKILL.md +1 -1
- package/presets/cursor/skills/spring-auth-auditor/SKILL.md +1 -1
- package/presets/cursor/skills/spring-boot-feature/SKILL.md +2 -4
- package/presets/cursor/skills/spring-boot-kotlin/SKILL.md +1 -1
- package/presets/cursor/skills/spring-boot-testing-strategy/SKILL.md +1 -1
- package/presets/cursor/skills/sqlalchemy/SKILL.md +1 -1
- package/presets/cursor/skills/tailwind-responsive-auditor/SKILL.md +1 -1
- package/presets/cursor/skills/tdd-mutation-tester/SKILL.md +1 -1
- package/presets/gemini/commands/cc/api-contract.toml +4 -5
- package/presets/gemini/commands/cc/backlog.toml +4 -5
- package/presets/gemini/commands/cc/clarify.toml +4 -5
- package/presets/gemini/commands/cc/council.toml +4 -5
- package/presets/gemini/commands/cc/db-migration.toml +4 -5
- package/presets/gemini/commands/cc/explore.toml +4 -5
- package/presets/gemini/commands/cc/feature.toml +4 -5
- package/presets/gemini/commands/cc/fix.toml +4 -5
- package/presets/gemini/commands/cc/handoff.toml +8 -5
- package/presets/gemini/commands/cc/iterative.toml +4 -5
- package/presets/gemini/commands/cc/odd.toml +4 -3
- package/presets/gemini/commands/cc/openspec.toml +6 -7
- package/presets/gemini/commands/cc/pagespeed.toml +6 -8
- package/presets/gemini/commands/cc/prototype.toml +4 -5
- package/presets/gemini/commands/cc/refactor.toml +4 -5
- package/presets/gemini/commands/cc/review.toml +35 -5
- package/presets/gemini/commands/cc/scorecard.toml +4 -5
- package/presets/gemini/commands/cc/security.toml +5 -6
- package/presets/gemini/commands/cc/spec-mutation.toml +4 -5
- package/presets/gemini/commands/cc/tdd-cycle.toml +4 -5
- package/presets/gemini/commands/cc/test-plan.toml +4 -5
- package/presets/gemini/commands/cc/triage.toml +4 -5
- package/presets/opencode/README.md +45 -52
- package/presets/opencode/commands/cc-api-contract.md +4 -5
- package/presets/opencode/commands/cc-backlog.md +4 -5
- package/presets/opencode/commands/cc-clarify.md +4 -5
- package/presets/opencode/commands/cc-council.md +4 -5
- package/presets/opencode/commands/cc-db-migration.md +4 -5
- package/presets/opencode/commands/cc-explore.md +4 -5
- package/presets/opencode/commands/cc-feature.md +4 -5
- package/presets/opencode/commands/cc-fix.md +4 -5
- package/presets/opencode/commands/cc-handoff.md +8 -5
- package/presets/opencode/commands/cc-iterative.md +4 -5
- package/presets/opencode/commands/cc-odd.md +4 -3
- package/presets/opencode/commands/cc-openspec.md +6 -7
- package/presets/opencode/commands/cc-pagespeed.md +6 -8
- package/presets/opencode/commands/cc-prototype.md +4 -5
- package/presets/opencode/commands/cc-refactor.md +4 -5
- package/presets/opencode/commands/cc-review.md +35 -5
- package/presets/opencode/commands/cc-scorecard.md +4 -5
- package/presets/opencode/commands/cc-security.md +5 -6
- package/presets/opencode/commands/cc-spec-mutation.md +4 -5
- package/presets/opencode/commands/cc-tdd-cycle.md +4 -5
- package/presets/opencode/commands/cc-test-plan.md +4 -5
- package/presets/opencode/commands/cc-triage.md +4 -5
- package/presets/opencode/opencode.jsonc +1 -1
- package/presets/opencode/skills/android/SKILL.md +1 -1
- package/presets/opencode/skills/api-versioning/SKILL.md +2 -1
- package/presets/opencode/skills/astro/SKILL.md +1 -1
- package/presets/opencode/skills/auth-token-inspector/SKILL.md +1 -1
- package/presets/opencode/skills/code-review/SKILL.md +1 -1
- package/presets/opencode/skills/django-orm/SKILL.md +3 -3
- package/presets/opencode/skills/django-testing/SKILL.md +1 -1
- package/presets/opencode/skills/django-uv/SKILL.md +1 -1
- package/presets/opencode/skills/drizzle-schema-architect/SKILL.md +1 -1
- package/presets/opencode/skills/fastapi-pydantic-strict/SKILL.md +1 -1
- package/presets/opencode/skills/jpa-nplusone-detector/SKILL.md +1 -1
- package/presets/opencode/skills/jpa-postgres/SKILL.md +2 -1
- package/presets/opencode/skills/livewire-alpine-bridge/SKILL.md +1 -1
- package/presets/opencode/skills/nextjs-typescript/SKILL.md +1 -1
- package/presets/opencode/skills/pagespeed-perf/SKILL.md +1 -1
- package/presets/opencode/skills/python/SKILL.md +6 -5
- package/presets/opencode/skills/python-django-stack/SKILL.md +1 -1
- package/presets/opencode/skills/python-fastapi-stack/SKILL.md +1 -1
- package/presets/opencode/skills/security/SKILL.md +1 -1
- package/presets/opencode/skills/seo-analytics-injector/SKILL.md +1 -1
- package/presets/opencode/skills/spring-auth-auditor/SKILL.md +1 -1
- package/presets/opencode/skills/spring-boot-feature/SKILL.md +2 -1
- package/presets/opencode/skills/spring-boot-kotlin/SKILL.md +1 -1
- package/presets/opencode/skills/spring-boot-testing-strategy/SKILL.md +1 -1
- package/presets/opencode/skills/sqlalchemy/SKILL.md +1 -1
- package/presets/opencode/skills/tailwind-responsive-auditor/SKILL.md +1 -1
- package/presets/opencode/skills/tdd-mutation-tester/SKILL.md +1 -1
- package/presets/seo-hotel/skills/astro-seo/SKILL.md +1 -1
- package/presets/seo-hotel/skills/geo-readiness/SKILL.md +1 -1
- package/presets/seo-hotel/skills/off-page/SKILL.md +1 -1
- package/presets/seo-hotel/skills/schema-validator/SKILL.md +1 -1
- package/presets/seo-hotel/skills/seo-audit/SKILL.md +1 -1
- package/presets/shared/invoke-hook.cjs +20 -5
- package/src/presets/manifests/codex.yml +3 -0
- package/src/presets/models/roles.yml +54 -56
- package/src/presets/shared-skills.yml +58 -22
package/dist/index.js
CHANGED
|
@@ -72,7 +72,7 @@ var package_default;
|
|
|
72
72
|
var init_package = __esm(() => {
|
|
73
73
|
package_default = {
|
|
74
74
|
name: "cc-codeconductor",
|
|
75
|
-
version: "1.
|
|
75
|
+
version: "1.5.1",
|
|
76
76
|
description: "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
|
|
77
77
|
keywords: [
|
|
78
78
|
"ai",
|
|
@@ -11216,9 +11216,11 @@ __export(exports_schemas, {
|
|
|
11216
11216
|
ExecutionContextSchema: () => ExecutionContextSchema,
|
|
11217
11217
|
ExecutionProfileNameSchema: () => ExecutionProfileNameSchema,
|
|
11218
11218
|
ExecutionProfileSchema: () => ExecutionProfileSchema,
|
|
11219
|
+
FixIntakeOutputSchema: () => FixIntakeOutputSchema,
|
|
11219
11220
|
GoalGraphSchema: () => GoalGraphSchema,
|
|
11220
11221
|
GoalTaskSchema: () => GoalTaskSchema,
|
|
11221
11222
|
GraphRelationSchema: () => GraphRelationSchema,
|
|
11223
|
+
HandoffEnvelopeSchema: () => HandoffEnvelopeSchema,
|
|
11222
11224
|
HarnessCatalogEntrySchema: () => HarnessCatalogEntrySchema,
|
|
11223
11225
|
HarnessCatalogSchema: () => HarnessCatalogSchema,
|
|
11224
11226
|
HarnessComponentIdSchema: () => HarnessComponentIdSchema,
|
|
@@ -11439,7 +11441,7 @@ function validateProductEvent(data) {
|
|
|
11439
11441
|
function validateSkillsRegistry(data) {
|
|
11440
11442
|
return SkillsRegistrySchema.parse(data);
|
|
11441
11443
|
}
|
|
11442
|
-
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, DeliveryRouteSchema, TokenUsageSchema, DeliveryTelemetrySchema, DeliveryLedgerTaskSchema, DeliveryLedgerSchema, DeliveryLedgerRequestSchema, TaskOutcomeSchema, HarnessComponentIdSchema, HarnessComponentLayerSchema, HarnessToggleKindSchema, HarnessCatalogEntrySchema, HarnessCatalogSchema, HarnessOverlaySchema, HarnessExperimentSchema, HarnessSuiteTaskSchema, HarnessSuiteSchema, EvaluationIndexSchema, ExecutionProfileNameSchema, ExecutionProfileSchema, SkillsRegistrySchema;
|
|
11444
|
+
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, FixIntakeOutputSchema, ScorecardVerdictSchema, ScorecardCriterionIdSchema, ScorecardCriterionSchema, ScorecardRecordSchema, TaskOutcomeSourceSchema, TaskOutcomeStatusSchema, DeliveryRouteSchema, TokenUsageSchema, DeliveryTelemetrySchema, DeliveryLedgerTaskSchema, DeliveryLedgerSchema, HandoffEnvelopeSchema, RepoRelativePathSchema, DeliveryLedgerRequestSchema, TaskOutcomeSchema, HarnessComponentIdSchema, HarnessComponentLayerSchema, HarnessToggleKindSchema, HarnessCatalogEntrySchema, HarnessCatalogSchema, HarnessOverlaySchema, HarnessExperimentSchema, HarnessSuiteTaskSchema, HarnessSuiteSchema, EvaluationIndexSchema, ExecutionProfileNameSchema, ExecutionProfileSchema, SkillsRegistrySchema;
|
|
11443
11445
|
var init_schemas = __esm(() => {
|
|
11444
11446
|
init_zod();
|
|
11445
11447
|
init_runner_target();
|
|
@@ -11517,6 +11519,7 @@ var init_schemas = __esm(() => {
|
|
|
11517
11519
|
"append",
|
|
11518
11520
|
"merge-json",
|
|
11519
11521
|
"merge-managed",
|
|
11522
|
+
"create-only",
|
|
11520
11523
|
"skip"
|
|
11521
11524
|
]);
|
|
11522
11525
|
ManifestEntrySchema = exports_external.object({
|
|
@@ -11821,7 +11824,8 @@ var init_schemas = __esm(() => {
|
|
|
11821
11824
|
"goal.updated",
|
|
11822
11825
|
"blocker.detected",
|
|
11823
11826
|
"verification.completed",
|
|
11824
|
-
"feedback.processed"
|
|
11827
|
+
"feedback.processed",
|
|
11828
|
+
"context.compiled"
|
|
11825
11829
|
]);
|
|
11826
11830
|
ProductEventSchema = exports_external.object({
|
|
11827
11831
|
id: exports_external.string(),
|
|
@@ -12166,6 +12170,11 @@ var init_schemas = __esm(() => {
|
|
|
12166
12170
|
risks: exports_external.array(exports_external.string()).default([]),
|
|
12167
12171
|
openQuestions: exports_external.array(exports_external.string()).optional()
|
|
12168
12172
|
});
|
|
12173
|
+
FixIntakeOutputSchema = exports_external.object({
|
|
12174
|
+
actualBehavior: exports_external.string(),
|
|
12175
|
+
expectedBehavior: exports_external.string(),
|
|
12176
|
+
reproductionSteps: exports_external.array(exports_external.string())
|
|
12177
|
+
});
|
|
12169
12178
|
ScorecardVerdictSchema = exports_external.enum(["PASS", "REVISE", "REJECT"]);
|
|
12170
12179
|
ScorecardCriterionIdSchema = exports_external.enum([
|
|
12171
12180
|
"acceptance",
|
|
@@ -12237,16 +12246,51 @@ var init_schemas = __esm(() => {
|
|
|
12237
12246
|
nextStep: exports_external.string().min(1),
|
|
12238
12247
|
memoryTopicKey: exports_external.string().min(1),
|
|
12239
12248
|
workspace: exports_external.record(exports_external.string(), exports_external.string()),
|
|
12249
|
+
technicalPlanPath: exports_external.string().min(1).optional(),
|
|
12240
12250
|
createdAt: exports_external.string().datetime(),
|
|
12241
12251
|
updatedAt: exports_external.string().datetime()
|
|
12242
12252
|
});
|
|
12253
|
+
HandoffEnvelopeSchema = exports_external.object({
|
|
12254
|
+
version: exports_external.literal(1),
|
|
12255
|
+
task: exports_external.object({
|
|
12256
|
+
id: exports_external.string().min(1),
|
|
12257
|
+
objective: exports_external.string().min(1),
|
|
12258
|
+
acceptanceCriteria: exports_external.array(exports_external.string().min(1)),
|
|
12259
|
+
status: CanonicalTaskCardStatusSchema
|
|
12260
|
+
}),
|
|
12261
|
+
decisions: exports_external.object({
|
|
12262
|
+
constraints: exports_external.array(exports_external.string()),
|
|
12263
|
+
unresolved: exports_external.array(exports_external.string())
|
|
12264
|
+
}),
|
|
12265
|
+
scope: exports_external.object({
|
|
12266
|
+
relevantFiles: exports_external.array(exports_external.string()),
|
|
12267
|
+
boundaries: exports_external.array(exports_external.string())
|
|
12268
|
+
}),
|
|
12269
|
+
verification: exports_external.object({
|
|
12270
|
+
evidence: exports_external.array(exports_external.string())
|
|
12271
|
+
}),
|
|
12272
|
+
change: exports_external.object({
|
|
12273
|
+
touchedFiles: exports_external.array(exports_external.string())
|
|
12274
|
+
}),
|
|
12275
|
+
next: exports_external.object({
|
|
12276
|
+
role: exports_external.string().min(1),
|
|
12277
|
+
objective: exports_external.string().min(1)
|
|
12278
|
+
}),
|
|
12279
|
+
sources: exports_external.object({
|
|
12280
|
+
deliveryLedger: exports_external.string().min(1),
|
|
12281
|
+
memoryTopicKey: exports_external.string().min(1),
|
|
12282
|
+
technicalPlanPath: exports_external.string().min(1).optional()
|
|
12283
|
+
})
|
|
12284
|
+
});
|
|
12285
|
+
RepoRelativePathSchema = exports_external.string().min(1).refine((path) => !/^([/\\]|[A-Za-z]:)/.test(path) && !path.split(/[/\\]/).includes(".."), 'Path must be relative to the repository and must not contain ".." segments');
|
|
12243
12286
|
DeliveryLedgerRequestSchema = exports_external.object({
|
|
12244
12287
|
id: exports_external.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/),
|
|
12245
12288
|
authorized: exports_external.boolean(),
|
|
12246
12289
|
route: DeliveryRouteSchema,
|
|
12247
12290
|
taskCard: CanonicalTaskCardSchema,
|
|
12248
12291
|
tasks: exports_external.array(DeliveryLedgerTaskSchema).min(1),
|
|
12249
|
-
nextStep: exports_external.string().min(1)
|
|
12292
|
+
nextStep: exports_external.string().min(1),
|
|
12293
|
+
technicalPlanPath: RepoRelativePathSchema.optional()
|
|
12250
12294
|
});
|
|
12251
12295
|
TaskOutcomeSchema = exports_external.object({
|
|
12252
12296
|
id: exports_external.string(),
|
|
@@ -12989,18 +13033,19 @@ var init_path_containment = __esm(() => {
|
|
|
12989
13033
|
});
|
|
12990
13034
|
|
|
12991
13035
|
// src/core/presets/complementary-detector.ts
|
|
12992
|
-
import {
|
|
13036
|
+
import { execFile } from "node:child_process";
|
|
12993
13037
|
import { existsSync, readFileSync } from "node:fs";
|
|
12994
13038
|
import { join as join3 } from "node:path";
|
|
12995
13039
|
import { homedir } from "node:os";
|
|
12996
|
-
|
|
13040
|
+
import { promisify } from "node:util";
|
|
13041
|
+
async function detectComplementaryTools() {
|
|
12997
13042
|
if (cachedStatus) {
|
|
12998
13043
|
return cachedStatus;
|
|
12999
13044
|
}
|
|
13000
|
-
const isCmdAvailable = (cmd) => {
|
|
13045
|
+
const isCmdAvailable = async (cmd) => {
|
|
13001
13046
|
try {
|
|
13002
13047
|
const binary = process.platform === "win32" ? "where" : "which";
|
|
13003
|
-
|
|
13048
|
+
await execFileAsync(binary, [cmd], { timeout: 1000 });
|
|
13004
13049
|
return true;
|
|
13005
13050
|
} catch {
|
|
13006
13051
|
return false;
|
|
@@ -13029,18 +13074,28 @@ function detectComplementaryTools() {
|
|
|
13029
13074
|
} catch {}
|
|
13030
13075
|
return false;
|
|
13031
13076
|
};
|
|
13077
|
+
const [rtk, codeReviewGraph, tokenSavior, tokenSaviorRecall, engram, gentleAi] = await Promise.all([
|
|
13078
|
+
isCmdAvailable("rtk"),
|
|
13079
|
+
isCmdAvailable("code-review-graph"),
|
|
13080
|
+
isCmdAvailable("token-savior"),
|
|
13081
|
+
isCmdAvailable("token-savior-recall"),
|
|
13082
|
+
isCmdAvailable("engram"),
|
|
13083
|
+
isCmdAvailable("gentle-ai")
|
|
13084
|
+
]);
|
|
13032
13085
|
cachedStatus = {
|
|
13033
|
-
rtk
|
|
13034
|
-
codeReviewGraph
|
|
13035
|
-
tokenSavior:
|
|
13086
|
+
rtk,
|
|
13087
|
+
codeReviewGraph,
|
|
13088
|
+
tokenSavior: tokenSavior || tokenSaviorRecall,
|
|
13036
13089
|
caveman: hasCaveman(),
|
|
13037
|
-
engram
|
|
13038
|
-
gentleAi
|
|
13090
|
+
engram,
|
|
13091
|
+
gentleAi
|
|
13039
13092
|
};
|
|
13040
13093
|
return cachedStatus;
|
|
13041
13094
|
}
|
|
13042
|
-
var cachedStatus = null;
|
|
13043
|
-
var init_complementary_detector = () => {
|
|
13095
|
+
var execFileAsync, cachedStatus = null;
|
|
13096
|
+
var init_complementary_detector = __esm(() => {
|
|
13097
|
+
execFileAsync = promisify(execFile);
|
|
13098
|
+
});
|
|
13044
13099
|
|
|
13045
13100
|
// src/core/presets/file-copier.ts
|
|
13046
13101
|
import { lstat as lstat2, readdir, readFile as readFile4, stat } from "node:fs/promises";
|
|
@@ -13133,9 +13188,9 @@ function extractAgentRole(filePath) {
|
|
|
13133
13188
|
];
|
|
13134
13189
|
return knownRoles.includes(name) ? name : null;
|
|
13135
13190
|
}
|
|
13136
|
-
function renderTemplate(content, modelConfig, filePath, locale = "en") {
|
|
13191
|
+
async function renderTemplate(content, modelConfig, filePath, locale = "en") {
|
|
13137
13192
|
const cleanLocale = locale === "es" || locale === "en" ? locale : "en";
|
|
13138
|
-
const tools = detectComplementaryTools();
|
|
13193
|
+
const tools = await detectComplementaryTools();
|
|
13139
13194
|
let complementaryRules = "";
|
|
13140
13195
|
if (cleanLocale === "es") {
|
|
13141
13196
|
if (tools.rtk) {
|
|
@@ -13258,7 +13313,7 @@ function substituteToolNames(content, modelConfig) {
|
|
|
13258
13313
|
const eol = fmMatch[1];
|
|
13259
13314
|
const frontmatter = fmMatch[2];
|
|
13260
13315
|
if (target === "opencode" && modelConfig.permissions) {
|
|
13261
|
-
const updatedFrontmatter2 = frontmatter.replace(/^tools:\s*(.+)\r?\n?/m, "");
|
|
13316
|
+
const updatedFrontmatter2 = frontmatter.replace(/^tools:\s*(.+)\r?\n?/m, "").replace(/^(?:temperature|effort):[^\r\n]*\r?\n?/gm, "");
|
|
13262
13317
|
return content.replace(fmMatch[0], `---${eol}${updatedFrontmatter2}${eol}---`);
|
|
13263
13318
|
}
|
|
13264
13319
|
if (!modelConfig.tools)
|
|
@@ -13276,11 +13331,10 @@ function substituteToolNames(content, modelConfig) {
|
|
|
13276
13331
|
});
|
|
13277
13332
|
return content.replace(fmMatch[0], `---${eol}${updatedFrontmatter}${eol}---`);
|
|
13278
13333
|
}
|
|
13279
|
-
function injectMcpServers(jsonString, filePath) {
|
|
13334
|
+
async function injectMcpServers(jsonString, filePath) {
|
|
13280
13335
|
const isAgyMcpConfig = filePath.endsWith("mcp_config.json");
|
|
13281
|
-
const isClaudeSettings = filePath.endsWith("settings.json");
|
|
13282
13336
|
const isOpencodeJsonc = filePath.endsWith("opencode.jsonc") || filePath.endsWith("opencode.json");
|
|
13283
|
-
if (!isAgyMcpConfig && !
|
|
13337
|
+
if (!isAgyMcpConfig && !isOpencodeJsonc) {
|
|
13284
13338
|
return jsonString;
|
|
13285
13339
|
}
|
|
13286
13340
|
try {
|
|
@@ -13289,13 +13343,13 @@ function injectMcpServers(jsonString, filePath) {
|
|
|
13289
13343
|
cleanJson = jsonString.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "$1");
|
|
13290
13344
|
}
|
|
13291
13345
|
const obj = JSON.parse(cleanJson);
|
|
13292
|
-
const tools = detectComplementaryTools();
|
|
13346
|
+
const tools = await detectComplementaryTools();
|
|
13293
13347
|
const mcpServers = {};
|
|
13294
13348
|
if (tools.tokenSavior) {
|
|
13295
13349
|
mcpServers["token-savior-recall"] = {
|
|
13296
13350
|
command: "token-savior",
|
|
13297
13351
|
env: {
|
|
13298
|
-
TOKEN_SAVIOR_CLIENT:
|
|
13352
|
+
TOKEN_SAVIOR_CLIENT: isOpencodeJsonc ? "opencode" : "agy"
|
|
13299
13353
|
}
|
|
13300
13354
|
};
|
|
13301
13355
|
}
|
|
@@ -13308,7 +13362,7 @@ function injectMcpServers(jsonString, filePath) {
|
|
|
13308
13362
|
if (Object.keys(mcpServers).length === 0) {
|
|
13309
13363
|
return jsonString;
|
|
13310
13364
|
}
|
|
13311
|
-
if (
|
|
13365
|
+
if (isAgyMcpConfig) {
|
|
13312
13366
|
obj.mcpServers = mergeDeep(obj.mcpServers || {}, mcpServers);
|
|
13313
13367
|
} else if (isOpencodeJsonc) {
|
|
13314
13368
|
const opencodeMcp = {};
|
|
@@ -13352,7 +13406,7 @@ async function applySingleFile(srcPath, destPath, strategy, force, dryRun, isTem
|
|
|
13352
13406
|
return { src: srcPath, dest: destPath, action: "error", error: String(error) };
|
|
13353
13407
|
}
|
|
13354
13408
|
}
|
|
13355
|
-
if (strategy === "overwrite" && !force && await fileExists2(destPath)) {
|
|
13409
|
+
if ((strategy === "overwrite" && !force || strategy === "create-only") && await fileExists2(destPath)) {
|
|
13356
13410
|
return { src: srcPath, dest: destPath, action: "skipped", dryRun };
|
|
13357
13411
|
}
|
|
13358
13412
|
let content;
|
|
@@ -13361,8 +13415,8 @@ async function applySingleFile(srcPath, destPath, strategy, force, dryRun, isTem
|
|
|
13361
13415
|
} catch (e) {
|
|
13362
13416
|
return { src: srcPath, dest: destPath, action: "error", error: `Cannot read source: ${e}` };
|
|
13363
13417
|
}
|
|
13364
|
-
let incomingContent = isTemplate && modelConfig ? renderTemplate(content, modelConfig, srcPath, locale) : content;
|
|
13365
|
-
incomingContent = injectMcpServers(incomingContent, destPath);
|
|
13418
|
+
let incomingContent = isTemplate && modelConfig ? await renderTemplate(content, modelConfig, srcPath, locale) : content;
|
|
13419
|
+
incomingContent = await injectMcpServers(incomingContent, destPath);
|
|
13366
13420
|
let finalContent = incomingContent;
|
|
13367
13421
|
let action = "written";
|
|
13368
13422
|
if (strategy === "append") {
|
|
@@ -13993,6 +14047,11 @@ ${spec.agents.map((a) => `- **${a.role}** (${a.id}): ${a.focus.join(", ")}`).joi
|
|
|
13993
14047
|
|
|
13994
14048
|
## Usage
|
|
13995
14049
|
Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
|
|
14050
|
+
Use Sonnet 5.5 for the routine council pass. Share one concise evidence summary and
|
|
14051
|
+
the relevant diff with the necessary roles. Invoke council-architect with
|
|
14052
|
+
\`model: opus\` only for
|
|
14053
|
+
one unresolved business-logic question; return its short decision to Sonnet for
|
|
14054
|
+
the verdict. Do not run every council role on Opus or repeat full context.
|
|
13996
14055
|
|
|
13997
14056
|
## Context
|
|
13998
14057
|
${spec.outputContract}
|
|
@@ -14107,7 +14166,8 @@ function generateCodexFiles(spec) {
|
|
|
14107
14166
|
files.push({
|
|
14108
14167
|
path: ".codex/config.toml",
|
|
14109
14168
|
content: generateCodexConfig(spec),
|
|
14110
|
-
overwrite: false
|
|
14169
|
+
overwrite: false,
|
|
14170
|
+
mergeExisting: (existing) => mergeCodexCouncilConfig(existing, spec)
|
|
14111
14171
|
});
|
|
14112
14172
|
for (const agent of spec.agents) {
|
|
14113
14173
|
files.push({
|
|
@@ -14123,17 +14183,32 @@ function generateCodexFiles(spec) {
|
|
|
14123
14183
|
});
|
|
14124
14184
|
return files;
|
|
14125
14185
|
}
|
|
14126
|
-
function
|
|
14127
|
-
const
|
|
14128
|
-
|
|
14129
|
-
return `
|
|
14186
|
+
function agentTable(agent) {
|
|
14187
|
+
const focusAreas = agent.focus.join(", ");
|
|
14188
|
+
return `
|
|
14130
14189
|
[agents.${agent.id}]
|
|
14131
14190
|
description = "${agent.role} council agent. Focus: ${focusAreas}. Context: ${agent.context}. Model hint: ${agent.modelHint}."
|
|
14191
|
+
config_file = "agents/council_${agent.id}.toml"
|
|
14132
14192
|
nickname_candidates = ["${agent.role}", "Council ${agent.role}"]`;
|
|
14133
|
-
|
|
14193
|
+
}
|
|
14194
|
+
function mergeCodexCouncilConfig(existing, spec) {
|
|
14195
|
+
const missing = spec.agents.filter((agent) => !existing.split(`
|
|
14196
|
+
`).some((line) => line.trim() === `[agents.${agent.id}]`));
|
|
14197
|
+
if (missing.length === 0)
|
|
14198
|
+
return existing;
|
|
14199
|
+
return `${existing.trimEnd()}
|
|
14200
|
+
${missing.map(agentTable).join(`
|
|
14201
|
+
`)}
|
|
14202
|
+
`;
|
|
14203
|
+
}
|
|
14204
|
+
function generateCodexConfig(spec) {
|
|
14205
|
+
const agentTables = spec.agents.map(agentTable).join(`
|
|
14134
14206
|
`);
|
|
14135
14207
|
return `# Codex Council Configuration
|
|
14136
14208
|
|
|
14209
|
+
model = "gpt-6.1-sol"
|
|
14210
|
+
model_reasoning_effort = "medium"
|
|
14211
|
+
|
|
14137
14212
|
[project]
|
|
14138
14213
|
name = "council"
|
|
14139
14214
|
version = "${spec.version}"
|
|
@@ -14143,7 +14218,9 @@ ${agentTables}
|
|
|
14143
14218
|
function generateCodexAgent(agent) {
|
|
14144
14219
|
const focusAreas = agent.focus.join(", ");
|
|
14145
14220
|
const checklist = checklistFor(agent.id).join("; ");
|
|
14146
|
-
return `
|
|
14221
|
+
return `model = "gpt-6.1-sol"
|
|
14222
|
+
model_reasoning_effort = "medium"
|
|
14223
|
+
name = "${agent.role}"
|
|
14147
14224
|
description = "${agent.role} council agent. Focus: ${focusAreas}. Context: ${agent.context}. Model hint: ${agent.modelHint}."
|
|
14148
14225
|
nickname_candidates = ["${agent.role}", "Council ${agent.role}"]
|
|
14149
14226
|
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."
|
|
@@ -14162,6 +14239,9 @@ ${spec.agents.map((a) => `- **${a.role}** (${a.id}): ${a.focus.join(", ")}`).joi
|
|
|
14162
14239
|
|
|
14163
14240
|
## Usage
|
|
14164
14241
|
Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
|
|
14242
|
+
Keep GPT-6.1 Sol at medium reasoning effort. Share a concise evidence summary
|
|
14243
|
+
and relevant diff with only the necessary council roles. Reuse findings in the
|
|
14244
|
+
final verdict instead of replaying the full transcript or repeating analysis.
|
|
14165
14245
|
`;
|
|
14166
14246
|
}
|
|
14167
14247
|
var init_codex_council_generator = __esm(() => {
|
|
@@ -14629,7 +14709,7 @@ async function checkUpdates(basePath, isGlobal, includeConflicts = false) {
|
|
|
14629
14709
|
let expectedContent;
|
|
14630
14710
|
try {
|
|
14631
14711
|
const srcContent = await readFile7(src, "utf-8");
|
|
14632
|
-
expectedContent = isTemplate && modelConfig ? renderTemplate(srcContent, modelConfig, src, locale) : srcContent;
|
|
14712
|
+
expectedContent = isTemplate && modelConfig ? await renderTemplate(srcContent, modelConfig, src, locale) : srcContent;
|
|
14633
14713
|
} catch {
|
|
14634
14714
|
continue;
|
|
14635
14715
|
}
|
|
@@ -14714,7 +14794,8 @@ async function checkUpdates(basePath, isGlobal, includeConflicts = false) {
|
|
|
14714
14794
|
let destContent;
|
|
14715
14795
|
try {
|
|
14716
14796
|
destContent = await readFile7(dest, "utf-8");
|
|
14717
|
-
|
|
14797
|
+
const expected = f.mergeExisting ? f.mergeExisting(destContent) : f.content;
|
|
14798
|
+
if (destContent.trim() !== expected.trim()) {
|
|
14718
14799
|
changedFiles.push(dest);
|
|
14719
14800
|
}
|
|
14720
14801
|
} catch {
|
|
@@ -15091,7 +15172,7 @@ async function doctorCommand(options) {
|
|
|
15091
15172
|
message: "No product graph yet. Run `codeconductor ingest` to build product memory."
|
|
15092
15173
|
});
|
|
15093
15174
|
}
|
|
15094
|
-
const compTools = detectComplementaryTools();
|
|
15175
|
+
const compTools = await detectComplementaryTools();
|
|
15095
15176
|
const toolDetails = [
|
|
15096
15177
|
{ name: "rtk", key: "rtk", label: "RTK", desc: "Run `brew install rtk` to compress command outputs" },
|
|
15097
15178
|
{ name: "code-review-graph", key: "codeReviewGraph", label: "code-review-graph", desc: "Run `pipx install code-review-graph` to navigate symbol graph" },
|
|
@@ -16899,7 +16980,7 @@ __export(exports_file_writer, {
|
|
|
16899
16980
|
writeGeneratedFiles: () => writeGeneratedFiles,
|
|
16900
16981
|
writeSingleFile: () => writeSingleFile
|
|
16901
16982
|
});
|
|
16902
|
-
import { access as access5 } from "node:fs/promises";
|
|
16983
|
+
import { access as access5, readFile as readFile11 } from "node:fs/promises";
|
|
16903
16984
|
import { relative as relative4 } from "node:path";
|
|
16904
16985
|
async function writeGeneratedFiles(files, options) {
|
|
16905
16986
|
const results = [];
|
|
@@ -16926,7 +17007,15 @@ async function writeGeneratedFiles(files, options) {
|
|
|
16926
17007
|
});
|
|
16927
17008
|
continue;
|
|
16928
17009
|
}
|
|
16929
|
-
|
|
17010
|
+
let content = file.content;
|
|
17011
|
+
let merged = false;
|
|
17012
|
+
if (file.mergeExisting) {
|
|
17013
|
+
try {
|
|
17014
|
+
content = file.mergeExisting(await readFile11(file.path, "utf-8"));
|
|
17015
|
+
merged = true;
|
|
17016
|
+
} catch {}
|
|
17017
|
+
}
|
|
17018
|
+
if (!options.force && !merged) {
|
|
16930
17019
|
try {
|
|
16931
17020
|
await access5(file.path);
|
|
16932
17021
|
results.push({
|
|
@@ -16946,7 +17035,7 @@ async function writeGeneratedFiles(files, options) {
|
|
|
16946
17035
|
continue;
|
|
16947
17036
|
}
|
|
16948
17037
|
try {
|
|
16949
|
-
await writeContainedFile(options.projectRoot, relative4(options.projectRoot, file.path),
|
|
17038
|
+
await writeContainedFile(options.projectRoot, relative4(options.projectRoot, file.path), content, { force: true });
|
|
16950
17039
|
results.push({
|
|
16951
17040
|
path: file.path,
|
|
16952
17041
|
success: true
|
|
@@ -16986,7 +17075,7 @@ __export(exports_install_command, {
|
|
|
16986
17075
|
installPresetCommand: () => installPresetCommand,
|
|
16987
17076
|
verifyRenderedFiles: () => verifyRenderedFiles
|
|
16988
17077
|
});
|
|
16989
|
-
import { readFile as
|
|
17078
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
16990
17079
|
import { homedir as homedir7 } from "node:os";
|
|
16991
17080
|
import { basename as basename5, dirname as dirname6, resolve as resolve12, sep as sep3 } from "node:path";
|
|
16992
17081
|
async function installCommand(options) {
|
|
@@ -17119,7 +17208,7 @@ async function verifyRenderedFiles(manifest, baseDir, results) {
|
|
|
17119
17208
|
continue;
|
|
17120
17209
|
let content;
|
|
17121
17210
|
try {
|
|
17122
|
-
content = await
|
|
17211
|
+
content = await readFile12(r.dest, "utf-8");
|
|
17123
17212
|
} catch {
|
|
17124
17213
|
continue;
|
|
17125
17214
|
}
|
|
@@ -18373,13 +18462,13 @@ var init_binary_downloader = __esm(() => {
|
|
|
18373
18462
|
});
|
|
18374
18463
|
|
|
18375
18464
|
// src/core/lsp/lsp-installer.ts
|
|
18376
|
-
import { execFile } from "node:child_process";
|
|
18465
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
18377
18466
|
import { access as access6, mkdir as mkdir6, mkdtemp, rename as rename2, rm, writeFile as writeFile5 } from "node:fs/promises";
|
|
18378
18467
|
import { homedir as homedir8, tmpdir } from "node:os";
|
|
18379
18468
|
import { join as join9 } from "node:path";
|
|
18380
|
-
import { promisify } from "node:util";
|
|
18469
|
+
import { promisify as promisify2 } from "node:util";
|
|
18381
18470
|
async function assertTarArchiveSafe(archivePath, destRoot) {
|
|
18382
|
-
const { stdout } = await
|
|
18471
|
+
const { stdout } = await execFileAsync2("tar", ["-tzf", archivePath], {
|
|
18383
18472
|
timeout: 60000,
|
|
18384
18473
|
maxBuffer: 10 * 1024 * 1024
|
|
18385
18474
|
});
|
|
@@ -18391,7 +18480,7 @@ async function assertTarArchiveSafe(archivePath, destRoot) {
|
|
|
18391
18480
|
}
|
|
18392
18481
|
async function extractHardenedTar(archivePath, destRoot) {
|
|
18393
18482
|
await assertTarArchiveSafe(archivePath, destRoot);
|
|
18394
|
-
await
|
|
18483
|
+
await execFileAsync2("tar", ["-xzf", archivePath, "-C", destRoot, ...TAR_EXTRACT_HARDENING_FLAGS], { timeout: 120000 });
|
|
18395
18484
|
}
|
|
18396
18485
|
|
|
18397
18486
|
class LspInstaller {
|
|
@@ -18401,7 +18490,7 @@ class LspInstaller {
|
|
|
18401
18490
|
}
|
|
18402
18491
|
async checkInstalled(def) {
|
|
18403
18492
|
try {
|
|
18404
|
-
const { stdout } = await
|
|
18493
|
+
const { stdout } = await execFileAsync2("which", [def.binaryName], { timeout: 5000 });
|
|
18405
18494
|
const path = stdout.trim();
|
|
18406
18495
|
if (path) {
|
|
18407
18496
|
const version = await this.getVersion(def);
|
|
@@ -18410,7 +18499,7 @@ class LspInstaller {
|
|
|
18410
18499
|
} catch {}
|
|
18411
18500
|
if (def.packageManager === "npm" && def.npmDetect) {
|
|
18412
18501
|
try {
|
|
18413
|
-
const { stdout } = await
|
|
18502
|
+
const { stdout } = await execFileAsync2("npm", ["list", "-g", def.npmDetect, "--depth=0"], { timeout: 1e4 });
|
|
18414
18503
|
if (stdout.includes(def.npmDetect)) {
|
|
18415
18504
|
const version = this.parseVersionFromNpmList(stdout, def.npmDetect);
|
|
18416
18505
|
return { installed: true, version };
|
|
@@ -18419,7 +18508,7 @@ class LspInstaller {
|
|
|
18419
18508
|
}
|
|
18420
18509
|
if (def.packageManager === "pip" && def.pipDetect) {
|
|
18421
18510
|
try {
|
|
18422
|
-
const { stdout } = await
|
|
18511
|
+
const { stdout } = await execFileAsync2("pip", ["show", def.pipDetect], { timeout: 1e4 });
|
|
18423
18512
|
if (stdout.includes("Version:")) {
|
|
18424
18513
|
const version = this.parseVersionFromPipShow(stdout);
|
|
18425
18514
|
return { installed: true, version };
|
|
@@ -18483,7 +18572,7 @@ class LspInstaller {
|
|
|
18483
18572
|
}
|
|
18484
18573
|
async getVersion(def) {
|
|
18485
18574
|
try {
|
|
18486
|
-
const { stdout } = await
|
|
18575
|
+
const { stdout } = await execFileAsync2(def.binaryName, [def.versionFlag], { timeout: 5000 });
|
|
18487
18576
|
return stdout.trim().split(`
|
|
18488
18577
|
`)[0];
|
|
18489
18578
|
} catch {
|
|
@@ -18501,7 +18590,7 @@ class LspInstaller {
|
|
|
18501
18590
|
async installNpm(def) {
|
|
18502
18591
|
assertPinnedPackage(def);
|
|
18503
18592
|
try {
|
|
18504
|
-
await
|
|
18593
|
+
await execFileAsync2("npm", ["install", "-g", def.package], { timeout: 120000 });
|
|
18505
18594
|
} catch (error) {
|
|
18506
18595
|
throw new Error(`Failed to install ${def.serverName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
18507
18596
|
}
|
|
@@ -18509,7 +18598,7 @@ class LspInstaller {
|
|
|
18509
18598
|
async installPip(def) {
|
|
18510
18599
|
assertPinnedPackage(def);
|
|
18511
18600
|
try {
|
|
18512
|
-
await
|
|
18601
|
+
await execFileAsync2("pip", ["install", "--user", def.package], { timeout: 120000 });
|
|
18513
18602
|
} catch (error) {
|
|
18514
18603
|
throw new Error(`Failed to install ${def.serverName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
18515
18604
|
}
|
|
@@ -18551,7 +18640,7 @@ class LspInstaller {
|
|
|
18551
18640
|
await access6(candidate);
|
|
18552
18641
|
await rename2(candidate, destPath);
|
|
18553
18642
|
} catch {
|
|
18554
|
-
const { stdout: found } = await
|
|
18643
|
+
const { stdout: found } = await execFileAsync2("find", [workDir, "-type", "f", "-name", def.binaryName], { timeout: 30000 });
|
|
18555
18644
|
const first = found.split(`
|
|
18556
18645
|
`).map((l) => l.trim()).find((l) => l.length > 0);
|
|
18557
18646
|
if (!first) {
|
|
@@ -18561,7 +18650,7 @@ class LspInstaller {
|
|
|
18561
18650
|
await rename2(first, destPath);
|
|
18562
18651
|
}
|
|
18563
18652
|
if (process.platform !== "win32") {
|
|
18564
|
-
await
|
|
18653
|
+
await execFileAsync2("chmod", ["+x", destPath], { timeout: 5000 });
|
|
18565
18654
|
}
|
|
18566
18655
|
} finally {
|
|
18567
18656
|
await rm(workDir, { recursive: true, force: true });
|
|
@@ -18571,11 +18660,11 @@ class LspInstaller {
|
|
|
18571
18660
|
function createLspInstaller() {
|
|
18572
18661
|
return new LspInstaller;
|
|
18573
18662
|
}
|
|
18574
|
-
var
|
|
18663
|
+
var execFileAsync2, TAR_EXTRACT_HARDENING_FLAGS;
|
|
18575
18664
|
var init_lsp_installer = __esm(() => {
|
|
18576
18665
|
init_binary_integrity();
|
|
18577
18666
|
init_binary_downloader();
|
|
18578
|
-
|
|
18667
|
+
execFileAsync2 = promisify2(execFile2);
|
|
18579
18668
|
TAR_EXTRACT_HARDENING_FLAGS = [
|
|
18580
18669
|
"--no-same-owner",
|
|
18581
18670
|
"--no-same-permissions"
|
|
@@ -18824,7 +18913,7 @@ var init_install_lsp_command = __esm(() => {
|
|
|
18824
18913
|
});
|
|
18825
18914
|
|
|
18826
18915
|
// src/core/install/update-transaction.ts
|
|
18827
|
-
import { mkdir as mkdir7, readFile as
|
|
18916
|
+
import { mkdir as mkdir7, readFile as readFile13, rm as rm2, unlink, writeFile as writeFile6 } from "node:fs/promises";
|
|
18828
18917
|
import { dirname as dirname7, join as join10, relative as relative5, resolve as resolve16 } from "node:path";
|
|
18829
18918
|
|
|
18830
18919
|
class UpdateTransaction {
|
|
@@ -18841,7 +18930,7 @@ class UpdateTransaction {
|
|
|
18841
18930
|
const snapshots = [];
|
|
18842
18931
|
for (const destination of unique) {
|
|
18843
18932
|
try {
|
|
18844
|
-
const content = await
|
|
18933
|
+
const content = await readFile13(destination);
|
|
18845
18934
|
snapshots.push({ path: destination, existed: true, content });
|
|
18846
18935
|
const backupPath = join10(backupDir, relative5(basePath, destination));
|
|
18847
18936
|
await mkdir7(dirname7(backupPath), { recursive: true });
|
|
@@ -18883,7 +18972,7 @@ __export(exports_update_command, {
|
|
|
18883
18972
|
});
|
|
18884
18973
|
import { homedir as homedir10 } from "node:os";
|
|
18885
18974
|
import { resolve as resolve17, dirname as dirname8 } from "node:path";
|
|
18886
|
-
import { mkdir as mkdir8, readFile as
|
|
18975
|
+
import { mkdir as mkdir8, readFile as readFile14, writeFile as writeFile7, stat as stat3 } from "node:fs/promises";
|
|
18887
18976
|
async function updateCommand(options) {
|
|
18888
18977
|
const { dryRun, force, global: isGlobal, output, projectRoot, check = false } = options;
|
|
18889
18978
|
const basePath = isGlobal ? homedir10() : projectRoot;
|
|
@@ -18992,7 +19081,7 @@ async function updateCommand(options) {
|
|
|
18992
19081
|
const localCouncil = resolve17(basePath, ".codeconductor", "presets", "council.yml");
|
|
18993
19082
|
const bundledCouncil = resolve17(SRC_PRESETS_DIR, "council", "council.yml");
|
|
18994
19083
|
try {
|
|
18995
|
-
const content = await
|
|
19084
|
+
const content = await readFile14(bundledCouncil, "utf-8");
|
|
18996
19085
|
await mkdir8(dirname8(localCouncil), { recursive: true });
|
|
18997
19086
|
await writeFile7(localCouncil, content, "utf-8");
|
|
18998
19087
|
updated.push(localCouncil);
|
|
@@ -19003,7 +19092,7 @@ async function updateCommand(options) {
|
|
|
19003
19092
|
if (updateResults.policy) {
|
|
19004
19093
|
const localPolicy = resolve17(basePath, ".codeconductor", "presets", "policy.yml");
|
|
19005
19094
|
try {
|
|
19006
|
-
const content = await
|
|
19095
|
+
const content = await readFile14(POLICY_PATH, "utf-8");
|
|
19007
19096
|
await mkdir8(dirname8(localPolicy), { recursive: true });
|
|
19008
19097
|
await writeFile7(localPolicy, content, "utf-8");
|
|
19009
19098
|
updated.push(localPolicy);
|
|
@@ -19161,7 +19250,7 @@ __export(exports_migrate_command, {
|
|
|
19161
19250
|
migrateCommand: () => migrateCommand,
|
|
19162
19251
|
migratePermissionRules: () => migratePermissionRules
|
|
19163
19252
|
});
|
|
19164
|
-
import { readFile as
|
|
19253
|
+
import { readFile as readFile15, readdir as readdir3, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
|
|
19165
19254
|
import { homedir as homedir11 } from "node:os";
|
|
19166
19255
|
import { join as join11, resolve as resolve18 } from "node:path";
|
|
19167
19256
|
function migratePermissionRules(settings) {
|
|
@@ -19244,7 +19333,7 @@ async function migrateCommand(options) {
|
|
|
19244
19333
|
const settingsPath = resolveSettingsPath(options);
|
|
19245
19334
|
let raw = null;
|
|
19246
19335
|
try {
|
|
19247
|
-
raw = await
|
|
19336
|
+
raw = await readFile15(settingsPath, "utf-8");
|
|
19248
19337
|
} catch (error) {
|
|
19249
19338
|
if (error.code !== "ENOENT") {
|
|
19250
19339
|
return {
|
|
@@ -19657,7 +19746,7 @@ var exports_debt_harvest_command = {};
|
|
|
19657
19746
|
__export(exports_debt_harvest_command, {
|
|
19658
19747
|
debtHarvestCommand: () => debtHarvestCommand
|
|
19659
19748
|
});
|
|
19660
|
-
import { readdir as readdir5, readFile as
|
|
19749
|
+
import { readdir as readdir5, readFile as readFile16, writeFile as writeFile9, mkdir as mkdir9 } from "node:fs/promises";
|
|
19661
19750
|
import { join as join13, relative as relative6, extname } from "node:path";
|
|
19662
19751
|
async function walkDir(dir, extensions) {
|
|
19663
19752
|
const results = [];
|
|
@@ -19735,7 +19824,7 @@ async function debtHarvestCommand(options) {
|
|
|
19735
19824
|
const files = await walkDir(targetDir, SOURCE_EXTENSIONS);
|
|
19736
19825
|
const allEntries = [];
|
|
19737
19826
|
for (const file of files) {
|
|
19738
|
-
const content = await
|
|
19827
|
+
const content = await readFile16(file, "utf-8");
|
|
19739
19828
|
const entries = extractDefers(content, relative6(projectRoot, file));
|
|
19740
19829
|
allEntries.push(...entries);
|
|
19741
19830
|
}
|
|
@@ -20213,11 +20302,11 @@ __export(exports_graph_store, {
|
|
|
20213
20302
|
saveGraph: () => saveGraph,
|
|
20214
20303
|
upsertNode: () => upsertNode
|
|
20215
20304
|
});
|
|
20216
|
-
import { mkdir as mkdir10, readFile as
|
|
20305
|
+
import { mkdir as mkdir10, readFile as readFile17, writeFile as writeFile10 } from "node:fs/promises";
|
|
20217
20306
|
import { dirname as dirname9 } from "node:path";
|
|
20218
20307
|
async function loadGraph(projectRoot) {
|
|
20219
20308
|
try {
|
|
20220
|
-
const raw = await
|
|
20309
|
+
const raw = await readFile17(productGraphPath(projectRoot), "utf-8");
|
|
20221
20310
|
return ok(ProductGraphSchema.parse(JSON.parse(raw)));
|
|
20222
20311
|
} catch (e) {
|
|
20223
20312
|
if (e.code === "ENOENT") {
|
|
@@ -20399,7 +20488,7 @@ __export(exports_goal_state, {
|
|
|
20399
20488
|
markTaskBlocked: () => markTaskBlocked,
|
|
20400
20489
|
writeGoal: () => writeGoal
|
|
20401
20490
|
});
|
|
20402
|
-
import { mkdir as mkdir11, readFile as
|
|
20491
|
+
import { mkdir as mkdir11, readFile as readFile18, writeFile as writeFile11 } from "node:fs/promises";
|
|
20403
20492
|
import { resolve as resolve19 } from "node:path";
|
|
20404
20493
|
function validateGoalGraph2(graph) {
|
|
20405
20494
|
const ids = new Set(graph.tasks.map((t) => t.id));
|
|
@@ -20452,7 +20541,7 @@ async function writeGoal(projectRoot, graph) {
|
|
|
20452
20541
|
async function loadGoal(projectRoot) {
|
|
20453
20542
|
try {
|
|
20454
20543
|
const filePath = resolve19(projectRoot, GOAL_FILE);
|
|
20455
|
-
const content = await
|
|
20544
|
+
const content = await readFile18(filePath, "utf-8");
|
|
20456
20545
|
const data = $parse(content);
|
|
20457
20546
|
const validated = GoalGraphSchema.parse(data);
|
|
20458
20547
|
return validateGoalGraph2(validated);
|
|
@@ -20614,7 +20703,7 @@ var init_goal_command = __esm(() => {
|
|
|
20614
20703
|
});
|
|
20615
20704
|
|
|
20616
20705
|
// src/core/openspec/backlog-parser.ts
|
|
20617
|
-
import { readFile as
|
|
20706
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
20618
20707
|
import { resolve as resolve20 } from "node:path";
|
|
20619
20708
|
function parseBool(value) {
|
|
20620
20709
|
const v = value.trim().toLowerCase();
|
|
@@ -20790,7 +20879,7 @@ function parseBacklogMarkdown(content) {
|
|
|
20790
20879
|
async function loadBacklog(projectRoot) {
|
|
20791
20880
|
try {
|
|
20792
20881
|
const filePath = resolve20(projectRoot, BACKLOG_FILE);
|
|
20793
|
-
const content = await
|
|
20882
|
+
const content = await readFile19(filePath, "utf-8");
|
|
20794
20883
|
return parseBacklogMarkdown(content);
|
|
20795
20884
|
} catch (e) {
|
|
20796
20885
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -20839,14 +20928,14 @@ function slugify(text) {
|
|
|
20839
20928
|
}
|
|
20840
20929
|
|
|
20841
20930
|
// src/core/knowledge/source-parsers.ts
|
|
20842
|
-
import { readFile as
|
|
20843
|
-
import { join as join15 } from "node:path";
|
|
20931
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
20932
|
+
import { basename as basename6, join as join15, relative as relative7, sep as sep5 } from "node:path";
|
|
20844
20933
|
async function parseAdrFile(filePath) {
|
|
20845
20934
|
try {
|
|
20846
|
-
const content = await
|
|
20847
|
-
const
|
|
20848
|
-
const idMatch =
|
|
20849
|
-
const id = idMatch ? `adr-${idMatch[1]}` : slugify(
|
|
20935
|
+
const content = await readFile20(filePath, "utf-8");
|
|
20936
|
+
const base = basename6(filePath);
|
|
20937
|
+
const idMatch = base.match(/adr-(\d+)/i);
|
|
20938
|
+
const id = idMatch ? `adr-${idMatch[1]}` : slugify(base);
|
|
20850
20939
|
const titleMatch = content.match(/^#\s+ADR-\d+:\s*(.+)$/m);
|
|
20851
20940
|
const statusMatch = content.match(/\*\*Status:\*\*\s*(\w+)/i);
|
|
20852
20941
|
const contextSection = extractSection(content, "Context");
|
|
@@ -20856,7 +20945,7 @@ async function parseAdrFile(filePath) {
|
|
|
20856
20945
|
`).filter((l) => l.trim().startsWith("-") || l.trim().startsWith("*")).map((l) => l.replace(/^[\s*-]+/, "").trim()).filter(Boolean);
|
|
20857
20946
|
return {
|
|
20858
20947
|
id,
|
|
20859
|
-
title: titleMatch?.[1]?.trim() ??
|
|
20948
|
+
title: titleMatch?.[1]?.trim() ?? base,
|
|
20860
20949
|
status: statusMatch?.[1]?.toLowerCase() ?? "unknown",
|
|
20861
20950
|
context: contextSection.trim(),
|
|
20862
20951
|
decision: decisionSection.trim(),
|
|
@@ -20892,7 +20981,7 @@ function adrToEntities(adr, source) {
|
|
|
20892
20981
|
}
|
|
20893
20982
|
async function parseReadmeEntities(projectRoot, productName) {
|
|
20894
20983
|
try {
|
|
20895
|
-
const content = await
|
|
20984
|
+
const content = await readFile20(join15(projectRoot, "README.md"), "utf-8");
|
|
20896
20985
|
const firstPara = content.split(`
|
|
20897
20986
|
|
|
20898
20987
|
`).find((p) => p.trim() && !p.startsWith("#") && !p.startsWith(">")) ?? "";
|
|
@@ -20913,7 +21002,7 @@ async function parseReadmeEntities(projectRoot, productName) {
|
|
|
20913
21002
|
}
|
|
20914
21003
|
async function parseGraphifyEntities(projectRoot) {
|
|
20915
21004
|
try {
|
|
20916
|
-
const raw = await
|
|
21005
|
+
const raw = await readFile20(join15(projectRoot, "graphify-out", "graph.json"), "utf-8");
|
|
20917
21006
|
const graph = JSON.parse(raw);
|
|
20918
21007
|
const entities = [];
|
|
20919
21008
|
for (const node2 of graph.nodes ?? []) {
|
|
@@ -20956,7 +21045,7 @@ async function scanSrcComponents(projectRoot) {
|
|
|
20956
21045
|
source: "src/",
|
|
20957
21046
|
confidence: "medium",
|
|
20958
21047
|
relations: [],
|
|
20959
|
-
data: { path: full.
|
|
21048
|
+
data: { path: relative7(projectRoot, full).split(sep5).join("/") }
|
|
20960
21049
|
});
|
|
20961
21050
|
await walk(full, prefix ? `${prefix}-${domainSlug}` : domainSlug);
|
|
20962
21051
|
}
|
|
@@ -20969,7 +21058,7 @@ async function scanSrcComponents(projectRoot) {
|
|
|
20969
21058
|
var init_source_parsers = () => {};
|
|
20970
21059
|
|
|
20971
21060
|
// src/core/memory/episodic-store.ts
|
|
20972
|
-
import { appendFile, mkdir as mkdir12, readFile as
|
|
21061
|
+
import { appendFile, mkdir as mkdir12, readFile as readFile21 } from "node:fs/promises";
|
|
20973
21062
|
import { resolve as resolve21 } from "node:path";
|
|
20974
21063
|
async function appendEvent(projectRoot, event) {
|
|
20975
21064
|
try {
|
|
@@ -20988,7 +21077,7 @@ async function appendEvent(projectRoot, event) {
|
|
|
20988
21077
|
}
|
|
20989
21078
|
async function listEvents(projectRoot, since, type) {
|
|
20990
21079
|
try {
|
|
20991
|
-
const content = await
|
|
21080
|
+
const content = await readFile21(eventsPath(projectRoot), "utf-8");
|
|
20992
21081
|
const events = [];
|
|
20993
21082
|
for (const line of content.split(`
|
|
20994
21083
|
`)) {
|
|
@@ -21016,8 +21105,8 @@ var init_episodic_store = __esm(() => {
|
|
|
21016
21105
|
|
|
21017
21106
|
// src/core/knowledge/ingest-pipeline.ts
|
|
21018
21107
|
import { createHash as createHash3 } from "node:crypto";
|
|
21019
|
-
import { readFile as
|
|
21020
|
-
import { join as join16 } from "node:path";
|
|
21108
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
21109
|
+
import { join as join16, relative as relative8, sep as sep6 } from "node:path";
|
|
21021
21110
|
import { mkdir as mkdir13, writeFile as writeFile12 } from "node:fs/promises";
|
|
21022
21111
|
async function mapLimit(items, limit, fn) {
|
|
21023
21112
|
if (items.length === 0)
|
|
@@ -21038,7 +21127,7 @@ async function mapLimit(items, limit, fn) {
|
|
|
21038
21127
|
}
|
|
21039
21128
|
async function hashFile(path) {
|
|
21040
21129
|
try {
|
|
21041
|
-
const content = await
|
|
21130
|
+
const content = await readFile22(path, "utf-8");
|
|
21042
21131
|
return createHash3("sha256").update(content).digest("hex").slice(0, 16);
|
|
21043
21132
|
} catch {
|
|
21044
21133
|
return null;
|
|
@@ -21065,8 +21154,8 @@ async function collectDeferRisks(projectRoot) {
|
|
|
21065
21154
|
await walk(join16(projectRoot, "src"));
|
|
21066
21155
|
const perFile = await mapLimit(files, WALK_READ_CONCURRENCY, async (full) => {
|
|
21067
21156
|
const entities = [];
|
|
21068
|
-
const content = await
|
|
21069
|
-
const rel = full.
|
|
21157
|
+
const content = await readFile22(full, "utf-8");
|
|
21158
|
+
const rel = relative8(projectRoot, full).split(sep6).join("/");
|
|
21070
21159
|
const deferRe = new RegExp(DEFER_REGEX_SOURCE, "gm");
|
|
21071
21160
|
let match;
|
|
21072
21161
|
while ((match = deferRe.exec(content)) !== null) {
|
|
@@ -21314,11 +21403,11 @@ var init_ingest_command = __esm(() => {
|
|
|
21314
21403
|
});
|
|
21315
21404
|
|
|
21316
21405
|
// src/core/memory/operational-state.ts
|
|
21317
|
-
import { mkdir as mkdir14, readFile as
|
|
21406
|
+
import { mkdir as mkdir14, readFile as readFile23, writeFile as writeFile13 } from "node:fs/promises";
|
|
21318
21407
|
import { resolve as resolve22 } from "node:path";
|
|
21319
21408
|
async function loadOperationalState(projectRoot) {
|
|
21320
21409
|
try {
|
|
21321
|
-
const raw = await
|
|
21410
|
+
const raw = await readFile23(operationalStatePath(projectRoot), "utf-8");
|
|
21322
21411
|
return ok(OperationalStateSchema.parse(JSON.parse(raw)));
|
|
21323
21412
|
} catch (e) {
|
|
21324
21413
|
if (e.code === "ENOENT") {
|
|
@@ -21375,11 +21464,11 @@ var init_operational_state = __esm(() => {
|
|
|
21375
21464
|
});
|
|
21376
21465
|
|
|
21377
21466
|
// src/core/memory/strategic-memory.ts
|
|
21378
|
-
import { mkdir as mkdir15, readFile as
|
|
21467
|
+
import { mkdir as mkdir15, readFile as readFile24, writeFile as writeFile14 } from "node:fs/promises";
|
|
21379
21468
|
import { resolve as resolve23 } from "node:path";
|
|
21380
21469
|
async function loadStrategicMemory(projectRoot) {
|
|
21381
21470
|
try {
|
|
21382
|
-
const raw = await
|
|
21471
|
+
const raw = await readFile24(strategicPath(projectRoot), "utf-8");
|
|
21383
21472
|
return ok(StrategicMemorySchema.parse(JSON.parse(raw)));
|
|
21384
21473
|
} catch (e) {
|
|
21385
21474
|
if (e.code === "ENOENT") {
|
|
@@ -21413,7 +21502,7 @@ var init_strategic_memory = __esm(() => {
|
|
|
21413
21502
|
});
|
|
21414
21503
|
|
|
21415
21504
|
// src/core/memory/memory-index.ts
|
|
21416
|
-
import { mkdir as mkdir16, readFile as
|
|
21505
|
+
import { mkdir as mkdir16, readFile as readFile25, writeFile as writeFile15 } from "node:fs/promises";
|
|
21417
21506
|
import { resolve as resolve24 } from "node:path";
|
|
21418
21507
|
function parseMarkdown(content) {
|
|
21419
21508
|
const startIdx = content.indexOf(SENTINEL_START);
|
|
@@ -21434,7 +21523,7 @@ function parseMarkdown(content) {
|
|
|
21434
21523
|
async function loadMemoryIndex(projectRoot) {
|
|
21435
21524
|
try {
|
|
21436
21525
|
const filePath = resolve24(projectRoot, MEMORY_FILE);
|
|
21437
|
-
const content = await
|
|
21526
|
+
const content = await readFile25(filePath, "utf-8");
|
|
21438
21527
|
const parsed = parseMarkdown(content);
|
|
21439
21528
|
if (!parsed) {
|
|
21440
21529
|
return err(new Error("Failed to parse memory index from memory.md"));
|
|
@@ -21451,7 +21540,7 @@ var init_memory_index = __esm(() => {
|
|
|
21451
21540
|
});
|
|
21452
21541
|
|
|
21453
21542
|
// src/core/evaluation/outcome-store.ts
|
|
21454
|
-
import { appendFile as appendFile2, mkdir as mkdir17, readFile as
|
|
21543
|
+
import { appendFile as appendFile2, mkdir as mkdir17, readFile as readFile26, readdir as readdir6, writeFile as writeFile16 } from "node:fs/promises";
|
|
21455
21544
|
import { resolve as resolve25 } from "node:path";
|
|
21456
21545
|
async function ensureEvaluationDir(projectRoot) {
|
|
21457
21546
|
const dir = resolve25(projectRoot, EVAL_DIR);
|
|
@@ -21468,7 +21557,7 @@ async function appendOutcome(projectRoot, outcome) {
|
|
|
21468
21557
|
const indexPath = resolve25(dir, INDEX_FILE);
|
|
21469
21558
|
let index = { version: 1, lastOutcomeId: validated.id };
|
|
21470
21559
|
try {
|
|
21471
|
-
const raw = await
|
|
21560
|
+
const raw = await readFile26(indexPath, "utf-8");
|
|
21472
21561
|
index = EvaluationIndexSchema.parse(JSON.parse(raw));
|
|
21473
21562
|
index.lastOutcomeId = validated.id;
|
|
21474
21563
|
} catch {}
|
|
@@ -21481,7 +21570,7 @@ async function appendOutcome(projectRoot, outcome) {
|
|
|
21481
21570
|
async function listOutcomes(projectRoot, filter = {}) {
|
|
21482
21571
|
try {
|
|
21483
21572
|
const path = resolve25(projectRoot, EVAL_DIR, OUTCOMES_FILE);
|
|
21484
|
-
const content = await
|
|
21573
|
+
const content = await readFile26(path, "utf-8");
|
|
21485
21574
|
const lines = content.split(`
|
|
21486
21575
|
`).filter((l) => l.trim().length > 0);
|
|
21487
21576
|
const outcomes = [];
|
|
@@ -21541,7 +21630,7 @@ async function listScorecards(projectRoot, filter = {}) {
|
|
|
21541
21630
|
for (const file of files) {
|
|
21542
21631
|
if (!file.endsWith(".json"))
|
|
21543
21632
|
continue;
|
|
21544
|
-
const parsed = ScorecardRecordSchema.parse(JSON.parse(await
|
|
21633
|
+
const parsed = ScorecardRecordSchema.parse(JSON.parse(await readFile26(resolve25(dir, file), "utf-8")));
|
|
21545
21634
|
if (filter.backlogId && parsed.backlogId !== filter.backlogId)
|
|
21546
21635
|
continue;
|
|
21547
21636
|
if (filter.verdict && parsed.verdict !== filter.verdict)
|
|
@@ -21564,7 +21653,7 @@ async function hasPassingScorecard(projectRoot, backlogId) {
|
|
|
21564
21653
|
async function loadScorecard(projectRoot, id) {
|
|
21565
21654
|
try {
|
|
21566
21655
|
const filePath = resolve25(projectRoot, EVAL_DIR, SCORECARDS_DIR, `${id}.json`);
|
|
21567
|
-
const content = await
|
|
21656
|
+
const content = await readFile26(filePath, "utf-8");
|
|
21568
21657
|
return ok(ScorecardRecordSchema.parse(JSON.parse(content)));
|
|
21569
21658
|
} catch (e) {
|
|
21570
21659
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -21656,11 +21745,11 @@ var init_outcome_store = __esm(() => {
|
|
|
21656
21745
|
});
|
|
21657
21746
|
|
|
21658
21747
|
// src/core/feedback/feedback-ingestor.ts
|
|
21659
|
-
import { readFile as
|
|
21748
|
+
import { readFile as readFile27 } from "node:fs/promises";
|
|
21660
21749
|
import { join as join17 } from "node:path";
|
|
21661
21750
|
async function parseChangelogLearnings(projectRoot) {
|
|
21662
21751
|
try {
|
|
21663
|
-
const content = await
|
|
21752
|
+
const content = await readFile27(join17(projectRoot, "CHANGELOG.md"), "utf-8");
|
|
21664
21753
|
const unreleased = content.match(/## \[Unreleased\]([\s\S]*?)(?=## \[|\n## )/i);
|
|
21665
21754
|
if (!unreleased)
|
|
21666
21755
|
return [];
|
|
@@ -22264,22 +22353,22 @@ __export(exports_rdd_receipt, {
|
|
|
22264
22353
|
verifyReceipt: () => verifyReceipt
|
|
22265
22354
|
});
|
|
22266
22355
|
import { createHash as createHash4 } from "node:crypto";
|
|
22267
|
-
import { readdir as readdir7, readFile as
|
|
22268
|
-
import { join as join18, relative as
|
|
22356
|
+
import { readdir as readdir7, readFile as readFile28 } from "node:fs/promises";
|
|
22357
|
+
import { join as join18, relative as relative9, resolve as resolve26, sep as sep7 } from "node:path";
|
|
22269
22358
|
function sha2562(content) {
|
|
22270
22359
|
return createHash4("sha256").update(content).digest("hex");
|
|
22271
22360
|
}
|
|
22272
22361
|
function canonicalPath(projectRoot, input) {
|
|
22273
22362
|
const root = resolve26(projectRoot);
|
|
22274
22363
|
const absolute = resolve26(root, input);
|
|
22275
|
-
if (absolute !== root && !absolute.startsWith(`${root}${
|
|
22364
|
+
if (absolute !== root && !absolute.startsWith(`${root}${sep7}`)) {
|
|
22276
22365
|
throw new Error(`RDD receipt path "${input}" is outside the project root`);
|
|
22277
22366
|
}
|
|
22278
|
-
const normalized =
|
|
22367
|
+
const normalized = relative9(root, absolute);
|
|
22279
22368
|
if (!normalized || normalized === ".") {
|
|
22280
22369
|
throw new Error("RDD receipts require file paths, not the project root");
|
|
22281
22370
|
}
|
|
22282
|
-
return { absolute, relative: normalized.split(
|
|
22371
|
+
return { absolute, relative: normalized.split(sep7).join("/") };
|
|
22283
22372
|
}
|
|
22284
22373
|
async function fingerprint(projectRoot, paths) {
|
|
22285
22374
|
const deduplicated = new Map;
|
|
@@ -22289,7 +22378,7 @@ async function fingerprint(projectRoot, paths) {
|
|
|
22289
22378
|
}
|
|
22290
22379
|
const result = [];
|
|
22291
22380
|
for (const [path, absolute] of [...deduplicated.entries()].sort(([left], [right]) => left.localeCompare(right))) {
|
|
22292
|
-
result.push({ path, hash: sha2562(await
|
|
22381
|
+
result.push({ path, hash: sha2562(await readFile28(absolute)) });
|
|
22293
22382
|
}
|
|
22294
22383
|
return result;
|
|
22295
22384
|
}
|
|
@@ -22334,7 +22423,7 @@ async function collectReceiptPaths(projectRoot) {
|
|
|
22334
22423
|
continue;
|
|
22335
22424
|
}
|
|
22336
22425
|
if (entry.isFile())
|
|
22337
|
-
paths.push(
|
|
22426
|
+
paths.push(relative9(root, join18(current, entry.name)).split(sep7).join("/"));
|
|
22338
22427
|
}
|
|
22339
22428
|
}
|
|
22340
22429
|
await visit2(root);
|
|
@@ -22349,7 +22438,7 @@ async function verifyReceipt(projectRoot, receipt) {
|
|
|
22349
22438
|
for (const path of pathsToCheck) {
|
|
22350
22439
|
try {
|
|
22351
22440
|
const canonical = canonicalPath(projectRoot, path);
|
|
22352
|
-
const hash = sha2562(await
|
|
22441
|
+
const hash = sha2562(await readFile28(canonical.absolute));
|
|
22353
22442
|
const currentEntry = { path: canonical.relative, hash };
|
|
22354
22443
|
current.push(currentEntry);
|
|
22355
22444
|
currentByPath.set(currentEntry.path, currentEntry);
|
|
@@ -22386,7 +22475,7 @@ var init_rdd_receipt = __esm(() => {
|
|
|
22386
22475
|
|
|
22387
22476
|
// src/core/verification/verification-runner.ts
|
|
22388
22477
|
import { existsSync as existsSync3 } from "node:fs";
|
|
22389
|
-
import { readFile as
|
|
22478
|
+
import { readFile as readFile29 } from "node:fs/promises";
|
|
22390
22479
|
import { dirname as dirname10, join as join19, resolve as resolve27 } from "node:path";
|
|
22391
22480
|
import { mkdir as mkdir18, readdir as readdir8, writeFile as writeFile18 } from "node:fs/promises";
|
|
22392
22481
|
function isPassingEvidence(ev) {
|
|
@@ -22449,7 +22538,7 @@ async function collectTaskEvidence(projectRoot, taskId) {
|
|
|
22449
22538
|
if (!file.endsWith(".json"))
|
|
22450
22539
|
continue;
|
|
22451
22540
|
try {
|
|
22452
|
-
const raw = await
|
|
22541
|
+
const raw = await readFile29(join19(evDir, file), "utf-8");
|
|
22453
22542
|
const ev = EvidenceSchema.parse(JSON.parse(raw));
|
|
22454
22543
|
if (ev.relatedTask === taskId)
|
|
22455
22544
|
records.push(ev);
|
|
@@ -22636,7 +22725,7 @@ async function loadTddSuiteEvidence(projectRoot, taskId, evidenceId) {
|
|
|
22636
22725
|
return path;
|
|
22637
22726
|
let raw;
|
|
22638
22727
|
try {
|
|
22639
|
-
raw = await
|
|
22728
|
+
raw = await readFile29(path.data, "utf-8");
|
|
22640
22729
|
} catch (e) {
|
|
22641
22730
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
22642
22731
|
}
|
|
@@ -23037,8 +23126,8 @@ var init_loop_state = __esm(() => {
|
|
|
23037
23126
|
});
|
|
23038
23127
|
|
|
23039
23128
|
// src/core/loop/git-stats.ts
|
|
23040
|
-
import { execFile as
|
|
23041
|
-
import { promisify as
|
|
23129
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
23130
|
+
import { promisify as promisify3 } from "node:util";
|
|
23042
23131
|
function countPorcelain(output) {
|
|
23043
23132
|
return output.split(`
|
|
23044
23133
|
`).filter((line) => line.trim().length > 0).length;
|
|
@@ -23062,12 +23151,12 @@ function countNumstat(output) {
|
|
|
23062
23151
|
async function fetchGitChangeStats(cwd) {
|
|
23063
23152
|
try {
|
|
23064
23153
|
const [status, diff] = await Promise.all([
|
|
23065
|
-
|
|
23154
|
+
execFileAsync3("git", ["status", "--porcelain"], {
|
|
23066
23155
|
cwd,
|
|
23067
23156
|
encoding: "utf-8",
|
|
23068
23157
|
timeout: 15000
|
|
23069
23158
|
}),
|
|
23070
|
-
|
|
23159
|
+
execFileAsync3("git", ["diff", "--numstat"], {
|
|
23071
23160
|
cwd,
|
|
23072
23161
|
encoding: "utf-8",
|
|
23073
23162
|
timeout: 15000
|
|
@@ -23091,9 +23180,9 @@ async function readGitChangeStats(cwd, options) {
|
|
|
23091
23180
|
cache = { cwd, at: now, stats };
|
|
23092
23181
|
return stats;
|
|
23093
23182
|
}
|
|
23094
|
-
var
|
|
23183
|
+
var execFileAsync3, GIT_STATS_CACHE_TTL_MS = 3000, cache;
|
|
23095
23184
|
var init_git_stats = __esm(() => {
|
|
23096
|
-
|
|
23185
|
+
execFileAsync3 = promisify3(execFile3);
|
|
23097
23186
|
});
|
|
23098
23187
|
|
|
23099
23188
|
// src/core/loop/loop-engine.ts
|
|
@@ -23826,11 +23915,11 @@ __export(exports_rdd_command, {
|
|
|
23826
23915
|
rddCommand: () => rddCommand,
|
|
23827
23916
|
rddStatus: () => rddStatus
|
|
23828
23917
|
});
|
|
23829
|
-
import { execFile as
|
|
23918
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
23830
23919
|
import { existsSync as existsSync4 } from "node:fs";
|
|
23831
|
-
import { mkdir as mkdir19, readFile as
|
|
23920
|
+
import { mkdir as mkdir19, readFile as readFile30, readdir as readdir9, rename as rename3, writeFile as writeFile19, chmod } from "node:fs/promises";
|
|
23832
23921
|
import { dirname as dirname11, resolve as resolve28 } from "node:path";
|
|
23833
|
-
import { promisify as
|
|
23922
|
+
import { promisify as promisify4 } from "node:util";
|
|
23834
23923
|
function receiptPath(projectRoot, id) {
|
|
23835
23924
|
const directory = resolve28(evidenceDir(projectRoot));
|
|
23836
23925
|
const path = resolve28(directory, `${id.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
|
|
@@ -23839,7 +23928,7 @@ function receiptPath(projectRoot, id) {
|
|
|
23839
23928
|
return path;
|
|
23840
23929
|
}
|
|
23841
23930
|
async function loadReceipt(projectRoot, id) {
|
|
23842
|
-
const raw = await
|
|
23931
|
+
const raw = await readFile30(receiptPath(projectRoot, id), "utf-8");
|
|
23843
23932
|
const evidence = EvidenceSchema.parse(JSON.parse(raw));
|
|
23844
23933
|
if (evidence.type !== "rdd")
|
|
23845
23934
|
throw new Error(`Evidence "${id}" is not an RDD receipt`);
|
|
@@ -23877,7 +23966,7 @@ async function rddStatus(projectRoot, taskId) {
|
|
|
23877
23966
|
return receipts.sort((left, right) => right.timestamp.localeCompare(left.timestamp));
|
|
23878
23967
|
}
|
|
23879
23968
|
async function installHooks(projectRoot) {
|
|
23880
|
-
const { stdout } = await
|
|
23969
|
+
const { stdout } = await execFileAsync4("git", ["rev-parse", "--git-path", "hooks"], {
|
|
23881
23970
|
cwd: projectRoot,
|
|
23882
23971
|
encoding: "utf8"
|
|
23883
23972
|
});
|
|
@@ -23890,7 +23979,7 @@ async function installHooks(projectRoot) {
|
|
|
23890
23979
|
const backup = resolve28(hooksDir, `${hook}.rdd-original`);
|
|
23891
23980
|
const marker = "# codeconductor-rdd-hook";
|
|
23892
23981
|
if (existsSync4(path)) {
|
|
23893
|
-
const existing = await
|
|
23982
|
+
const existing = await readFile30(path, "utf8");
|
|
23894
23983
|
if (existing.includes(marker)) {
|
|
23895
23984
|
skipped.push(hook);
|
|
23896
23985
|
continue;
|
|
@@ -23969,12 +24058,12 @@ async function rddCommand(options) {
|
|
|
23969
24058
|
return { code: 1, data: { success: false, errors: [error instanceof Error ? error.message : String(error)] } };
|
|
23970
24059
|
}
|
|
23971
24060
|
}
|
|
23972
|
-
var
|
|
24061
|
+
var execFileAsync4;
|
|
23973
24062
|
var init_rdd_command = __esm(() => {
|
|
23974
24063
|
init_schemas();
|
|
23975
24064
|
init_paths();
|
|
23976
24065
|
init_rdd_receipt();
|
|
23977
|
-
|
|
24066
|
+
execFileAsync4 = promisify4(execFile4);
|
|
23978
24067
|
});
|
|
23979
24068
|
|
|
23980
24069
|
// src/core/ccep/confirmation-gate.ts
|
|
@@ -24055,6 +24144,101 @@ function buildOpenspecPhaseContext(context, phase) {
|
|
|
24055
24144
|
};
|
|
24056
24145
|
}
|
|
24057
24146
|
|
|
24147
|
+
// src/core/ccep/output-validator.ts
|
|
24148
|
+
function resolveOutputSchemaName(schemaName, role) {
|
|
24149
|
+
if (schemaName !== "agent-output" && SCHEMA_REGISTRY[schemaName]) {
|
|
24150
|
+
return schemaName;
|
|
24151
|
+
}
|
|
24152
|
+
if (role === "implementer") {
|
|
24153
|
+
return "implementer-output";
|
|
24154
|
+
}
|
|
24155
|
+
if (role === "reviewer") {
|
|
24156
|
+
return "review-report";
|
|
24157
|
+
}
|
|
24158
|
+
if (role === "task-coach" || role === "architect") {
|
|
24159
|
+
return schemaName === "technical-plan" ? "technical-plan" : "planner-output";
|
|
24160
|
+
}
|
|
24161
|
+
return schemaName;
|
|
24162
|
+
}
|
|
24163
|
+
function validateResolvedOutputSchema(schemaName, data) {
|
|
24164
|
+
const schema = SCHEMA_REGISTRY[schemaName];
|
|
24165
|
+
if (!schema) {
|
|
24166
|
+
return {
|
|
24167
|
+
valid: false,
|
|
24168
|
+
schema: schemaName,
|
|
24169
|
+
errors: [`Unknown output schema: ${schemaName}`]
|
|
24170
|
+
};
|
|
24171
|
+
}
|
|
24172
|
+
const parsed = schema.safeParse(data);
|
|
24173
|
+
if (parsed.success) {
|
|
24174
|
+
return { valid: true, schema: schemaName, data: parsed.data };
|
|
24175
|
+
}
|
|
24176
|
+
return {
|
|
24177
|
+
valid: false,
|
|
24178
|
+
schema: schemaName,
|
|
24179
|
+
errors: parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
|
24180
|
+
};
|
|
24181
|
+
}
|
|
24182
|
+
function parseJsonInput(raw) {
|
|
24183
|
+
return JSON.parse(raw);
|
|
24184
|
+
}
|
|
24185
|
+
function validateOutputForRole(role, outputSchema, data) {
|
|
24186
|
+
const resolved = resolveOutputSchemaName(outputSchema, role);
|
|
24187
|
+
if (resolved === "implementer-output") {
|
|
24188
|
+
try {
|
|
24189
|
+
return { valid: true, schema: "implementer-output", data: validateImplementerOutput(data) };
|
|
24190
|
+
} catch (err3) {
|
|
24191
|
+
return {
|
|
24192
|
+
valid: false,
|
|
24193
|
+
schema: "implementer-output",
|
|
24194
|
+
errors: [String(err3)]
|
|
24195
|
+
};
|
|
24196
|
+
}
|
|
24197
|
+
}
|
|
24198
|
+
if (resolved === "review-report") {
|
|
24199
|
+
try {
|
|
24200
|
+
return { valid: true, schema: "review-report", data: validateReviewerOutput(data) };
|
|
24201
|
+
} catch (err3) {
|
|
24202
|
+
return {
|
|
24203
|
+
valid: false,
|
|
24204
|
+
schema: "review-report",
|
|
24205
|
+
errors: [String(err3)]
|
|
24206
|
+
};
|
|
24207
|
+
}
|
|
24208
|
+
}
|
|
24209
|
+
if (resolved === "planner-output") {
|
|
24210
|
+
try {
|
|
24211
|
+
return { valid: true, schema: "planner-output", data: validatePlannerOutput(data) };
|
|
24212
|
+
} catch (err3) {
|
|
24213
|
+
return {
|
|
24214
|
+
valid: false,
|
|
24215
|
+
schema: "planner-output",
|
|
24216
|
+
errors: [String(err3)]
|
|
24217
|
+
};
|
|
24218
|
+
}
|
|
24219
|
+
}
|
|
24220
|
+
return validateResolvedOutputSchema(resolved, data);
|
|
24221
|
+
}
|
|
24222
|
+
var SCHEMA_REGISTRY;
|
|
24223
|
+
var init_output_validator = __esm(() => {
|
|
24224
|
+
init_schemas();
|
|
24225
|
+
SCHEMA_REGISTRY = {
|
|
24226
|
+
"planner-output": PlannerOutputSchema,
|
|
24227
|
+
"implementer-output": ImplementerOutputSchema,
|
|
24228
|
+
"review-report": ReviewerOutputSchema,
|
|
24229
|
+
"technical-plan": TechnicalPlanOutputSchema,
|
|
24230
|
+
"fix-intake-output": FixIntakeOutputSchema,
|
|
24231
|
+
"council-verdict": CouncilVerdictSchema,
|
|
24232
|
+
"agent-output": AgentOutputSchema,
|
|
24233
|
+
taskcard: CanonicalTaskCardSchema,
|
|
24234
|
+
"test-plan": AgentOutputSchema,
|
|
24235
|
+
"complexity-audit": AgentOutputSchema,
|
|
24236
|
+
"api-contract": AgentOutputSchema,
|
|
24237
|
+
"pagespeed-report": AgentOutputSchema,
|
|
24238
|
+
"scorecard-record": ScorecardRecordSchema
|
|
24239
|
+
};
|
|
24240
|
+
});
|
|
24241
|
+
|
|
24058
24242
|
// src/core/ccep/prompt-compiler.ts
|
|
24059
24243
|
function buildSystemLayer() {
|
|
24060
24244
|
return [
|
|
@@ -24067,24 +24251,22 @@ function buildSystemLayer() {
|
|
|
24067
24251
|
].join(`
|
|
24068
24252
|
`);
|
|
24069
24253
|
}
|
|
24070
|
-
function buildAgentLayer(role, phase) {
|
|
24254
|
+
function buildAgentLayer(role, phase, outputSchema) {
|
|
24071
24255
|
const label = ROLE_LABELS[role] ?? role;
|
|
24256
|
+
let instruction;
|
|
24072
24257
|
if (role === "task-coach" && phase === "intake") {
|
|
24073
|
-
|
|
24258
|
+
instruction = `You are the Planner / ${label} of CodeConductor.
|
|
24074
24259
|
Convert product intent into a structured plan without writing code.`;
|
|
24075
|
-
}
|
|
24076
|
-
|
|
24077
|
-
return `You are the ${label}.
|
|
24078
|
-
Execute only your assigned phase: ${phase}.
|
|
24079
|
-
Write the minimal diff. Return implementer-output JSON only.`;
|
|
24080
|
-
}
|
|
24081
|
-
if (role === "reviewer") {
|
|
24082
|
-
return `You are the ${label}.
|
|
24260
|
+
} else if (role === "implementer") {
|
|
24261
|
+
instruction = `You are the ${label}.
|
|
24083
24262
|
Execute only your assigned phase: ${phase}.
|
|
24084
|
-
|
|
24085
|
-
}
|
|
24086
|
-
|
|
24263
|
+
Write the minimal diff.`;
|
|
24264
|
+
} else {
|
|
24265
|
+
instruction = `You are the ${label}.
|
|
24087
24266
|
Execute only your assigned phase: ${phase}.`;
|
|
24267
|
+
}
|
|
24268
|
+
return `${instruction}
|
|
24269
|
+
Return ${outputSchema} JSON only.`;
|
|
24088
24270
|
}
|
|
24089
24271
|
function buildTaskLayer(context, phase) {
|
|
24090
24272
|
if (context.envelope.command === "openspec") {
|
|
@@ -24094,19 +24276,28 @@ function buildTaskLayer(context, phase) {
|
|
|
24094
24276
|
command: context.envelope.command,
|
|
24095
24277
|
intent: context.intent,
|
|
24096
24278
|
phase,
|
|
24097
|
-
userRequest: context.envelope.userRequest,
|
|
24098
24279
|
project: context.project.name
|
|
24099
24280
|
}, null, 2);
|
|
24100
24281
|
}
|
|
24282
|
+
function scopeKnowledgeForRole(knowledge, role) {
|
|
24283
|
+
const keys = KNOWLEDGE_KEYS_BY_ROLE[role];
|
|
24284
|
+
if (!keys)
|
|
24285
|
+
return knowledge;
|
|
24286
|
+
if (Object.keys(knowledge).some((key) => !PRODUCT_GRAPH_KNOWLEDGE_KEYS.has(key))) {
|
|
24287
|
+
return knowledge;
|
|
24288
|
+
}
|
|
24289
|
+
return Object.fromEntries(keys.filter((key) => knowledge[key] !== undefined).map((key) => [key, knowledge[key]]));
|
|
24290
|
+
}
|
|
24101
24291
|
function compilePrompt(options) {
|
|
24102
24292
|
const { role, phase, context, promptVersion } = options;
|
|
24103
24293
|
const phaseDef = context.profile.phases.find((p) => p.id === phase);
|
|
24104
|
-
const
|
|
24294
|
+
const configuredSchemaName = phaseDef?.outputSchema ?? context.outputSchema ?? "agent-output";
|
|
24295
|
+
const schemaName = resolveOutputSchemaName(configuredSchemaName, role);
|
|
24105
24296
|
const schemaBody = OUTPUT_SCHEMAS[schemaName] ?? OUTPUT_SCHEMAS["agent-output"];
|
|
24106
|
-
const knowledge = context.envelope.command === "openspec" ? buildOpenspecPhaseContext(context, phase).knowledge : context.knowledge;
|
|
24297
|
+
const knowledge = context.envelope.command === "openspec" ? buildOpenspecPhaseContext(context, phase).knowledge : scopeKnowledgeForRole(context.knowledge, role);
|
|
24107
24298
|
const layers = [
|
|
24108
24299
|
{ name: "system", content: buildSystemLayer() },
|
|
24109
|
-
{ name: "agent", content: buildAgentLayer(role, phase) },
|
|
24300
|
+
{ name: "agent", content: buildAgentLayer(role, phase, schemaName) },
|
|
24110
24301
|
{
|
|
24111
24302
|
name: "policies",
|
|
24112
24303
|
content: JSON.stringify({ ...context.policies, promptVersion }, null, 2)
|
|
@@ -24124,10 +24315,11 @@ ${schemaBody}`
|
|
|
24124
24315
|
${layer.content}`).join(`
|
|
24125
24316
|
|
|
24126
24317
|
`);
|
|
24127
|
-
return { layers, prompt };
|
|
24318
|
+
return { layers, prompt, outputSchema: schemaName };
|
|
24128
24319
|
}
|
|
24129
|
-
var ROLE_LABELS, OUTPUT_SCHEMAS;
|
|
24320
|
+
var ROLE_LABELS, OUTPUT_SCHEMAS, KNOWLEDGE_KEYS_BY_ROLE, PRODUCT_GRAPH_KNOWLEDGE_KEYS;
|
|
24130
24321
|
var init_prompt_compiler = __esm(() => {
|
|
24322
|
+
init_output_validator();
|
|
24131
24323
|
ROLE_LABELS = {
|
|
24132
24324
|
"task-coach": "Task Coach",
|
|
24133
24325
|
architect: "Architect",
|
|
@@ -24182,108 +24374,50 @@ var init_prompt_compiler = __esm(() => {
|
|
|
24182
24374
|
"filesChanged": [{ "path": "", "summary": "" }],
|
|
24183
24375
|
"tests": { "runner": "", "result": "passed" | "failed" }
|
|
24184
24376
|
}`,
|
|
24185
|
-
"agent-output":
|
|
24186
|
-
|
|
24187
|
-
|
|
24188
|
-
|
|
24189
|
-
|
|
24190
|
-
|
|
24191
|
-
|
|
24192
|
-
|
|
24193
|
-
|
|
24194
|
-
|
|
24195
|
-
|
|
24196
|
-
|
|
24197
|
-
|
|
24198
|
-
|
|
24199
|
-
|
|
24200
|
-
|
|
24201
|
-
|
|
24202
|
-
|
|
24203
|
-
|
|
24204
|
-
|
|
24205
|
-
|
|
24206
|
-
|
|
24207
|
-
|
|
24208
|
-
|
|
24209
|
-
|
|
24210
|
-
|
|
24211
|
-
|
|
24212
|
-
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
|
|
24216
|
-
|
|
24217
|
-
|
|
24218
|
-
|
|
24219
|
-
|
|
24220
|
-
|
|
24221
|
-
|
|
24222
|
-
|
|
24223
|
-
|
|
24224
|
-
}
|
|
24225
|
-
function parseJsonInput(raw) {
|
|
24226
|
-
return JSON.parse(raw);
|
|
24227
|
-
}
|
|
24228
|
-
function validateOutputForRole(role, outputSchema, data) {
|
|
24229
|
-
if (role === "implementer") {
|
|
24230
|
-
try {
|
|
24231
|
-
return { valid: true, schema: "implementer-output", data: validateImplementerOutput(data) };
|
|
24232
|
-
} catch (err3) {
|
|
24233
|
-
return {
|
|
24234
|
-
valid: false,
|
|
24235
|
-
schema: "implementer-output",
|
|
24236
|
-
errors: [String(err3)]
|
|
24237
|
-
};
|
|
24238
|
-
}
|
|
24239
|
-
}
|
|
24240
|
-
if (role === "reviewer") {
|
|
24241
|
-
try {
|
|
24242
|
-
return { valid: true, schema: "review-report", data: validateReviewerOutput(data) };
|
|
24243
|
-
} catch (err3) {
|
|
24244
|
-
return {
|
|
24245
|
-
valid: false,
|
|
24246
|
-
schema: "review-report",
|
|
24247
|
-
errors: [String(err3)]
|
|
24248
|
-
};
|
|
24249
|
-
}
|
|
24250
|
-
}
|
|
24251
|
-
if (outputSchema === "planner-output" || role === "task-coach") {
|
|
24252
|
-
try {
|
|
24253
|
-
return { valid: true, schema: "planner-output", data: validatePlannerOutput(data) };
|
|
24254
|
-
} catch (err3) {
|
|
24255
|
-
return {
|
|
24256
|
-
valid: false,
|
|
24257
|
-
schema: "planner-output",
|
|
24258
|
-
errors: [String(err3)]
|
|
24259
|
-
};
|
|
24260
|
-
}
|
|
24261
|
-
}
|
|
24262
|
-
return validateAgentOutputBySchema(outputSchema, data, role);
|
|
24263
|
-
}
|
|
24264
|
-
var SCHEMA_REGISTRY;
|
|
24265
|
-
var init_output_validator = __esm(() => {
|
|
24266
|
-
init_schemas();
|
|
24267
|
-
SCHEMA_REGISTRY = {
|
|
24268
|
-
"planner-output": PlannerOutputSchema,
|
|
24269
|
-
"implementer-output": ImplementerOutputSchema,
|
|
24270
|
-
"review-report": ReviewerOutputSchema,
|
|
24271
|
-
"technical-plan": TechnicalPlanOutputSchema,
|
|
24272
|
-
"fix-intake-output": AgentOutputSchema,
|
|
24273
|
-
"council-verdict": CouncilVerdictSchema,
|
|
24274
|
-
"agent-output": AgentOutputSchema,
|
|
24275
|
-
taskcard: CanonicalTaskCardSchema,
|
|
24276
|
-
"test-plan": AgentOutputSchema,
|
|
24277
|
-
"complexity-audit": AgentOutputSchema,
|
|
24278
|
-
"api-contract": AgentOutputSchema,
|
|
24279
|
-
"pagespeed-report": AgentOutputSchema,
|
|
24280
|
-
"scorecard-record": ScorecardRecordSchema
|
|
24281
|
-
};
|
|
24377
|
+
"agent-output": `{
|
|
24378
|
+
"status": "success" | "failure" | "blocked" | "needs_clarification",
|
|
24379
|
+
"confidence": 0.0,
|
|
24380
|
+
"warnings": [],
|
|
24381
|
+
"artifacts": [],
|
|
24382
|
+
"next_actions": []
|
|
24383
|
+
}`,
|
|
24384
|
+
"scorecard-record": `{
|
|
24385
|
+
"id": "",
|
|
24386
|
+
"taskId": "",
|
|
24387
|
+
"agent": "",
|
|
24388
|
+
"contractVersion": "",
|
|
24389
|
+
"criteria": [],
|
|
24390
|
+
"weightedScore": 0.0,
|
|
24391
|
+
"verdict": "PASS" | "REVISE" | "REJECT",
|
|
24392
|
+
"findings": [],
|
|
24393
|
+
"createdAt": ""
|
|
24394
|
+
}`
|
|
24395
|
+
};
|
|
24396
|
+
KNOWLEDGE_KEYS_BY_ROLE = {
|
|
24397
|
+
"task-coach": ["productName", "domains", "requirements", "risks"],
|
|
24398
|
+
architect: ["productName", "domains", "decisions", "requirements", "risks"],
|
|
24399
|
+
tester: ["productName", "requirements", "risks"],
|
|
24400
|
+
implementer: ["productName", "decisions", "requirements"],
|
|
24401
|
+
reviewer: ["productName", "decisions", "requirements", "risks"],
|
|
24402
|
+
docs: ["productName", "decisions", "requirements"],
|
|
24403
|
+
"contract-builder": ["productName", "domains", "decisions", "requirements"],
|
|
24404
|
+
"complexity-auditor": ["productName", "decisions", "requirements", "risks"],
|
|
24405
|
+
orchestrator: ["productName", "domains", "decisions", "requirements", "risks"],
|
|
24406
|
+
"repo-explorer": ["productName", "domains", "requirements"]
|
|
24407
|
+
};
|
|
24408
|
+
PRODUCT_GRAPH_KNOWLEDGE_KEYS = new Set([
|
|
24409
|
+
"productName",
|
|
24410
|
+
"domains",
|
|
24411
|
+
"decisions",
|
|
24412
|
+
"risks",
|
|
24413
|
+
"requirements",
|
|
24414
|
+
"nodeCount"
|
|
24415
|
+
]);
|
|
24282
24416
|
});
|
|
24283
24417
|
|
|
24284
24418
|
// src/core/ccep/command-parser.ts
|
|
24285
24419
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
|
|
24286
|
-
import { join as join20 } from "node:path";
|
|
24420
|
+
import { basename as basename7, join as join20 } from "node:path";
|
|
24287
24421
|
function readProjectId(projectRoot) {
|
|
24288
24422
|
const packageJsonPath = join20(projectRoot, "package.json");
|
|
24289
24423
|
if (existsSync5(packageJsonPath)) {
|
|
@@ -24294,7 +24428,7 @@ function readProjectId(projectRoot) {
|
|
|
24294
24428
|
}
|
|
24295
24429
|
} catch {}
|
|
24296
24430
|
}
|
|
24297
|
-
return projectRoot
|
|
24431
|
+
return basename7(projectRoot) || "unknown";
|
|
24298
24432
|
}
|
|
24299
24433
|
function parseCommand(command, userRequest, projectRoot) {
|
|
24300
24434
|
const validatedCommand = WorkflowCommandSchema.parse(command);
|
|
@@ -24390,7 +24524,7 @@ var init_workflow_profile_loader = __esm(() => {
|
|
|
24390
24524
|
// src/core/evaluation/harness-catalog.ts
|
|
24391
24525
|
import { createHash as createHash5 } from "node:crypto";
|
|
24392
24526
|
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
|
|
24393
|
-
import { copyFile as copyFile2, mkdir as mkdir20, readFile as
|
|
24527
|
+
import { copyFile as copyFile2, mkdir as mkdir20, readFile as readFile31, readdir as readdir10, rm as rm4, writeFile as writeFile20 } from "node:fs/promises";
|
|
24394
24528
|
import { dirname as dirname12, join as join21, resolve as resolve29 } from "node:path";
|
|
24395
24529
|
function catalogIds(catalog = DEFAULT_HARNESS_CATALOG) {
|
|
24396
24530
|
return catalog.components.map((c) => c.id);
|
|
@@ -24446,7 +24580,7 @@ function harnessFingerprint(disabled, contractVersion, ccepProfile = "feature",
|
|
|
24446
24580
|
async function loadHarnessCatalog(projectRoot) {
|
|
24447
24581
|
const overridePath = resolve29(projectRoot, EVAL_DIR2, CATALOG_FILE);
|
|
24448
24582
|
try {
|
|
24449
|
-
const raw = await
|
|
24583
|
+
const raw = await readFile31(overridePath, "utf-8");
|
|
24450
24584
|
return HarnessCatalogSchema.parse($parse(raw));
|
|
24451
24585
|
} catch {
|
|
24452
24586
|
return DEFAULT_HARNESS_CATALOG;
|
|
@@ -24457,7 +24591,7 @@ function activeOverlayPath(projectRoot) {
|
|
|
24457
24591
|
}
|
|
24458
24592
|
async function readActiveOverlay(projectRoot) {
|
|
24459
24593
|
try {
|
|
24460
|
-
const raw = await
|
|
24594
|
+
const raw = await readFile31(activeOverlayPath(projectRoot), "utf-8");
|
|
24461
24595
|
return HarnessOverlaySchema.parse($parse(raw));
|
|
24462
24596
|
} catch {
|
|
24463
24597
|
return null;
|
|
@@ -24714,7 +24848,7 @@ var init_harness_catalog = __esm(() => {
|
|
|
24714
24848
|
|
|
24715
24849
|
// src/core/openspec/openspec-state.ts
|
|
24716
24850
|
import { createHash as createHash6 } from "node:crypto";
|
|
24717
|
-
import { mkdir as mkdir21, readFile as
|
|
24851
|
+
import { mkdir as mkdir21, readFile as readFile32, rename as rename4, writeFile as writeFile21 } from "node:fs/promises";
|
|
24718
24852
|
import { resolve as resolve30 } from "node:path";
|
|
24719
24853
|
function canTransition(from, to) {
|
|
24720
24854
|
return ALLOWED_TRANSITIONS[from]?.includes(to) ?? false;
|
|
@@ -24742,7 +24876,7 @@ async function writeFileAtomic(path, content) {
|
|
|
24742
24876
|
async function loadOpenspecState(projectRoot) {
|
|
24743
24877
|
try {
|
|
24744
24878
|
const filePath = resolve30(projectRoot, STATE_FILE);
|
|
24745
|
-
const content = await
|
|
24879
|
+
const content = await readFile32(filePath, "utf-8");
|
|
24746
24880
|
const data = JSON.parse(content);
|
|
24747
24881
|
return ok(OpenspecStateSchema.parse(data));
|
|
24748
24882
|
} catch (e) {
|
|
@@ -24867,7 +25001,7 @@ var init_openspec_state = __esm(() => {
|
|
|
24867
25001
|
|
|
24868
25002
|
// src/core/ccep/context-resolver.ts
|
|
24869
25003
|
import { existsSync as existsSync7 } from "node:fs";
|
|
24870
|
-
import { readFile as
|
|
25004
|
+
import { readFile as readFile33 } from "node:fs/promises";
|
|
24871
25005
|
import { join as join22 } from "node:path";
|
|
24872
25006
|
async function loadProductKnowledge(projectRoot) {
|
|
24873
25007
|
if (isProductGraphDisabled(projectRoot)) {
|
|
@@ -24878,7 +25012,7 @@ async function loadProductKnowledge(projectRoot) {
|
|
|
24878
25012
|
return {};
|
|
24879
25013
|
}
|
|
24880
25014
|
try {
|
|
24881
|
-
const raw = await
|
|
25015
|
+
const raw = await readFile33(graphPath, "utf-8");
|
|
24882
25016
|
const graph = ProductGraphSchema.parse(JSON.parse(raw));
|
|
24883
25017
|
return {
|
|
24884
25018
|
productName: graph.productName,
|
|
@@ -25448,6 +25582,11 @@ async function ccepCommand(options) {
|
|
|
25448
25582
|
input,
|
|
25449
25583
|
contextPath,
|
|
25450
25584
|
promptVersion = "v1.0.0",
|
|
25585
|
+
view = "full",
|
|
25586
|
+
recordTelemetry = false,
|
|
25587
|
+
executionId,
|
|
25588
|
+
taskId,
|
|
25589
|
+
contextStrategy,
|
|
25451
25590
|
config,
|
|
25452
25591
|
rest
|
|
25453
25592
|
} = options;
|
|
@@ -25498,6 +25637,28 @@ async function ccepCommand(options) {
|
|
|
25498
25637
|
};
|
|
25499
25638
|
}
|
|
25500
25639
|
case "compile": {
|
|
25640
|
+
if (!["prompt", "layers", "full"].includes(view)) {
|
|
25641
|
+
return {
|
|
25642
|
+
code: 1,
|
|
25643
|
+
data: {
|
|
25644
|
+
success: false,
|
|
25645
|
+
command: "ccep compile",
|
|
25646
|
+
errors: [`Unknown compile view: ${view}`]
|
|
25647
|
+
}
|
|
25648
|
+
};
|
|
25649
|
+
}
|
|
25650
|
+
if (contextStrategy !== undefined && !CONTEXT_STRATEGIES.includes(contextStrategy)) {
|
|
25651
|
+
return {
|
|
25652
|
+
code: 1,
|
|
25653
|
+
data: {
|
|
25654
|
+
success: false,
|
|
25655
|
+
command: "ccep compile",
|
|
25656
|
+
errors: [
|
|
25657
|
+
`Invalid context strategy: ${contextStrategy}. Expected one of: ${CONTEXT_STRATEGIES.join(", ")}`
|
|
25658
|
+
]
|
|
25659
|
+
}
|
|
25660
|
+
};
|
|
25661
|
+
}
|
|
25501
25662
|
const parsed = parseWorkflowCommand(command);
|
|
25502
25663
|
if (!parsed.ok) {
|
|
25503
25664
|
return {
|
|
@@ -25548,12 +25709,69 @@ async function ccepCommand(options) {
|
|
|
25548
25709
|
outputSchema: resolvedPhase.outputSchema
|
|
25549
25710
|
};
|
|
25550
25711
|
}
|
|
25712
|
+
const compileStartedAt = Date.now();
|
|
25551
25713
|
const compiled = compilePrompt({
|
|
25552
25714
|
role: agentRole,
|
|
25553
25715
|
phase: phaseId,
|
|
25554
25716
|
context,
|
|
25555
25717
|
promptVersion
|
|
25556
25718
|
});
|
|
25719
|
+
if (recordTelemetry) {
|
|
25720
|
+
const event = await appendEvent(projectRoot, {
|
|
25721
|
+
type: "context.compiled",
|
|
25722
|
+
timestamp: new Date().toISOString(),
|
|
25723
|
+
payload: {
|
|
25724
|
+
workflow: parsed.command,
|
|
25725
|
+
phase: phaseId,
|
|
25726
|
+
agent: agentRole,
|
|
25727
|
+
executionId: executionId ?? "unknown",
|
|
25728
|
+
taskId: taskId ?? "unknown",
|
|
25729
|
+
contextStrategy: contextStrategy ?? "unknown",
|
|
25730
|
+
promptVersion,
|
|
25731
|
+
view,
|
|
25732
|
+
source: "compiler",
|
|
25733
|
+
success: true,
|
|
25734
|
+
provider: "unknown",
|
|
25735
|
+
model: "unknown",
|
|
25736
|
+
effort: "unknown",
|
|
25737
|
+
sessionId: "unknown",
|
|
25738
|
+
parentSessionId: "unknown",
|
|
25739
|
+
requestedModel: "unknown",
|
|
25740
|
+
effectiveModel: "unknown",
|
|
25741
|
+
inputTokens: "unknown",
|
|
25742
|
+
outputTokens: "unknown",
|
|
25743
|
+
reasoningTokens: "unknown",
|
|
25744
|
+
cacheReadTokens: "unknown",
|
|
25745
|
+
cacheWriteTokens: "unknown",
|
|
25746
|
+
cachedTokens: "unknown",
|
|
25747
|
+
contextTokensEstimate: "unknown",
|
|
25748
|
+
filesRead: "unknown",
|
|
25749
|
+
uniqueFilesRead: "unknown",
|
|
25750
|
+
repeatedFileReads: "unknown",
|
|
25751
|
+
toolCalls: "unknown",
|
|
25752
|
+
retries: "unknown",
|
|
25753
|
+
compactions: "unknown",
|
|
25754
|
+
modelSwitches: "unknown",
|
|
25755
|
+
promptBytes: Buffer.byteLength(compiled.prompt, "utf-8"),
|
|
25756
|
+
layerBytes: Object.fromEntries(compiled.layers.map((layer) => [
|
|
25757
|
+
layer.name,
|
|
25758
|
+
Buffer.byteLength(layer.content, "utf-8")
|
|
25759
|
+
])),
|
|
25760
|
+
durationMs: Date.now() - compileStartedAt
|
|
25761
|
+
}
|
|
25762
|
+
});
|
|
25763
|
+
if (!event.success) {
|
|
25764
|
+
return {
|
|
25765
|
+
code: 1,
|
|
25766
|
+
data: {
|
|
25767
|
+
success: false,
|
|
25768
|
+
command: "ccep compile",
|
|
25769
|
+
errors: [`Could not record compile telemetry: ${event.error.message}`]
|
|
25770
|
+
}
|
|
25771
|
+
};
|
|
25772
|
+
}
|
|
25773
|
+
}
|
|
25774
|
+
const representation = view === "prompt" ? { prompt: compiled.prompt } : view === "layers" ? { layers: compiled.layers } : { layers: compiled.layers, prompt: compiled.prompt };
|
|
25557
25775
|
return {
|
|
25558
25776
|
code: 0,
|
|
25559
25777
|
data: {
|
|
@@ -25561,10 +25779,9 @@ async function ccepCommand(options) {
|
|
|
25561
25779
|
command: "ccep compile",
|
|
25562
25780
|
phase: phaseId,
|
|
25563
25781
|
role: agentRole,
|
|
25564
|
-
outputSchema:
|
|
25782
|
+
outputSchema: compiled.outputSchema,
|
|
25565
25783
|
promptVersion,
|
|
25566
|
-
|
|
25567
|
-
prompt: compiled.prompt
|
|
25784
|
+
...representation
|
|
25568
25785
|
}
|
|
25569
25786
|
};
|
|
25570
25787
|
}
|
|
@@ -25818,9 +26035,11 @@ async function ccepCommand(options) {
|
|
|
25818
26035
|
};
|
|
25819
26036
|
}
|
|
25820
26037
|
}
|
|
26038
|
+
var CONTEXT_STRATEGIES;
|
|
25821
26039
|
var init_ccep_command = __esm(() => {
|
|
25822
26040
|
init_path_containment();
|
|
25823
26041
|
init_prompt_compiler();
|
|
26042
|
+
init_episodic_store();
|
|
25824
26043
|
init_output_validator();
|
|
25825
26044
|
init_command_parser();
|
|
25826
26045
|
init_context_resolver();
|
|
@@ -25828,6 +26047,7 @@ var init_ccep_command = __esm(() => {
|
|
|
25828
26047
|
init_council_consensus();
|
|
25829
26048
|
init_task_card_validator();
|
|
25830
26049
|
init_schemas();
|
|
26050
|
+
CONTEXT_STRATEGIES = ["sticky", "isolated", "artifact", "compact", "fork", "full"];
|
|
25831
26051
|
});
|
|
25832
26052
|
|
|
25833
26053
|
// src/core/openspec/backlog-validator.ts
|
|
@@ -25969,8 +26189,8 @@ var init_backlog_validator = __esm(() => {
|
|
|
25969
26189
|
});
|
|
25970
26190
|
|
|
25971
26191
|
// src/core/openspec/backlog-scanner.ts
|
|
25972
|
-
import { execFileSync
|
|
25973
|
-
import { readFile as
|
|
26192
|
+
import { execFileSync } from "node:child_process";
|
|
26193
|
+
import { readFile as readFile34 } from "node:fs/promises";
|
|
25974
26194
|
import { resolve as resolve31 } from "node:path";
|
|
25975
26195
|
function itemSnapshot(items) {
|
|
25976
26196
|
const snap = {};
|
|
@@ -25982,11 +26202,11 @@ function itemSnapshot(items) {
|
|
|
25982
26202
|
async function scanBacklog(projectRoot, previousSnapshot = {}) {
|
|
25983
26203
|
try {
|
|
25984
26204
|
const filePath = resolve31(projectRoot, BACKLOG_FILENAME);
|
|
25985
|
-
const content = await
|
|
26205
|
+
const content = await readFile34(filePath, "utf-8");
|
|
25986
26206
|
const hash = hashContent(content);
|
|
25987
26207
|
let fileChanged = true;
|
|
25988
26208
|
try {
|
|
25989
|
-
const diff =
|
|
26209
|
+
const diff = execFileSync("git", ["diff", "--name-only", "--", BACKLOG_FILENAME], {
|
|
25990
26210
|
cwd: projectRoot,
|
|
25991
26211
|
encoding: "utf-8",
|
|
25992
26212
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -26220,7 +26440,7 @@ var init_backlog_planner = __esm(() => {
|
|
|
26220
26440
|
|
|
26221
26441
|
// src/core/openspec/openspec-generator.ts
|
|
26222
26442
|
import { mkdir as mkdir22, rename as rename5, writeFile as writeFile22 } from "node:fs/promises";
|
|
26223
|
-
import { basename as
|
|
26443
|
+
import { basename as basename8, resolve as resolve32 } from "node:path";
|
|
26224
26444
|
function pad3(n) {
|
|
26225
26445
|
return String(n).padStart(3, "0");
|
|
26226
26446
|
}
|
|
@@ -26367,7 +26587,7 @@ capabilities:
|
|
|
26367
26587
|
}
|
|
26368
26588
|
async function archiveChangeFolder(projectRoot, changePath) {
|
|
26369
26589
|
const src = resolve32(projectRoot, changePath);
|
|
26370
|
-
const slug =
|
|
26590
|
+
const slug = basename8(changePath);
|
|
26371
26591
|
const destDir = resolve32(projectRoot, "openspec", "changes", "archive");
|
|
26372
26592
|
await mkdir22(destDir, { recursive: true });
|
|
26373
26593
|
const dest = resolve32(destDir, slug);
|
|
@@ -26392,8 +26612,8 @@ var init_openspec_generator = __esm(() => {
|
|
|
26392
26612
|
});
|
|
26393
26613
|
|
|
26394
26614
|
// src/core/openspec/spec-quality.ts
|
|
26395
|
-
import { readdir as readdir11, readFile as
|
|
26396
|
-
import { join as join23, relative as
|
|
26615
|
+
import { readdir as readdir11, readFile as readFile35 } from "node:fs/promises";
|
|
26616
|
+
import { join as join23, relative as relative10, resolve as resolve33 } from "node:path";
|
|
26397
26617
|
function uniqueIds(matches) {
|
|
26398
26618
|
return [...new Set(matches ?? [])];
|
|
26399
26619
|
}
|
|
@@ -26549,17 +26769,17 @@ async function assessChangeFolder(projectRoot, changePath) {
|
|
|
26549
26769
|
const extra = ["proposal.md", "design.md"].map((name) => join23(changeRoot, name));
|
|
26550
26770
|
const reports = [];
|
|
26551
26771
|
for (const file of specFiles) {
|
|
26552
|
-
const content = await
|
|
26553
|
-
reports.push(assessSpecMarkdown(content,
|
|
26772
|
+
const content = await readFile35(file, "utf-8");
|
|
26773
|
+
reports.push(assessSpecMarkdown(content, relative10(root, file).replace(/\\/g, "/")));
|
|
26554
26774
|
}
|
|
26555
26775
|
for (const file of extra) {
|
|
26556
26776
|
let content;
|
|
26557
26777
|
try {
|
|
26558
|
-
content = await
|
|
26778
|
+
content = await readFile35(file, "utf-8");
|
|
26559
26779
|
} catch {
|
|
26560
26780
|
continue;
|
|
26561
26781
|
}
|
|
26562
|
-
const rel =
|
|
26782
|
+
const rel = relative10(root, file).replace(/\\/g, "/");
|
|
26563
26783
|
if (PLACEHOLDER.test(content)) {
|
|
26564
26784
|
reports.push({
|
|
26565
26785
|
valid: false,
|
|
@@ -26610,7 +26830,7 @@ var init_spec_quality = __esm(() => {
|
|
|
26610
26830
|
});
|
|
26611
26831
|
|
|
26612
26832
|
// src/core/openspec/spec-analyzer.ts
|
|
26613
|
-
import { readFile as
|
|
26833
|
+
import { readFile as readFile36, readdir as readdir12 } from "node:fs/promises";
|
|
26614
26834
|
import { join as join24, resolve as resolve34 } from "node:path";
|
|
26615
26835
|
function unique(ids) {
|
|
26616
26836
|
return [...new Set(ids)];
|
|
@@ -26648,7 +26868,7 @@ async function readDeltaSpecs(specDir) {
|
|
|
26648
26868
|
if (entry.isDirectory()) {
|
|
26649
26869
|
contents.push(await readDeltaSpecs(path));
|
|
26650
26870
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
26651
|
-
contents.push(await
|
|
26871
|
+
contents.push(await readFile36(path, "utf-8"));
|
|
26652
26872
|
}
|
|
26653
26873
|
}
|
|
26654
26874
|
return contents.filter(Boolean).join(`
|
|
@@ -26730,13 +26950,13 @@ async function analyzeChangeFolder(projectRoot, changePath, options) {
|
|
|
26730
26950
|
const specMarkdown = await readDeltaSpecs(join24(changeRoot, "specs"));
|
|
26731
26951
|
let tasksMarkdown = "";
|
|
26732
26952
|
try {
|
|
26733
|
-
tasksMarkdown = await
|
|
26953
|
+
tasksMarkdown = await readFile36(join24(changeRoot, "tasks.md"), "utf-8");
|
|
26734
26954
|
} catch {
|
|
26735
26955
|
tasksMarkdown = "";
|
|
26736
26956
|
}
|
|
26737
26957
|
let designMarkdown;
|
|
26738
26958
|
try {
|
|
26739
|
-
designMarkdown = await
|
|
26959
|
+
designMarkdown = await readFile36(join24(changeRoot, "design.md"), "utf-8");
|
|
26740
26960
|
} catch {
|
|
26741
26961
|
designMarkdown = undefined;
|
|
26742
26962
|
}
|
|
@@ -26755,8 +26975,8 @@ var init_spec_analyzer = __esm(() => {
|
|
|
26755
26975
|
});
|
|
26756
26976
|
|
|
26757
26977
|
// src/core/openspec/spec-sync.ts
|
|
26758
|
-
import { mkdir as mkdir23, readFile as
|
|
26759
|
-
import { join as join25, relative as
|
|
26978
|
+
import { mkdir as mkdir23, readFile as readFile37, readdir as readdir13 } from "node:fs/promises";
|
|
26979
|
+
import { join as join25, relative as relative11, resolve as resolve35 } from "node:path";
|
|
26760
26980
|
async function markdownFiles(dir) {
|
|
26761
26981
|
let entries;
|
|
26762
26982
|
try {
|
|
@@ -26854,23 +27074,23 @@ async function syncChangeSpecs(projectRoot, changePath) {
|
|
|
26854
27074
|
}
|
|
26855
27075
|
const writes = [];
|
|
26856
27076
|
for (const file of files) {
|
|
26857
|
-
const delta = await
|
|
27077
|
+
const delta = await readFile37(file, "utf-8");
|
|
26858
27078
|
const requirements = deltaRequirements(delta);
|
|
26859
27079
|
if (requirements.length === 0) {
|
|
26860
27080
|
return {
|
|
26861
27081
|
success: false,
|
|
26862
27082
|
syncedPaths: [],
|
|
26863
|
-
errors: [`${
|
|
27083
|
+
errors: [`${relative11(root, file)}: no delta requirements found`]
|
|
26864
27084
|
};
|
|
26865
27085
|
}
|
|
26866
|
-
const relativeSpec =
|
|
27086
|
+
const relativeSpec = relative11(changeSpecs, file);
|
|
26867
27087
|
const target = join25(root, "openspec", "specs", relativeSpec);
|
|
26868
27088
|
let existing = `# ${relativeSpec.replace(/\\/g, "/")}
|
|
26869
27089
|
`;
|
|
26870
27090
|
try {
|
|
26871
|
-
existing = await
|
|
27091
|
+
existing = await readFile37(target, "utf-8");
|
|
26872
27092
|
} catch {}
|
|
26873
|
-
const merged = upsertRequirements(existing, requirements,
|
|
27093
|
+
const merged = upsertRequirements(existing, requirements, relative11(root, file));
|
|
26874
27094
|
if (!merged.ok)
|
|
26875
27095
|
return { success: false, syncedPaths: [], errors: [merged.error] };
|
|
26876
27096
|
writes.push({ path: target, content: merged.content });
|
|
@@ -26881,7 +27101,7 @@ async function syncChangeSpecs(projectRoot, changePath) {
|
|
|
26881
27101
|
}
|
|
26882
27102
|
return {
|
|
26883
27103
|
success: true,
|
|
26884
|
-
syncedPaths: writes.map((write) =>
|
|
27104
|
+
syncedPaths: writes.map((write) => relative11(root, write.path).replace(/\\/g, "/")),
|
|
26885
27105
|
errors: []
|
|
26886
27106
|
};
|
|
26887
27107
|
}
|
|
@@ -26897,7 +27117,7 @@ var exports_openspec_command = {};
|
|
|
26897
27117
|
__export(exports_openspec_command, {
|
|
26898
27118
|
openspecCommand: () => openspecCommand
|
|
26899
27119
|
});
|
|
26900
|
-
import { readFile as
|
|
27120
|
+
import { readFile as readFile38 } from "node:fs/promises";
|
|
26901
27121
|
import { resolve as resolve36 } from "node:path";
|
|
26902
27122
|
async function openspecCommand(options) {
|
|
26903
27123
|
const { subcommand, itemId, projectRoot, output, reason } = options;
|
|
@@ -26954,7 +27174,7 @@ async function persistState(projectRoot, state) {
|
|
|
26954
27174
|
return { ok: true };
|
|
26955
27175
|
}
|
|
26956
27176
|
async function readBacklogMarkdown(projectRoot) {
|
|
26957
|
-
return
|
|
27177
|
+
return readFile38(resolve36(projectRoot, BACKLOG_FILENAME), "utf-8");
|
|
26958
27178
|
}
|
|
26959
27179
|
async function transitionItem(projectRoot, item, to, progress) {
|
|
26960
27180
|
const content = await readBacklogMarkdown(projectRoot);
|
|
@@ -27152,7 +27372,7 @@ async function handleAnalyze(projectRoot, itemId) {
|
|
|
27152
27372
|
const policyParts = [];
|
|
27153
27373
|
for (const name of ["AGENTS.md", "BACKLOG.md"]) {
|
|
27154
27374
|
try {
|
|
27155
|
-
policyParts.push(await
|
|
27375
|
+
policyParts.push(await readFile38(resolve36(projectRoot, name), "utf-8"));
|
|
27156
27376
|
} catch {}
|
|
27157
27377
|
}
|
|
27158
27378
|
const cards = itemCards(stateResult.data, targetId);
|
|
@@ -27584,10 +27804,45 @@ function resumeDecision(changedPaths) {
|
|
|
27584
27804
|
}
|
|
27585
27805
|
var init_context_assembly = () => {};
|
|
27586
27806
|
|
|
27807
|
+
// src/core/ccep/handoff-envelope.ts
|
|
27808
|
+
function buildHandoffEnvelope(ledger, changedPaths) {
|
|
27809
|
+
return HandoffEnvelopeSchema.parse({
|
|
27810
|
+
version: 1,
|
|
27811
|
+
task: {
|
|
27812
|
+
id: ledger.taskCard.id,
|
|
27813
|
+
objective: ledger.taskCard.objective,
|
|
27814
|
+
acceptanceCriteria: ledger.taskCard.acceptanceCriteria,
|
|
27815
|
+
status: ledger.taskCard.status
|
|
27816
|
+
},
|
|
27817
|
+
decisions: {
|
|
27818
|
+
constraints: ledger.taskCard.constraints,
|
|
27819
|
+
unresolved: ledger.tasks.filter((task) => task.status === "blocked").map((task) => task.title)
|
|
27820
|
+
},
|
|
27821
|
+
scope: {
|
|
27822
|
+
relevantFiles: ledger.taskCard.targetFiles,
|
|
27823
|
+
boundaries: ledger.taskCard.boundaries
|
|
27824
|
+
},
|
|
27825
|
+
verification: { evidence: ledger.evidence },
|
|
27826
|
+
change: { touchedFiles: [...new Set(changedPaths)].sort() },
|
|
27827
|
+
next: {
|
|
27828
|
+
role: ledger.taskCard.agentType,
|
|
27829
|
+
objective: ledger.nextStep
|
|
27830
|
+
},
|
|
27831
|
+
sources: {
|
|
27832
|
+
deliveryLedger: ledger.id,
|
|
27833
|
+
memoryTopicKey: ledger.memoryTopicKey,
|
|
27834
|
+
technicalPlanPath: ledger.technicalPlanPath
|
|
27835
|
+
}
|
|
27836
|
+
});
|
|
27837
|
+
}
|
|
27838
|
+
var init_handoff_envelope = __esm(() => {
|
|
27839
|
+
init_schemas();
|
|
27840
|
+
});
|
|
27841
|
+
|
|
27587
27842
|
// src/core/delivery/delivery-ledger.ts
|
|
27588
27843
|
import { createHash as createHash7 } from "node:crypto";
|
|
27589
|
-
import { mkdir as mkdir24, readFile as
|
|
27590
|
-
import { resolve as resolve37, sep as
|
|
27844
|
+
import { mkdir as mkdir24, readFile as readFile39, writeFile as writeFile23 } from "node:fs/promises";
|
|
27845
|
+
import { resolve as resolve37, sep as sep8 } from "node:path";
|
|
27591
27846
|
function ledgerPath(projectRoot, id) {
|
|
27592
27847
|
if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(id))
|
|
27593
27848
|
throw new Error("Invalid delivery ledger id");
|
|
@@ -27598,12 +27853,12 @@ async function fingerprintWorkspace(projectRoot, paths) {
|
|
|
27598
27853
|
const fingerprints = {};
|
|
27599
27854
|
for (const path of paths) {
|
|
27600
27855
|
const candidate = resolve37(root, path);
|
|
27601
|
-
if (candidate !== root && !candidate.startsWith(`${root}${
|
|
27856
|
+
if (candidate !== root && !candidate.startsWith(`${root}${sep8}`)) {
|
|
27602
27857
|
fingerprints[path] = "outside-root";
|
|
27603
27858
|
continue;
|
|
27604
27859
|
}
|
|
27605
27860
|
try {
|
|
27606
|
-
fingerprints[path] = createHash7("sha256").update(await
|
|
27861
|
+
fingerprints[path] = createHash7("sha256").update(await readFile39(candidate)).digest("hex");
|
|
27607
27862
|
} catch {
|
|
27608
27863
|
fingerprints[path] = "missing";
|
|
27609
27864
|
}
|
|
@@ -27626,7 +27881,7 @@ function parseLedger(content) {
|
|
|
27626
27881
|
return DeliveryLedgerSchema.parse($parse(match[1]));
|
|
27627
27882
|
}
|
|
27628
27883
|
async function loadDeliveryLedger(projectRoot, id) {
|
|
27629
|
-
return parseLedger(await
|
|
27884
|
+
return parseLedger(await readFile39(ledgerPath(projectRoot, id), "utf-8"));
|
|
27630
27885
|
}
|
|
27631
27886
|
async function createDeliveryLedger(projectRoot, input) {
|
|
27632
27887
|
const request = DeliveryLedgerRequestSchema.parse(input);
|
|
@@ -27647,6 +27902,7 @@ async function createDeliveryLedger(projectRoot, input) {
|
|
|
27647
27902
|
nextStep: request.nextStep,
|
|
27648
27903
|
memoryTopicKey: `delivery:${request.id}`,
|
|
27649
27904
|
workspace: await fingerprintWorkspace(projectRoot, request.taskCard.targetFiles),
|
|
27905
|
+
technicalPlanPath: request.technicalPlanPath,
|
|
27650
27906
|
createdAt: now,
|
|
27651
27907
|
updatedAt: now
|
|
27652
27908
|
});
|
|
@@ -27678,6 +27934,28 @@ var exports_odd_command = {};
|
|
|
27678
27934
|
__export(exports_odd_command, {
|
|
27679
27935
|
oddCommand: () => oddCommand
|
|
27680
27936
|
});
|
|
27937
|
+
async function reconcileForResume(projectRoot, id) {
|
|
27938
|
+
const result = await reconcileDeliveryLedger(projectRoot, id);
|
|
27939
|
+
const memory = await loadMemoryIndex(projectRoot);
|
|
27940
|
+
const { rddCommand: rddCommand2 } = await Promise.resolve().then(() => (init_rdd_command(), exports_rdd_command));
|
|
27941
|
+
const rdd = await rddCommand2({
|
|
27942
|
+
subcommand: "status",
|
|
27943
|
+
projectRoot,
|
|
27944
|
+
taskId: result.ledger.taskCard.id
|
|
27945
|
+
});
|
|
27946
|
+
const receipts = rdd.data.receipts ?? [];
|
|
27947
|
+
const staleReceipt = receipts.some((receipt) => receipt.valid === false);
|
|
27948
|
+
const changedPaths = staleReceipt ? [...result.changedPaths, "RDD receipt"].sort() : result.changedPaths;
|
|
27949
|
+
return {
|
|
27950
|
+
...result,
|
|
27951
|
+
changedPaths,
|
|
27952
|
+
resume: resumeDecision(changedPaths),
|
|
27953
|
+
status: changedPaths.length === 0 ? "ready" : "conflict",
|
|
27954
|
+
rdd,
|
|
27955
|
+
memory: memory.success ? "available" : "unavailable",
|
|
27956
|
+
memoryPointers: memory.success ? memory.data.pointers.filter((pointer) => pointer.topic_key === result.ledger.memoryTopicKey) : []
|
|
27957
|
+
};
|
|
27958
|
+
}
|
|
27681
27959
|
async function oddCommand(options) {
|
|
27682
27960
|
if (options.subcommand === "create") {
|
|
27683
27961
|
let input = options.input;
|
|
@@ -27711,28 +27989,25 @@ async function oddCommand(options) {
|
|
|
27711
27989
|
return { code: 0, data: { success: true, ledger: await loadDeliveryLedger(options.projectRoot, options.id) } };
|
|
27712
27990
|
}
|
|
27713
27991
|
if (options.subcommand === "reconcile") {
|
|
27714
|
-
const result = await
|
|
27715
|
-
const memory = await loadMemoryIndex(options.projectRoot);
|
|
27716
|
-
const { rddCommand: rddCommand2 } = await Promise.resolve().then(() => (init_rdd_command(), exports_rdd_command));
|
|
27717
|
-
const rdd = await rddCommand2({
|
|
27718
|
-
subcommand: "status",
|
|
27719
|
-
projectRoot: options.projectRoot,
|
|
27720
|
-
taskId: result.ledger.taskCard.id
|
|
27721
|
-
});
|
|
27722
|
-
const receipts = rdd.data.receipts ?? [];
|
|
27723
|
-
const staleReceipt = receipts.some((receipt) => receipt.valid === false);
|
|
27724
|
-
const changedPaths = staleReceipt ? [...result.changedPaths, "RDD receipt"].sort() : result.changedPaths;
|
|
27992
|
+
const result = await reconcileForResume(options.projectRoot, options.id);
|
|
27725
27993
|
return {
|
|
27726
27994
|
code: 0,
|
|
27727
27995
|
data: {
|
|
27728
27996
|
success: true,
|
|
27729
|
-
|
|
27730
|
-
|
|
27731
|
-
|
|
27732
|
-
|
|
27733
|
-
|
|
27734
|
-
|
|
27735
|
-
|
|
27997
|
+
...result
|
|
27998
|
+
}
|
|
27999
|
+
};
|
|
28000
|
+
}
|
|
28001
|
+
if (options.subcommand === "handoff") {
|
|
28002
|
+
const result = await reconcileForResume(options.projectRoot, options.id);
|
|
28003
|
+
return {
|
|
28004
|
+
code: 0,
|
|
28005
|
+
data: {
|
|
28006
|
+
success: true,
|
|
28007
|
+
status: result.status,
|
|
28008
|
+
changedPaths: result.changedPaths,
|
|
28009
|
+
resume: result.resume,
|
|
28010
|
+
handoff: buildHandoffEnvelope(result.ledger, result.changedPaths)
|
|
27736
28011
|
}
|
|
27737
28012
|
};
|
|
27738
28013
|
}
|
|
@@ -27744,6 +28019,7 @@ async function oddCommand(options) {
|
|
|
27744
28019
|
var init_odd_command = __esm(() => {
|
|
27745
28020
|
init_memory_index();
|
|
27746
28021
|
init_context_assembly();
|
|
28022
|
+
init_handoff_envelope();
|
|
27747
28023
|
init_task_card_validator();
|
|
27748
28024
|
init_workflow_profile_loader();
|
|
27749
28025
|
init_delivery_ledger();
|
|
@@ -27755,7 +28031,11 @@ function normalizeCommand(raw) {
|
|
|
27755
28031
|
return raw.replace(/\s+/g, " ").trim();
|
|
27756
28032
|
}
|
|
27757
28033
|
function stripGitBinary(command) {
|
|
27758
|
-
|
|
28034
|
+
const match = command.match(/^(?:&\s*)?("[^"]+"|'[^']+'|[^\s]+)([\s\S]*)$/);
|
|
28035
|
+
if (!match)
|
|
28036
|
+
return command;
|
|
28037
|
+
const binary = match[1].replace(/^["']|["']$/g, "").replace(/\\/g, "/").split("/").pop();
|
|
28038
|
+
return /^git(?:\.exe)?$/i.test(binary ?? "") ? `git${match[2]}` : command;
|
|
27759
28039
|
}
|
|
27760
28040
|
function evaluatePath(filePath) {
|
|
27761
28041
|
if (SENSITIVE_PATH.test(filePath.replace(/\//g, "\\")) || SENSITIVE_PATH.test(filePath)) {
|
|
@@ -27764,9 +28044,44 @@ function evaluatePath(filePath) {
|
|
|
27764
28044
|
return allow();
|
|
27765
28045
|
}
|
|
27766
28046
|
function evaluateCommand(rawCommand) {
|
|
27767
|
-
|
|
28047
|
+
if (/(?:curl|wget)\b.+\|\s*(sh|bash|zsh|cmd)\b/i.test(normalizeCommand(rawCommand)))
|
|
28048
|
+
return deny(MSG_POLICY);
|
|
28049
|
+
const tokens = rawCommand.match(/"[^"]*"|'[^']*'|[^"';&|\r\n]+|[;&|\r\n]+/g) ?? [];
|
|
28050
|
+
const commands = [];
|
|
28051
|
+
let current = "";
|
|
28052
|
+
for (const token of tokens) {
|
|
28053
|
+
if (/^[;&|\r\n]+$/.test(token) && !(token === "&" && !current.trim())) {
|
|
28054
|
+
commands.push(current);
|
|
28055
|
+
current = "";
|
|
28056
|
+
} else {
|
|
28057
|
+
current += token;
|
|
28058
|
+
}
|
|
28059
|
+
}
|
|
28060
|
+
commands.push(current);
|
|
28061
|
+
let verdict = allow();
|
|
28062
|
+
for (const part of commands) {
|
|
28063
|
+
const result = evaluateSingleCommand(part);
|
|
28064
|
+
if (result.action === "deny")
|
|
28065
|
+
return result;
|
|
28066
|
+
if (result.action === "ask")
|
|
28067
|
+
verdict = result;
|
|
28068
|
+
}
|
|
28069
|
+
return verdict;
|
|
28070
|
+
}
|
|
28071
|
+
function evaluateSingleCommand(rawCommand) {
|
|
28072
|
+
let command = stripGitBinary(normalizeCommand(rawCommand));
|
|
27768
28073
|
if (!command)
|
|
27769
28074
|
return allow();
|
|
28075
|
+
if (/^git\s/i.test(command)) {
|
|
28076
|
+
const words = command.match(/"[^"]*"|'[^']*'|\S+/g) ?? [];
|
|
28077
|
+
let index = 1;
|
|
28078
|
+
while (words[index]?.startsWith("-")) {
|
|
28079
|
+
const option = words[index++];
|
|
28080
|
+
if (/^(?:-C|-c|--git-dir|--work-tree|--namespace)$/.test(option))
|
|
28081
|
+
index++;
|
|
28082
|
+
}
|
|
28083
|
+
command = ["git", ...words.slice(index)].join(" ");
|
|
28084
|
+
}
|
|
27770
28085
|
if (SENSITIVE_PATH.test(command) && READ_LIKE.test(command)) {
|
|
27771
28086
|
return deny(MSG_SECRET);
|
|
27772
28087
|
}
|
|
@@ -27789,9 +28104,12 @@ function evaluateCommand(rawCommand) {
|
|
|
27789
28104
|
}
|
|
27790
28105
|
if (/^rm\s+-rf\s+(\*|[\\/])/i.test(command))
|
|
27791
28106
|
return deny(MSG_POLICY);
|
|
27792
|
-
|
|
28107
|
+
const windowsTarget = /(?:^|\s)["']?(?:[a-z]:[\\/]|\\|\*)/i.test(command);
|
|
28108
|
+
if (windowsTarget && /^Remove-Item\b/i.test(command) && /\s-(?:Recurse|r)\b/i.test(command) && /\s-(?:Force|f)\b/i.test(command))
|
|
27793
28109
|
return deny(MSG_POLICY);
|
|
27794
|
-
if (
|
|
28110
|
+
if (windowsTarget && /^(?:rd|rmdir|del|erase)\b/i.test(command) && /\s\/s\b/i.test(command))
|
|
28111
|
+
return deny(MSG_POLICY);
|
|
28112
|
+
if (/^sudo\s+/i.test(command))
|
|
27795
28113
|
return deny(MSG_POLICY);
|
|
27796
28114
|
if (/^chmod\s+777\b/i.test(command))
|
|
27797
28115
|
return deny(MSG_POLICY);
|
|
@@ -27818,13 +28136,16 @@ function evaluatePreTool(input) {
|
|
|
27818
28136
|
function formatHookOutput(verdict, format) {
|
|
27819
28137
|
if (format === "agy") {
|
|
27820
28138
|
if (verdict.action === "deny") {
|
|
27821
|
-
return JSON.stringify({ decision: "deny",
|
|
28139
|
+
return JSON.stringify({ decision: "deny", reason: verdict.message });
|
|
27822
28140
|
}
|
|
27823
28141
|
if (verdict.action === "ask") {
|
|
27824
28142
|
return JSON.stringify({ decision: "ask" });
|
|
27825
28143
|
}
|
|
27826
28144
|
return JSON.stringify({ decision: "allow" });
|
|
27827
28145
|
}
|
|
28146
|
+
if (verdict.action === "ask") {
|
|
28147
|
+
return JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "ask" } });
|
|
28148
|
+
}
|
|
27828
28149
|
return "";
|
|
27829
28150
|
}
|
|
27830
28151
|
function claudeExitCode(verdict) {
|
|
@@ -27835,11 +28156,24 @@ function parseAgyPayload(raw) {
|
|
|
27835
28156
|
return {};
|
|
27836
28157
|
try {
|
|
27837
28158
|
const parsed = JSON.parse(raw);
|
|
27838
|
-
const args = parsed.arguments ?? {};
|
|
28159
|
+
const args = parsed.toolCall?.args ?? parsed.arguments ?? {};
|
|
28160
|
+
return {
|
|
28161
|
+
toolName: typeof (parsed.toolCall?.name ?? parsed.toolName) === "string" ? parsed.toolCall?.name ?? parsed.toolName : undefined,
|
|
28162
|
+
command: typeof args.CommandLine === "string" ? args.CommandLine : undefined,
|
|
28163
|
+
filePath: typeof args.TargetFile === "string" ? args.TargetFile : typeof args.AbsolutePath === "string" ? args.AbsolutePath : undefined
|
|
28164
|
+
};
|
|
28165
|
+
} catch {
|
|
28166
|
+
return {};
|
|
28167
|
+
}
|
|
28168
|
+
}
|
|
28169
|
+
function parseClaudePayload(raw) {
|
|
28170
|
+
try {
|
|
28171
|
+
const parsed = JSON.parse(raw);
|
|
28172
|
+
const input = parsed.tool_input ?? {};
|
|
27839
28173
|
return {
|
|
27840
|
-
toolName: parsed.
|
|
27841
|
-
command:
|
|
27842
|
-
filePath:
|
|
28174
|
+
toolName: typeof parsed.tool_name === "string" ? parsed.tool_name : undefined,
|
|
28175
|
+
command: typeof input.command === "string" ? input.command : undefined,
|
|
28176
|
+
filePath: typeof input.file_path === "string" ? input.file_path : undefined
|
|
27843
28177
|
};
|
|
27844
28178
|
} catch {
|
|
27845
28179
|
return {};
|
|
@@ -27890,7 +28224,7 @@ function isDestructiveRestore(command) {
|
|
|
27890
28224
|
}
|
|
27891
28225
|
var SENSITIVE_PATH, READ_LIKE, MSG_SECRET = "Bloqueado: intento de leer archivos sensibles", MSG_AUTHORITY = "Bloqueado: El agente no tiene autoridad sobre este comando.", MSG_POLICY = "Bloqueado: Command violated security policy";
|
|
27892
28226
|
var init_hook_runner = __esm(() => {
|
|
27893
|
-
SENSITIVE_PATH = /(?:\.env\b|secrets[/\\]|id_rsa|\.pem\b|\.key\b|(?:^|[/\\])\.ssh(?:[/\\]|$)|(?:^|[/\\])\.aws(?:[/\\]|$)|(?:^|[/\\])\.kube(?:[/\\]|$))/i;
|
|
28227
|
+
SENSITIVE_PATH = /(?:\.env(?!\.example(?:$|[/\\]))\b|secrets[/\\]|id_rsa|\.pem\b|\.key\b|(?:^|[/\\])\.ssh(?:[/\\]|$)|(?:^|[/\\])\.aws(?:[/\\]|$)|(?:^|[/\\])\.kube(?:[/\\]|$))/i;
|
|
27894
28228
|
READ_LIKE = /(?:^|[\s;&|])(cat|less|more|head|tail|type|Get-Content|cp|copy|mv|move|scp)\b/i;
|
|
27895
28229
|
});
|
|
27896
28230
|
|
|
@@ -27901,14 +28235,17 @@ __export(exports_hook_command, {
|
|
|
27901
28235
|
readStdinText: () => readStdinText
|
|
27902
28236
|
});
|
|
27903
28237
|
import { spawnSync } from "node:child_process";
|
|
27904
|
-
import { existsSync as existsSync8 } from "node:fs";
|
|
27905
|
-
import {
|
|
28238
|
+
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "node:fs";
|
|
28239
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
28240
|
+
import { dirname as dirname13, resolve as resolve38 } from "node:path";
|
|
27906
28241
|
function detectFormat(explicit, stdinText) {
|
|
27907
28242
|
if (explicit)
|
|
27908
28243
|
return explicit;
|
|
27909
|
-
|
|
27910
|
-
|
|
27911
|
-
|
|
28244
|
+
try {
|
|
28245
|
+
const payload = JSON.parse(stdinText);
|
|
28246
|
+
if (payload && (("toolCall" in payload) || ("toolName" in payload) || ("workspacePaths" in payload)))
|
|
28247
|
+
return "agy";
|
|
28248
|
+
} catch {}
|
|
27912
28249
|
return "claude";
|
|
27913
28250
|
}
|
|
27914
28251
|
async function readStdinText() {
|
|
@@ -27920,11 +28257,11 @@ async function readStdinText() {
|
|
|
27920
28257
|
}
|
|
27921
28258
|
return Buffer.concat(chunks).toString("utf8");
|
|
27922
28259
|
}
|
|
27923
|
-
function resolvePreToolInput(options, stdinText) {
|
|
27924
|
-
const fromStdin = parseAgyPayload(stdinText);
|
|
28260
|
+
function resolvePreToolInput(options, stdinText, format) {
|
|
28261
|
+
const fromStdin = format === "agy" ? parseAgyPayload(stdinText) : parseClaudePayload(stdinText);
|
|
27925
28262
|
return {
|
|
27926
|
-
command: options.command ?? process.env.CLAUDE_TOOL_INPUT_COMMAND ?? fromStdin.command,
|
|
27927
|
-
filePath: options.filePath ?? process.env.CLAUDE_TOOL_INPUT_FILE_PATH ?? fromStdin.filePath,
|
|
28263
|
+
command: options.command ?? (process.env.CLAUDE_TOOL_INPUT_COMMAND || undefined) ?? fromStdin.command,
|
|
28264
|
+
filePath: options.filePath ?? (process.env.CLAUDE_TOOL_INPUT_FILE_PATH || undefined) ?? fromStdin.filePath,
|
|
27928
28265
|
toolName: fromStdin.toolName
|
|
27929
28266
|
};
|
|
27930
28267
|
}
|
|
@@ -27951,15 +28288,15 @@ async function hookCommand(options) {
|
|
|
27951
28288
|
return { code: 0, data: { success: true, command: "hook session-start" } };
|
|
27952
28289
|
}
|
|
27953
28290
|
if (event === "post-tool") {
|
|
27954
|
-
const filePath = options
|
|
27955
|
-
formatWrittenFile(filePath);
|
|
28291
|
+
const filePath = resolvePreToolInput(options, stdinText, format).filePath;
|
|
28292
|
+
formatWrittenFile(filePath, options.projectRoot);
|
|
27956
28293
|
if (format === "agy") {
|
|
27957
28294
|
process.stdout.write(`{}
|
|
27958
28295
|
`);
|
|
27959
28296
|
}
|
|
27960
28297
|
return { code: 0, data: { success: true, command: "hook post-tool" } };
|
|
27961
28298
|
}
|
|
27962
|
-
const input = resolvePreToolInput(options, stdinText);
|
|
28299
|
+
const input = resolvePreToolInput(options, stdinText, format);
|
|
27963
28300
|
const verdict = evaluatePreTool(input);
|
|
27964
28301
|
if (format === "agy") {
|
|
27965
28302
|
process.stdout.write(`${formatHookOutput(verdict, "agy")}
|
|
@@ -27973,23 +28310,40 @@ async function hookCommand(options) {
|
|
|
27973
28310
|
process.stderr.write(`${verdict.message}
|
|
27974
28311
|
`);
|
|
27975
28312
|
}
|
|
28313
|
+
const output = formatHookOutput(verdict, "claude");
|
|
28314
|
+
if (output)
|
|
28315
|
+
process.stdout.write(`${output}
|
|
28316
|
+
`);
|
|
27976
28317
|
return {
|
|
27977
28318
|
code: claudeExitCode(verdict),
|
|
27978
28319
|
data: { success: verdict.action !== "deny", command: "hook pre-tool", verdict }
|
|
27979
28320
|
};
|
|
27980
28321
|
}
|
|
27981
|
-
function formatWrittenFile(filePath) {
|
|
27982
|
-
if (!filePath
|
|
28322
|
+
function formatWrittenFile(filePath, projectRoot) {
|
|
28323
|
+
if (!filePath)
|
|
28324
|
+
return;
|
|
28325
|
+
filePath = resolve38(projectRoot, filePath);
|
|
28326
|
+
if (!existsSync8(filePath))
|
|
27983
28327
|
return;
|
|
27984
28328
|
const prettier = /\.(ts|tsx|js|jsx|mjs|cjs|json|jsonc|md|mdx|css|scss|html|astro|ya?ml)$/i;
|
|
27985
28329
|
const eslint = /\.(ts|tsx|js|jsx|mjs|cjs)$/i;
|
|
27986
28330
|
const python = /\.py$/i;
|
|
27987
|
-
const opts = { stdio: "ignore", windowsHide: true };
|
|
28331
|
+
const opts = { cwd: projectRoot, stdio: "ignore", windowsHide: true, timeout: 5000 };
|
|
28332
|
+
const require2 = createRequire2(resolve38(projectRoot, "package.json"));
|
|
28333
|
+
function runNodeTool(name, args) {
|
|
28334
|
+
try {
|
|
28335
|
+
const manifestPath = require2.resolve(`${name}/package.json`);
|
|
28336
|
+
const manifest = JSON.parse(readFileSync5(manifestPath, "utf8"));
|
|
28337
|
+
const bin = typeof manifest.bin === "string" ? manifest.bin : manifest.bin?.[name];
|
|
28338
|
+
if (typeof bin === "string")
|
|
28339
|
+
spawnSync(process.execPath, [resolve38(dirname13(manifestPath), bin), ...args], opts);
|
|
28340
|
+
} catch {}
|
|
28341
|
+
}
|
|
27988
28342
|
if (prettier.test(filePath)) {
|
|
27989
|
-
|
|
28343
|
+
runNodeTool("prettier", ["--write", filePath]);
|
|
27990
28344
|
}
|
|
27991
28345
|
if (eslint.test(filePath)) {
|
|
27992
|
-
|
|
28346
|
+
runNodeTool("eslint", ["--fix", filePath]);
|
|
27993
28347
|
}
|
|
27994
28348
|
if (python.test(filePath)) {
|
|
27995
28349
|
spawnSync("ruff", ["format", filePath], opts);
|
|
@@ -28396,7 +28750,7 @@ function ccGainToScorecardImpact(result) {
|
|
|
28396
28750
|
}
|
|
28397
28751
|
|
|
28398
28752
|
// src/core/evaluation/scorecard-signals.ts
|
|
28399
|
-
import { execFileSync as
|
|
28753
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
28400
28754
|
function parseScopeFiles(scope) {
|
|
28401
28755
|
return scope.split(/[,;]/).map((entry) => entry.trim().replace(/[.;:]$/, "").replace(/^`|`$/g, "")).filter(Boolean);
|
|
28402
28756
|
}
|
|
@@ -28426,7 +28780,7 @@ function collectScorecardSignals(projectRoot, scopeFiles, extra) {
|
|
|
28426
28780
|
}
|
|
28427
28781
|
let diff = "";
|
|
28428
28782
|
try {
|
|
28429
|
-
diff =
|
|
28783
|
+
diff = execFileSync2("git", ["diff", "HEAD"], {
|
|
28430
28784
|
cwd: projectRoot,
|
|
28431
28785
|
encoding: "utf-8",
|
|
28432
28786
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -28521,8 +28875,8 @@ var init_scorecard_signals = __esm(() => {
|
|
|
28521
28875
|
|
|
28522
28876
|
// src/core/evaluation/harness-experiment.ts
|
|
28523
28877
|
import { existsSync as existsSync9 } from "node:fs";
|
|
28524
|
-
import { cp, mkdir as mkdir25, readFile as
|
|
28525
|
-
import { dirname as
|
|
28878
|
+
import { cp, mkdir as mkdir25, readFile as readFile40, readdir as readdir14, writeFile as writeFile24 } from "node:fs/promises";
|
|
28879
|
+
import { dirname as dirname14, join as join26, resolve as resolve39 } from "node:path";
|
|
28526
28880
|
function experimentDir(projectRoot, experimentId) {
|
|
28527
28881
|
return resolve39(projectRoot, EVAL_DIR2, EXPERIMENTS_DIR, experimentId);
|
|
28528
28882
|
}
|
|
@@ -28538,7 +28892,7 @@ async function loadHarnessSuite(projectRoot, suiteId, suitePath) {
|
|
|
28538
28892
|
if (!existsSync9(path))
|
|
28539
28893
|
continue;
|
|
28540
28894
|
try {
|
|
28541
|
-
const suite = HarnessSuiteSchema.parse($parse(await
|
|
28895
|
+
const suite = HarnessSuiteSchema.parse($parse(await readFile40(path, "utf-8")));
|
|
28542
28896
|
return ok({ ...suite, path });
|
|
28543
28897
|
} catch (e) {
|
|
28544
28898
|
return err(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -28548,7 +28902,7 @@ async function loadHarnessSuite(projectRoot, suiteId, suitePath) {
|
|
|
28548
28902
|
}
|
|
28549
28903
|
async function loadExperiment(projectRoot, experimentId) {
|
|
28550
28904
|
try {
|
|
28551
|
-
const raw = await
|
|
28905
|
+
const raw = await readFile40(experimentYamlPath(projectRoot, experimentId), "utf-8");
|
|
28552
28906
|
return ok(HarnessExperimentSchema.parse($parse(raw)));
|
|
28553
28907
|
} catch (e) {
|
|
28554
28908
|
if (e.code === "ENOENT") {
|
|
@@ -28637,7 +28991,7 @@ function generateExperimentId(suiteId, now = new Date) {
|
|
|
28637
28991
|
return `abl-${date}-${suiteId}-${rand}`;
|
|
28638
28992
|
}
|
|
28639
28993
|
async function copyFixture(suitePath, fixtureDir, dest) {
|
|
28640
|
-
const source = fixtureDir ? resolve39(
|
|
28994
|
+
const source = fixtureDir ? resolve39(dirname14(suitePath), fixtureDir) : join26(dirname14(suitePath), "fixture");
|
|
28641
28995
|
await mkdir25(dest, { recursive: true });
|
|
28642
28996
|
if (existsSync9(source)) {
|
|
28643
28997
|
await cp(source, dest, { recursive: true });
|
|
@@ -28823,11 +29177,11 @@ var init_suite_run = __esm(() => {
|
|
|
28823
29177
|
});
|
|
28824
29178
|
|
|
28825
29179
|
// src/core/evaluation/execution-profile.ts
|
|
28826
|
-
import { readFile as
|
|
29180
|
+
import { readFile as readFile41 } from "node:fs/promises";
|
|
28827
29181
|
import { resolve as resolve41 } from "node:path";
|
|
28828
29182
|
async function loadExecutionProfile(projectRoot, defaultTarget = "opencode") {
|
|
28829
29183
|
try {
|
|
28830
|
-
const content = await
|
|
29184
|
+
const content = await readFile41(resolve41(projectRoot, PROFILE_FILE), "utf-8");
|
|
28831
29185
|
const data = $parse(content);
|
|
28832
29186
|
return ExecutionProfileSchema.parse(data);
|
|
28833
29187
|
} catch {
|
|
@@ -28907,7 +29261,7 @@ var init_execution_profile = __esm(() => {
|
|
|
28907
29261
|
});
|
|
28908
29262
|
|
|
28909
29263
|
// src/core/evaluation/prompt-diff.ts
|
|
28910
|
-
import { readFile as
|
|
29264
|
+
import { readFile as readFile42, readdir as readdir15 } from "node:fs/promises";
|
|
28911
29265
|
import { join as join27, resolve as resolve42 } from "node:path";
|
|
28912
29266
|
function normalizeVersion(v) {
|
|
28913
29267
|
return v.startsWith("v") ? v : `v${v}`;
|
|
@@ -28967,7 +29321,7 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
|
|
|
28967
29321
|
const f = join27(root, fromV);
|
|
28968
29322
|
const t = join27(root, toV);
|
|
28969
29323
|
try {
|
|
28970
|
-
await
|
|
29324
|
+
await readFile42(join27(f, "orchestrator.md"), "utf-8");
|
|
28971
29325
|
fromDir = f;
|
|
28972
29326
|
toDir = t;
|
|
28973
29327
|
break;
|
|
@@ -28978,7 +29332,7 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
|
|
|
28978
29332
|
toDir = join27(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
|
|
28979
29333
|
} else {
|
|
28980
29334
|
try {
|
|
28981
|
-
await
|
|
29335
|
+
await readFile42(join27(toDir, "orchestrator.md"), "utf-8");
|
|
28982
29336
|
} catch {
|
|
28983
29337
|
toDir = join27(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
|
|
28984
29338
|
}
|
|
@@ -28998,12 +29352,12 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
|
|
|
28998
29352
|
let oldText = "";
|
|
28999
29353
|
let newText = "";
|
|
29000
29354
|
try {
|
|
29001
|
-
oldText = await
|
|
29355
|
+
oldText = await readFile42(join27(fromDir, name), "utf-8");
|
|
29002
29356
|
} catch {
|
|
29003
29357
|
oldText = "";
|
|
29004
29358
|
}
|
|
29005
29359
|
try {
|
|
29006
|
-
newText = await
|
|
29360
|
+
newText = await readFile42(join27(toDir, name), "utf-8");
|
|
29007
29361
|
} catch {
|
|
29008
29362
|
newText = "";
|
|
29009
29363
|
}
|
|
@@ -29042,13 +29396,13 @@ var init_prompt_diff = __esm(() => {
|
|
|
29042
29396
|
});
|
|
29043
29397
|
|
|
29044
29398
|
// src/core/evaluation/regression-checklist.ts
|
|
29045
|
-
import { execFileSync as
|
|
29046
|
-
import { mkdir as mkdir26, readFile as
|
|
29047
|
-
import { dirname as
|
|
29399
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
29400
|
+
import { mkdir as mkdir26, readFile as readFile43, writeFile as writeFile25 } from "node:fs/promises";
|
|
29401
|
+
import { dirname as dirname15, resolve as resolve43 } from "node:path";
|
|
29048
29402
|
async function loadRegressionChecklist() {
|
|
29049
29403
|
try {
|
|
29050
29404
|
const path = resolve43(ROOT_PRESETS_DIR, "templates", "regression-checklist.yml");
|
|
29051
|
-
const content = await
|
|
29405
|
+
const content = await readFile43(path, "utf-8");
|
|
29052
29406
|
const data = $parse(content);
|
|
29053
29407
|
return data.checks ?? [];
|
|
29054
29408
|
} catch {
|
|
@@ -29062,7 +29416,7 @@ function runCheckCommand(cmd, cwd) {
|
|
|
29062
29416
|
if (!file)
|
|
29063
29417
|
return { passed: false, message: "Empty command" };
|
|
29064
29418
|
try {
|
|
29065
|
-
|
|
29419
|
+
execFileSync3(file, args, {
|
|
29066
29420
|
cwd,
|
|
29067
29421
|
encoding: "utf-8",
|
|
29068
29422
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -29104,7 +29458,7 @@ async function runRegressionChecklist(projectRoot, options = {}) {
|
|
|
29104
29458
|
timestamp: new Date().toISOString()
|
|
29105
29459
|
};
|
|
29106
29460
|
const outPath = resolve43(projectRoot, ".codeconductor/evaluation/regression-last.json");
|
|
29107
|
-
await mkdir26(
|
|
29461
|
+
await mkdir26(dirname15(outPath), { recursive: true });
|
|
29108
29462
|
await writeFile25(outPath, JSON.stringify(report, null, 2), "utf-8");
|
|
29109
29463
|
return ok(report);
|
|
29110
29464
|
} catch (e) {
|
|
@@ -29378,7 +29732,7 @@ var exports_scorecard_command = {};
|
|
|
29378
29732
|
__export(exports_scorecard_command, {
|
|
29379
29733
|
scorecardCommand: () => scorecardCommand
|
|
29380
29734
|
});
|
|
29381
|
-
import { readFile as
|
|
29735
|
+
import { readFile as readFile44 } from "node:fs/promises";
|
|
29382
29736
|
import { resolve as resolve46 } from "node:path";
|
|
29383
29737
|
function contractVersion() {
|
|
29384
29738
|
return package_default.version;
|
|
@@ -29669,7 +30023,7 @@ async function handleCompareModels(projectRoot, options) {
|
|
|
29669
30023
|
const markdown = generateModelComparisonMarkdown(outcomes, options.modelsFilter);
|
|
29670
30024
|
const templatePath = resolve46(projectRoot, ".codeconductor/evaluation/model-comparison-last.md");
|
|
29671
30025
|
try {
|
|
29672
|
-
await
|
|
30026
|
+
await readFile44(templatePath);
|
|
29673
30027
|
} catch {}
|
|
29674
30028
|
const { writeFile: writeFile28, mkdir: mkdir28 } = await import("node:fs/promises");
|
|
29675
30029
|
await mkdir28(resolve46(projectRoot, ".codeconductor/evaluation"), { recursive: true });
|
|
@@ -31516,6 +31870,7 @@ var COMMANDS = [
|
|
|
31516
31870
|
{ name: "setup", group: "getting-started", summary: "Configure and install CodeConductor.", usage: ["cc-codeconductor setup [--target <target>] [--locale en|es] [--yes] [--dry-run]"] },
|
|
31517
31871
|
{ name: "detect", group: "getting-started", summary: "Inspect the project stack and recommended presets.", usage: ["cc-codeconductor detect"] },
|
|
31518
31872
|
{ name: "init", group: "getting-started", summary: "Initialize low-level CodeConductor configuration.", usage: ["cc-codeconductor init [--locale en|es]"] },
|
|
31873
|
+
{ name: "usage", group: "getting-started", summary: "Show installation examples for presets, council, and LSP.", usage: ["cc-codeconductor usage"] },
|
|
31519
31874
|
{ name: "install", group: "getting-started", summary: "Install harness components.", usage: ["cc-codeconductor install preset --target <target>"], options: ["--target opencode|claude|codex|gemini|cursor|agy|pi|all"], subcommands: [
|
|
31520
31875
|
{ name: "preset", group: "getting-started", summary: "Install agents, prompts, skills, and commands.", usage: ["cc-codeconductor install preset --target <target> [--locale en|es]"] },
|
|
31521
31876
|
{ name: "council", group: "getting-started", summary: "Install generated council files.", usage: ["cc-codeconductor install council --target <target>"] },
|
|
@@ -31535,6 +31890,7 @@ var COMMANDS = [
|
|
|
31535
31890
|
{ name: "ingest", group: "workflow", summary: "Ingest repository knowledge into the product graph.", usage: ["cc-codeconductor ingest"] },
|
|
31536
31891
|
{ name: "product", group: "workflow", summary: "Explore the product graph and memory.", usage: ["cc-codeconductor product <subcommand>"] },
|
|
31537
31892
|
{ name: "ccep", group: "workflow", summary: "Run CCEP contract workflows.", usage: ["cc-codeconductor ccep <subcommand>"] },
|
|
31893
|
+
{ name: "odd", group: "workflow", summary: "Create, resume, and hand off tracked delivery work.", usage: ["cc-codeconductor odd <create|read|reconcile|handoff>"] },
|
|
31538
31894
|
{ name: "openspec", group: "workflow", summary: "Run the OpenSpec delivery loop.", usage: ["cc-codeconductor openspec <subcommand>"] },
|
|
31539
31895
|
{ name: "scorecard", group: "workflow", summary: "Record and aggregate outcomes.", usage: ["cc-codeconductor scorecard <subcommand>"] },
|
|
31540
31896
|
{ name: "orchestrate", group: "workflow", summary: "Run goal execution orchestration.", usage: ["cc-codeconductor orchestrate <subcommand>"] },
|
|
@@ -31629,11 +31985,102 @@ _arguments '1:command:(${names})' '--target[target]:target:(${targets})'`;
|
|
|
31629
31985
|
return null;
|
|
31630
31986
|
}
|
|
31631
31987
|
|
|
31988
|
+
// src/cli/usage-guide.ts
|
|
31989
|
+
init_cli_bin();
|
|
31990
|
+
var RECOMMENDED_FLOW = [
|
|
31991
|
+
"cc-codeconductor setup --target claude",
|
|
31992
|
+
"cc-codeconductor setup --target claude --locale es --yes",
|
|
31993
|
+
"cc-codeconductor setup --target claude --dry-run"
|
|
31994
|
+
];
|
|
31995
|
+
var PRIMITIVES = [
|
|
31996
|
+
"cc-codeconductor detect",
|
|
31997
|
+
"cc-codeconductor init --locale es",
|
|
31998
|
+
"cc-codeconductor install preset --target claude",
|
|
31999
|
+
"cc-codeconductor install council --target claude",
|
|
32000
|
+
"cc-codeconductor install lsp --target claude"
|
|
32001
|
+
];
|
|
32002
|
+
var PRESET_EXAMPLES = [
|
|
32003
|
+
"cc-codeconductor install preset --target claude",
|
|
32004
|
+
"cc-codeconductor install preset --target claude --global",
|
|
32005
|
+
"cc-codeconductor install preset --target claude --force",
|
|
32006
|
+
"cc-codeconductor install preset --target claude --dry-run",
|
|
32007
|
+
"cc-codeconductor install preset --target all",
|
|
32008
|
+
"cc-codeconductor install preset --target claude --locale es",
|
|
32009
|
+
"cc-codeconductor install preset --target claude --global --force"
|
|
32010
|
+
];
|
|
32011
|
+
var COUNCIL_EXAMPLES = [
|
|
32012
|
+
"cc-codeconductor install council --target claude",
|
|
32013
|
+
"cc-codeconductor install council --target claude --global",
|
|
32014
|
+
"cc-codeconductor install council --target claude --force",
|
|
32015
|
+
"cc-codeconductor install council --target claude --dry-run",
|
|
32016
|
+
"cc-codeconductor install council --target all",
|
|
32017
|
+
"cc-codeconductor install council --target claude --global --force"
|
|
32018
|
+
];
|
|
32019
|
+
var LSP_EXAMPLES = [
|
|
32020
|
+
"cc-codeconductor install lsp --target claude --lang typescript,python",
|
|
32021
|
+
"cc-codeconductor install lsp --target all --lang typescript,python",
|
|
32022
|
+
"cc-codeconductor install lsp --target claude --global",
|
|
32023
|
+
"cc-codeconductor install lsp --target claude --dry-run"
|
|
32024
|
+
];
|
|
32025
|
+
var AFTER_INSTALL_EXAMPLES = [
|
|
32026
|
+
["cc-codeconductor doctor", "validates the installation"],
|
|
32027
|
+
["cc-codeconductor status", "shows what is installed"],
|
|
32028
|
+
["cc-codeconductor update --dry-run", "previews reconciliation of managed files after upgrading"],
|
|
32029
|
+
["cc-codeconductor update --force", "applies reconciliation of managed files after upgrading"],
|
|
32030
|
+
["cc-codeconductor migrate --dry-run", "previews repair of orphaned artifacts a reinstall cannot fix"]
|
|
32031
|
+
];
|
|
32032
|
+
function renderExamples(lines, bin) {
|
|
32033
|
+
return lines.map((line) => ` ${formatUsage(line, bin)}`);
|
|
32034
|
+
}
|
|
32035
|
+
function renderAnnotatedExamples(entries, bin) {
|
|
32036
|
+
return entries.map(([line, description]) => ` ${formatUsage(line, bin)} — ${description}`);
|
|
32037
|
+
}
|
|
32038
|
+
function renderUsageGuide(bin = resolveCliBin()) {
|
|
32039
|
+
return [
|
|
32040
|
+
"CodeConductor — installation usage guide",
|
|
32041
|
+
"",
|
|
32042
|
+
"Recommended flow (one command, installs and configures everything):",
|
|
32043
|
+
...renderExamples(RECOMMENDED_FLOW, bin),
|
|
32044
|
+
"",
|
|
32045
|
+
"Fine-grained primitives (for scripting or partial installs):",
|
|
32046
|
+
...renderExamples(PRIMITIVES, bin),
|
|
32047
|
+
"",
|
|
32048
|
+
"Shared flags:",
|
|
32049
|
+
" --target opencode|claude|codex|gemini|cursor|agy|pi|all (default: opencode)",
|
|
32050
|
+
" --global Install to the home directory (~/.claude, ~/.opencode, etc.) instead of the project",
|
|
32051
|
+
" --force Allow overwriting existing files",
|
|
32052
|
+
" --dry-run Show what would happen without writing files",
|
|
32053
|
+
" --locale Instruction language for agent files: en (default) | es — install preset only",
|
|
32054
|
+
" --lang Comma-separated languages to install LSP servers for — install lsp only",
|
|
32055
|
+
" --output Output mode: human (default) | json",
|
|
32056
|
+
"",
|
|
32057
|
+
"install preset — agents, prompts, skills, and commands:",
|
|
32058
|
+
...renderExamples(PRESET_EXAMPLES, bin),
|
|
32059
|
+
"",
|
|
32060
|
+
"install council — generated council spec files:",
|
|
32061
|
+
...renderExamples(COUNCIL_EXAMPLES, bin),
|
|
32062
|
+
"",
|
|
32063
|
+
"install lsp — language servers:",
|
|
32064
|
+
...renderExamples(LSP_EXAMPLES, bin),
|
|
32065
|
+
" Dedicated integration config is generated for: opencode, claude, codex, gemini, cursor, agy.",
|
|
32066
|
+
" pi installs the language servers but does not get a dedicated integration config file.",
|
|
32067
|
+
"",
|
|
32068
|
+
"After installing, verify and keep in sync:",
|
|
32069
|
+
...renderAnnotatedExamples(AFTER_INSTALL_EXAMPLES, bin),
|
|
32070
|
+
"",
|
|
32071
|
+
"More detail (GitHub only, not bundled in the npm package):",
|
|
32072
|
+
" docs/usage-cli.md Detailed CLI reference, incl. per-target generated files",
|
|
32073
|
+
" docs/getting-started/ Installation, first project, and update walkthroughs"
|
|
32074
|
+
].join(`
|
|
32075
|
+
`);
|
|
32076
|
+
}
|
|
32077
|
+
|
|
31632
32078
|
// src/cli/router.ts
|
|
31633
32079
|
var OutputModeSchema = exports_external.enum(["json", "human"]);
|
|
31634
32080
|
var SeoFormatSchema = exports_external.enum(["cli", "json", "markdown"]);
|
|
31635
32081
|
var SeoFailOnSchema = exports_external.enum(["error", "warning", "never"]);
|
|
31636
32082
|
var NonNegativeIntegerSchema = exports_external.coerce.number().int().nonnegative();
|
|
32083
|
+
var BOOLEAN_OPTIONS = new Set(["record-telemetry"]);
|
|
31637
32084
|
function parseArgs(args) {
|
|
31638
32085
|
const commandAcceptsOutputPath = args[0] === "seo";
|
|
31639
32086
|
const flags = {
|
|
@@ -31704,6 +32151,9 @@ function parseArgs(args) {
|
|
|
31704
32151
|
} else if (value !== undefined) {
|
|
31705
32152
|
options[key] = value;
|
|
31706
32153
|
consumed.add(i);
|
|
32154
|
+
} else if (BOOLEAN_OPTIONS.has(key)) {
|
|
32155
|
+
options[key] = true;
|
|
32156
|
+
consumed.add(i);
|
|
31707
32157
|
} else if (remaining[i + 1] && !remaining[i + 1].startsWith("-")) {
|
|
31708
32158
|
options[key] = remaining[++i];
|
|
31709
32159
|
consumed.add(i - 1);
|
|
@@ -31909,6 +32359,8 @@ async function routeCommand(args, projectRoot) {
|
|
|
31909
32359
|
case "docs":
|
|
31910
32360
|
case "man":
|
|
31911
32361
|
return { code: 0, data: { success: true, command, output: renderDocs(subcommand) } };
|
|
32362
|
+
case "usage":
|
|
32363
|
+
return { code: 0, data: { success: true, command: "usage", output: renderUsageGuide() } };
|
|
31912
32364
|
case "completion": {
|
|
31913
32365
|
const output = renderCompletion(subcommand ?? "");
|
|
31914
32366
|
return output ? { code: 0, data: { success: true, command: "completion", output } } : cliContractError("completion", ["Expected shell: bash, zsh, fish, or powershell."]);
|
|
@@ -32059,6 +32511,11 @@ async function routeCommand(args, projectRoot) {
|
|
|
32059
32511
|
input: options.input,
|
|
32060
32512
|
contextPath: options.context || options.contextPath,
|
|
32061
32513
|
promptVersion: options["prompt-version"] || options.promptVersion,
|
|
32514
|
+
view: options.view,
|
|
32515
|
+
recordTelemetry: options["record-telemetry"] === true || options["record-telemetry"] === "true",
|
|
32516
|
+
executionId: options["execution-id"],
|
|
32517
|
+
taskId: options["task-id"],
|
|
32518
|
+
contextStrategy: options["context-strategy"],
|
|
32062
32519
|
config: options.config,
|
|
32063
32520
|
rest: validateRest
|
|
32064
32521
|
});
|
|
@@ -32099,7 +32556,7 @@ async function routeCommand(args, projectRoot) {
|
|
|
32099
32556
|
});
|
|
32100
32557
|
}
|
|
32101
32558
|
case "odd": {
|
|
32102
|
-
const validSubs = ["create", "read", "reconcile"];
|
|
32559
|
+
const validSubs = ["create", "read", "reconcile", "handoff"];
|
|
32103
32560
|
if (!subcommand || !validSubs.includes(subcommand)) {
|
|
32104
32561
|
return unknownSubcommand(command, subcommand ?? "", validSubs);
|
|
32105
32562
|
}
|