cc-codeconductor 0.4.1 → 0.4.2
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 +27 -4
- package/dist/index.js +597 -40
- package/package.json +1 -1
- package/presets/agy/AGENTS.md +24 -0
- package/presets/codex/AGENTS.md +34 -0
- package/src/presets/models/agy.yml +7 -0
- package/src/presets/models/claude.yml +6 -0
- package/src/presets/models/codex.yml +6 -0
- package/src/presets/models/cursor.yml +6 -0
- package/src/presets/models/gemini.yml +6 -0
- package/src/presets/models/opencode.yml +6 -0
package/README.md
CHANGED
|
@@ -40,6 +40,9 @@ contracts, task cards, and risk-based routing.
|
|
|
40
40
|
> (skills, subagents, commands) for the active or specified target
|
|
41
41
|
> - `npx cc-codeconductor debt-harvest` (alias: `harvest`) — scans source files
|
|
42
42
|
> for `// defer` comments and writes `.codeconductor/debt-ledger.md`
|
|
43
|
+
> - `npx cc-codeconductor goal "<objective>"` (alias: `cc-goal`) — decomposes an
|
|
44
|
+
> objective into a dependency-ordered task graph, writes
|
|
45
|
+
> `.codeconductor/current-goal.yml`
|
|
43
46
|
> - `/cc-pagespeed --url <url>` — audits web performance using the PageSpeed
|
|
44
47
|
> Insights API; applies the 80/20 principle to produce a prioritized report of
|
|
45
48
|
> Core Web Vitals (LCP, TBT, CLS, FCP, TTFB) with framework-specific fixes;
|
|
@@ -120,21 +123,22 @@ Task Card → Risk Classification → Routing Policy → Conductor Agent → Del
|
|
|
120
123
|
|
|
121
124
|
---
|
|
122
125
|
|
|
123
|
-
## Current Support
|
|
126
|
+
## Current Support
|
|
124
127
|
|
|
125
128
|
- OpenCode preset
|
|
126
129
|
- Claude Code-compatible preset (see [Claude Environment Options & Best Practices](file:///c:/Users/R2D2/Documents/GitHub/codeconductor/docs/claude-env-options.md))
|
|
127
130
|
- Codex preset
|
|
128
131
|
- Spring Boot / Kotlin workflow
|
|
129
132
|
- Python / Django workflow guidance
|
|
130
|
-
-
|
|
131
|
-
- Routing Policy v0.
|
|
133
|
+
- 12 core Conductor Agents
|
|
134
|
+
- Routing Policy v0.3.0
|
|
132
135
|
- Task Card template
|
|
133
136
|
- Scorecard template
|
|
134
137
|
- End-to-end example
|
|
135
138
|
- YAML-driven model configuration
|
|
136
139
|
- Provider-agnostic `AgentContract` abstraction with target renderers for Claude, OpenCode, Codex, and Agy
|
|
137
140
|
- Council consensus engine (`councilConsensus()`) for multi-agent governance with majority/unanimous algorithms and security veto
|
|
141
|
+
- Phase 5 runtime modules — scoped context injection, TDD history compaction, concise inter-agent messaging, and token budget enforcement in the compile-fix loop
|
|
138
142
|
|
|
139
143
|
---
|
|
140
144
|
|
|
@@ -300,6 +304,20 @@ into `.codeconductor/debt-ledger.md`, grouped by optional tag
|
|
|
300
304
|
Supported extensions: `.ts`, `.tsx`, `.js`, `.jsx`, `.go`, `.rs`, `.java`,
|
|
301
305
|
`.kt`, `.swift`, `.cs`, `.php`, `.scala`, `.dart`, `.c`, `.cpp`, `.h`, `.hpp`.
|
|
302
306
|
|
|
307
|
+
#### `goal` — decompose objective into task graph
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
npx cc-codeconductor goal "Add user authentication"
|
|
311
|
+
npx cc-codeconductor goal "Implement CRUD for invoices"
|
|
312
|
+
npx cc-codeconductor cc-goal "Add search with filters" # alias
|
|
313
|
+
npx cc-codeconductor goal "Add user authentication" --output json
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Matches the objective against built-in templates (auth, crud, search,
|
|
317
|
+
notification, migration) or falls back to a generic 4-task chain. Writes the
|
|
318
|
+
resulting task graph to `.codeconductor/current-goal.yml` with dependency
|
|
319
|
+
ordering. The orchestrator uses this file to delegate tasks in dependency order.
|
|
320
|
+
|
|
303
321
|
|
|
304
322
|
### Global options
|
|
305
323
|
|
|
@@ -404,9 +422,14 @@ codeconductor/
|
|
|
404
422
|
├── src/ ← CLI source (TypeScript + Bun)
|
|
405
423
|
│ ├── cli/ ← entry point, router, error codes
|
|
406
424
|
│ ├── commands/ ← init, detect, install, doctor, update
|
|
407
|
-
│ ├── core/ ← config, detection, filesystem, presets
|
|
425
|
+
│ ├── core/ ← config, detection, filesystem, presets, goal
|
|
426
|
+
│ │ ├── context/ ← scoped context injection (Phase 5)
|
|
427
|
+
│ │ ├── compaction/ ← TDD history compaction hook (Phase 5)
|
|
428
|
+
│ │ ├── messages/ ← concise inter-agent formatter (Phase 5)
|
|
429
|
+
│ │ └── loop/ ← compile-fix loop controller (Phase 5)
|
|
408
430
|
│ ├── adapters/ ← opencode, claude, codex generators
|
|
409
431
|
│ ├── domain/council/ ← council spec, agent, contract
|
|
432
|
+
│ ├── domain/loop/ ← loop state machine
|
|
410
433
|
│ ├── validation/ ← Zod schemas
|
|
411
434
|
│ ├── utils/ ← Result type, logger, invariant
|
|
412
435
|
│ └── presets/council/ ← bundled council.yml preset
|
package/dist/index.js
CHANGED
|
@@ -11126,7 +11126,7 @@ function validateCouncilSpec(data) {
|
|
|
11126
11126
|
function validateConfig(data) {
|
|
11127
11127
|
return CodeConductorConfigSchema.parse(data);
|
|
11128
11128
|
}
|
|
11129
|
-
var CouncilAgentSpecSchema, CouncilSpecSchema, ProjectProfileSchema, CompileCheckConfigSchema, LoopConfigSchema, CodeConductorConfigSchema, RunnerTargetSchema, InstallStrategySchema, ManifestEntrySchema, InstallManifestSchema, ToolProviderNamesSchema, PermissionProviderNamesSchema, ModelConfigSchema, ContractTargetSchema, ContractFormatSchema, AgentContractSchema, CouncilFindingSchema, CouncilVerdictInputSchema, ConsensusConfigSchema, CouncilVerdictSchema, ClaudeAgentFileSchema, OpenCodeAgentFileSchema, SentryStackFrameSchema, SentryWebhookSchema;
|
|
11129
|
+
var CouncilAgentSpecSchema, CouncilSpecSchema, ProjectProfileSchema, CompileCheckConfigSchema, LoopConfigSchema, CodeConductorConfigSchema, RunnerTargetSchema, InstallStrategySchema, ManifestEntrySchema, InstallManifestSchema, ToolProviderNamesSchema, PermissionProviderNamesSchema, ModelConfigSchema, ContractTargetSchema, ContractFormatSchema, AgentContractSchema, CouncilFindingSchema, CouncilVerdictInputSchema, ConsensusConfigSchema, CouncilVerdictSchema, ClaudeAgentFileSchema, OpenCodeAgentFileSchema, SentryStackFrameSchema, SentryWebhookSchema, GoalTaskSchema, GoalGraphSchema;
|
|
11130
11130
|
var init_schemas = __esm(() => {
|
|
11131
11131
|
init_zod();
|
|
11132
11132
|
CouncilAgentSpecSchema = exports_external.object({
|
|
@@ -11167,7 +11167,11 @@ var init_schemas = __esm(() => {
|
|
|
11167
11167
|
LoopConfigSchema = exports_external.object({
|
|
11168
11168
|
enabled: exports_external.boolean().optional().default(true),
|
|
11169
11169
|
maxIterations: exports_external.number().int().positive().optional().default(3),
|
|
11170
|
-
maxTokenBudget: exports_external.number().nonnegative().optional().default(0)
|
|
11170
|
+
maxTokenBudget: exports_external.number().nonnegative().optional().default(0),
|
|
11171
|
+
compaction: exports_external.object({
|
|
11172
|
+
enabled: exports_external.boolean().optional().default(true),
|
|
11173
|
+
historyFile: exports_external.string().optional()
|
|
11174
|
+
}).optional()
|
|
11171
11175
|
});
|
|
11172
11176
|
CodeConductorConfigSchema = exports_external.object({
|
|
11173
11177
|
version: exports_external.string(),
|
|
@@ -11309,6 +11313,22 @@ var init_schemas = __esm(() => {
|
|
|
11309
11313
|
environment: exports_external.string().optional(),
|
|
11310
11314
|
release: exports_external.string().optional()
|
|
11311
11315
|
});
|
|
11316
|
+
GoalTaskSchema = exports_external.object({
|
|
11317
|
+
id: exports_external.string(),
|
|
11318
|
+
title: exports_external.string(),
|
|
11319
|
+
type: exports_external.enum(["feature", "fix", "refactor", "test", "docs"]),
|
|
11320
|
+
risk: exports_external.enum(["low", "medium", "high"]),
|
|
11321
|
+
status: exports_external.enum(["pending", "in-progress", "done", "blocked"]),
|
|
11322
|
+
depends_on: exports_external.array(exports_external.string()).optional().default([]),
|
|
11323
|
+
acceptance_criteria: exports_external.array(exports_external.string()),
|
|
11324
|
+
blocked_reason: exports_external.string().optional(),
|
|
11325
|
+
context_scope: exports_external.enum(["isolated", "continuation", "full"]).optional().default("isolated")
|
|
11326
|
+
});
|
|
11327
|
+
GoalGraphSchema = exports_external.object({
|
|
11328
|
+
objective: exports_external.string(),
|
|
11329
|
+
tasks: exports_external.array(GoalTaskSchema),
|
|
11330
|
+
created_at: exports_external.string()
|
|
11331
|
+
});
|
|
11312
11332
|
});
|
|
11313
11333
|
|
|
11314
11334
|
// src/core/presets/package-paths.ts
|
|
@@ -12134,7 +12154,7 @@ init_errors();
|
|
|
12134
12154
|
// package.json
|
|
12135
12155
|
var package_default = {
|
|
12136
12156
|
name: "cc-codeconductor",
|
|
12137
|
-
version: "0.4.
|
|
12157
|
+
version: "0.4.2",
|
|
12138
12158
|
description: "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
|
|
12139
12159
|
keywords: [
|
|
12140
12160
|
"ai",
|
|
@@ -13056,7 +13076,8 @@ function renderTemplate(content, modelConfig, filePath, locale = "en") {
|
|
|
13056
13076
|
"tester",
|
|
13057
13077
|
"reviewer",
|
|
13058
13078
|
"docs",
|
|
13059
|
-
"repo-explorer"
|
|
13079
|
+
"repo-explorer",
|
|
13080
|
+
"goal-planner"
|
|
13060
13081
|
];
|
|
13061
13082
|
let result = templatedContent;
|
|
13062
13083
|
for (const role of knownRoles) {
|
|
@@ -13144,8 +13165,20 @@ function injectMcpServers(jsonString, filePath) {
|
|
|
13144
13165
|
if (isClaudeSettings || isAgyMcpConfig) {
|
|
13145
13166
|
obj.mcpServers = mergeDeep(obj.mcpServers || {}, mcpServers);
|
|
13146
13167
|
} else if (isOpencodeJsonc) {
|
|
13147
|
-
|
|
13148
|
-
|
|
13168
|
+
const opencodeMcp = {};
|
|
13169
|
+
for (const [key, server] of Object.entries(mcpServers)) {
|
|
13170
|
+
const commandArray = typeof server.command === "string" ? [server.command, ...server.args || []] : server.command;
|
|
13171
|
+
const formattedServer = {
|
|
13172
|
+
type: "local",
|
|
13173
|
+
command: commandArray,
|
|
13174
|
+
enabled: true
|
|
13175
|
+
};
|
|
13176
|
+
if (server.env) {
|
|
13177
|
+
formattedServer.environment = server.env;
|
|
13178
|
+
}
|
|
13179
|
+
opencodeMcp[key] = formattedServer;
|
|
13180
|
+
}
|
|
13181
|
+
obj.mcp = mergeDeep(obj.mcp || {}, opencodeMcp);
|
|
13149
13182
|
}
|
|
13150
13183
|
return JSON.stringify(obj, null, 2);
|
|
13151
13184
|
} catch {
|
|
@@ -15080,6 +15113,522 @@ async function debtHarvestCommand(options) {
|
|
|
15080
15113
|
}
|
|
15081
15114
|
}
|
|
15082
15115
|
|
|
15116
|
+
// src/core/goal/goal-planner.ts
|
|
15117
|
+
var TEMPLATES = [
|
|
15118
|
+
{
|
|
15119
|
+
keywords: ["login", "auth", "authentication", "signin", "sign-in"],
|
|
15120
|
+
tasks: [
|
|
15121
|
+
{
|
|
15122
|
+
id: "auth-schema",
|
|
15123
|
+
title: "Define auth data model and DB schema",
|
|
15124
|
+
type: "feature",
|
|
15125
|
+
risk: "high",
|
|
15126
|
+
status: "pending",
|
|
15127
|
+
context_scope: "isolated",
|
|
15128
|
+
depends_on: [],
|
|
15129
|
+
acceptance_criteria: [
|
|
15130
|
+
"User entity with email, password_hash, created_at fields",
|
|
15131
|
+
"Migration script creates users table",
|
|
15132
|
+
"Schema supports password reset token"
|
|
15133
|
+
]
|
|
15134
|
+
},
|
|
15135
|
+
{
|
|
15136
|
+
id: "auth-api",
|
|
15137
|
+
title: "Define auth API contract",
|
|
15138
|
+
type: "feature",
|
|
15139
|
+
risk: "medium",
|
|
15140
|
+
status: "pending",
|
|
15141
|
+
context_scope: "isolated",
|
|
15142
|
+
depends_on: ["auth-schema"],
|
|
15143
|
+
acceptance_criteria: [
|
|
15144
|
+
"POST /auth/register endpoint defined",
|
|
15145
|
+
"POST /auth/login endpoint defined",
|
|
15146
|
+
"POST /auth/logout endpoint defined",
|
|
15147
|
+
"OpenAPI spec updated"
|
|
15148
|
+
]
|
|
15149
|
+
},
|
|
15150
|
+
{
|
|
15151
|
+
id: "auth-impl",
|
|
15152
|
+
title: "Implement auth endpoints",
|
|
15153
|
+
type: "feature",
|
|
15154
|
+
risk: "high",
|
|
15155
|
+
status: "pending",
|
|
15156
|
+
context_scope: "isolated",
|
|
15157
|
+
depends_on: ["auth-api"],
|
|
15158
|
+
acceptance_criteria: [
|
|
15159
|
+
"Register endpoint hashes password and stores user",
|
|
15160
|
+
"Login endpoint validates credentials and returns session",
|
|
15161
|
+
"Logout endpoint invalidates session",
|
|
15162
|
+
"Input validation on all endpoints"
|
|
15163
|
+
]
|
|
15164
|
+
},
|
|
15165
|
+
{
|
|
15166
|
+
id: "auth-tests",
|
|
15167
|
+
title: "Write auth tests",
|
|
15168
|
+
type: "test",
|
|
15169
|
+
risk: "medium",
|
|
15170
|
+
status: "pending",
|
|
15171
|
+
context_scope: "isolated",
|
|
15172
|
+
depends_on: ["auth-impl"],
|
|
15173
|
+
acceptance_criteria: [
|
|
15174
|
+
"Unit tests for password hashing",
|
|
15175
|
+
"Integration tests for register/login/logout flow",
|
|
15176
|
+
"Edge cases: duplicate email, invalid password, expired token"
|
|
15177
|
+
]
|
|
15178
|
+
}
|
|
15179
|
+
]
|
|
15180
|
+
},
|
|
15181
|
+
{
|
|
15182
|
+
keywords: ["crud", "resource", "api", "endpoint", "rest"],
|
|
15183
|
+
tasks: [
|
|
15184
|
+
{
|
|
15185
|
+
id: "crud-model",
|
|
15186
|
+
title: "Define data model and schema",
|
|
15187
|
+
type: "feature",
|
|
15188
|
+
risk: "medium",
|
|
15189
|
+
status: "pending",
|
|
15190
|
+
context_scope: "isolated",
|
|
15191
|
+
depends_on: [],
|
|
15192
|
+
acceptance_criteria: [
|
|
15193
|
+
"Entity definition with required fields",
|
|
15194
|
+
"Database migration script",
|
|
15195
|
+
"Schema follows project conventions"
|
|
15196
|
+
]
|
|
15197
|
+
},
|
|
15198
|
+
{
|
|
15199
|
+
id: "crud-service",
|
|
15200
|
+
title: "Implement repository/service layer",
|
|
15201
|
+
type: "feature",
|
|
15202
|
+
risk: "medium",
|
|
15203
|
+
status: "pending",
|
|
15204
|
+
context_scope: "isolated",
|
|
15205
|
+
depends_on: ["crud-model"],
|
|
15206
|
+
acceptance_criteria: [
|
|
15207
|
+
"Create, Read (list + by id), Update, Delete operations",
|
|
15208
|
+
"Input validation",
|
|
15209
|
+
"Error handling for not-found and conflict"
|
|
15210
|
+
]
|
|
15211
|
+
},
|
|
15212
|
+
{
|
|
15213
|
+
id: "crud-api",
|
|
15214
|
+
title: "Implement API endpoints",
|
|
15215
|
+
type: "feature",
|
|
15216
|
+
risk: "medium",
|
|
15217
|
+
status: "pending",
|
|
15218
|
+
context_scope: "isolated",
|
|
15219
|
+
depends_on: ["crud-service"],
|
|
15220
|
+
acceptance_criteria: [
|
|
15221
|
+
"REST endpoints for all CRUD operations",
|
|
15222
|
+
"Proper HTTP status codes",
|
|
15223
|
+
"Request/response schemas"
|
|
15224
|
+
]
|
|
15225
|
+
},
|
|
15226
|
+
{
|
|
15227
|
+
id: "crud-tests",
|
|
15228
|
+
title: "Write tests",
|
|
15229
|
+
type: "test",
|
|
15230
|
+
risk: "low",
|
|
15231
|
+
status: "pending",
|
|
15232
|
+
context_scope: "isolated",
|
|
15233
|
+
depends_on: ["crud-api"],
|
|
15234
|
+
acceptance_criteria: [
|
|
15235
|
+
"Unit tests for service layer",
|
|
15236
|
+
"Integration tests for API endpoints",
|
|
15237
|
+
"Edge cases covered"
|
|
15238
|
+
]
|
|
15239
|
+
}
|
|
15240
|
+
]
|
|
15241
|
+
},
|
|
15242
|
+
{
|
|
15243
|
+
keywords: ["search", "filter", "query", "full-text", "fts"],
|
|
15244
|
+
tasks: [
|
|
15245
|
+
{
|
|
15246
|
+
id: "search-schema",
|
|
15247
|
+
title: "Design search schema and indexing strategy",
|
|
15248
|
+
type: "feature",
|
|
15249
|
+
risk: "medium",
|
|
15250
|
+
status: "pending",
|
|
15251
|
+
context_scope: "isolated",
|
|
15252
|
+
depends_on: [],
|
|
15253
|
+
acceptance_criteria: [
|
|
15254
|
+
"Search index definition",
|
|
15255
|
+
"Indexing strategy documented",
|
|
15256
|
+
"Performance requirements defined"
|
|
15257
|
+
]
|
|
15258
|
+
},
|
|
15259
|
+
{
|
|
15260
|
+
id: "search-service",
|
|
15261
|
+
title: "Implement search service",
|
|
15262
|
+
type: "feature",
|
|
15263
|
+
risk: "medium",
|
|
15264
|
+
status: "pending",
|
|
15265
|
+
context_scope: "isolated",
|
|
15266
|
+
depends_on: ["search-schema"],
|
|
15267
|
+
acceptance_criteria: [
|
|
15268
|
+
"Full-text search with ranking",
|
|
15269
|
+
"Filter support",
|
|
15270
|
+
"Pagination"
|
|
15271
|
+
]
|
|
15272
|
+
},
|
|
15273
|
+
{
|
|
15274
|
+
id: "search-api",
|
|
15275
|
+
title: "Implement search API",
|
|
15276
|
+
type: "feature",
|
|
15277
|
+
risk: "low",
|
|
15278
|
+
status: "pending",
|
|
15279
|
+
context_scope: "isolated",
|
|
15280
|
+
depends_on: ["search-service"],
|
|
15281
|
+
acceptance_criteria: [
|
|
15282
|
+
"GET /search endpoint with query params",
|
|
15283
|
+
"Response includes results + metadata",
|
|
15284
|
+
"Rate limiting applied"
|
|
15285
|
+
]
|
|
15286
|
+
},
|
|
15287
|
+
{
|
|
15288
|
+
id: "search-tests",
|
|
15289
|
+
title: "Write search tests",
|
|
15290
|
+
type: "test",
|
|
15291
|
+
risk: "low",
|
|
15292
|
+
status: "pending",
|
|
15293
|
+
context_scope: "isolated",
|
|
15294
|
+
depends_on: ["search-api"],
|
|
15295
|
+
acceptance_criteria: [
|
|
15296
|
+
"Unit tests for search logic",
|
|
15297
|
+
"Integration tests with sample data",
|
|
15298
|
+
"Performance test for large datasets"
|
|
15299
|
+
]
|
|
15300
|
+
}
|
|
15301
|
+
]
|
|
15302
|
+
},
|
|
15303
|
+
{
|
|
15304
|
+
keywords: ["notification", "email", "alert", "push", "notify"],
|
|
15305
|
+
tasks: [
|
|
15306
|
+
{
|
|
15307
|
+
id: "notif-model",
|
|
15308
|
+
title: "Design notification data model",
|
|
15309
|
+
type: "feature",
|
|
15310
|
+
risk: "medium",
|
|
15311
|
+
status: "pending",
|
|
15312
|
+
context_scope: "isolated",
|
|
15313
|
+
depends_on: [],
|
|
15314
|
+
acceptance_criteria: [
|
|
15315
|
+
"Notification entity with type, payload, status, user_id",
|
|
15316
|
+
"Database migration",
|
|
15317
|
+
"Enum for notification types"
|
|
15318
|
+
]
|
|
15319
|
+
},
|
|
15320
|
+
{
|
|
15321
|
+
id: "notif-service",
|
|
15322
|
+
title: "Implement notification service",
|
|
15323
|
+
type: "feature",
|
|
15324
|
+
risk: "medium",
|
|
15325
|
+
status: "pending",
|
|
15326
|
+
context_scope: "isolated",
|
|
15327
|
+
depends_on: ["notif-model"],
|
|
15328
|
+
acceptance_criteria: [
|
|
15329
|
+
"Send notification by type",
|
|
15330
|
+
"Queue-based delivery",
|
|
15331
|
+
"Retry logic for failed deliveries"
|
|
15332
|
+
]
|
|
15333
|
+
},
|
|
15334
|
+
{
|
|
15335
|
+
id: "notif-api",
|
|
15336
|
+
title: "Implement notification API",
|
|
15337
|
+
type: "feature",
|
|
15338
|
+
risk: "low",
|
|
15339
|
+
status: "pending",
|
|
15340
|
+
context_scope: "isolated",
|
|
15341
|
+
depends_on: ["notif-service"],
|
|
15342
|
+
acceptance_criteria: [
|
|
15343
|
+
"POST /notifications endpoint",
|
|
15344
|
+
"GET /notifications endpoint with read/unread filter",
|
|
15345
|
+
"PATCH /notifications/:id/read endpoint"
|
|
15346
|
+
]
|
|
15347
|
+
},
|
|
15348
|
+
{
|
|
15349
|
+
id: "notif-tests",
|
|
15350
|
+
title: "Write notification tests",
|
|
15351
|
+
type: "test",
|
|
15352
|
+
risk: "low",
|
|
15353
|
+
status: "pending",
|
|
15354
|
+
context_scope: "isolated",
|
|
15355
|
+
depends_on: ["notif-api"],
|
|
15356
|
+
acceptance_criteria: [
|
|
15357
|
+
"Unit tests for notification logic",
|
|
15358
|
+
"Integration tests for API",
|
|
15359
|
+
"Edge cases: invalid type, missing user"
|
|
15360
|
+
]
|
|
15361
|
+
}
|
|
15362
|
+
]
|
|
15363
|
+
},
|
|
15364
|
+
{
|
|
15365
|
+
keywords: ["migration", "migrate", "schema change", "database change", "column"],
|
|
15366
|
+
tasks: [
|
|
15367
|
+
{
|
|
15368
|
+
id: "migrate-script",
|
|
15369
|
+
title: "Write migration script",
|
|
15370
|
+
type: "feature",
|
|
15371
|
+
risk: "high",
|
|
15372
|
+
status: "pending",
|
|
15373
|
+
context_scope: "isolated",
|
|
15374
|
+
depends_on: [],
|
|
15375
|
+
acceptance_criteria: [
|
|
15376
|
+
"Migration is reversible",
|
|
15377
|
+
"Handles existing data gracefully",
|
|
15378
|
+
"Rollback script included"
|
|
15379
|
+
]
|
|
15380
|
+
},
|
|
15381
|
+
{
|
|
15382
|
+
id: "migrate-model",
|
|
15383
|
+
title: "Update domain model",
|
|
15384
|
+
type: "refactor",
|
|
15385
|
+
risk: "medium",
|
|
15386
|
+
status: "pending",
|
|
15387
|
+
context_scope: "isolated",
|
|
15388
|
+
depends_on: ["migrate-script"],
|
|
15389
|
+
acceptance_criteria: [
|
|
15390
|
+
"Domain model reflects new schema",
|
|
15391
|
+
"Existing code paths updated",
|
|
15392
|
+
"Backward compatibility maintained"
|
|
15393
|
+
]
|
|
15394
|
+
},
|
|
15395
|
+
{
|
|
15396
|
+
id: "migrate-dal",
|
|
15397
|
+
title: "Update data access layer",
|
|
15398
|
+
type: "refactor",
|
|
15399
|
+
risk: "medium",
|
|
15400
|
+
status: "pending",
|
|
15401
|
+
context_scope: "isolated",
|
|
15402
|
+
depends_on: ["migrate-model"],
|
|
15403
|
+
acceptance_criteria: [
|
|
15404
|
+
"Repository/service reads/writes new schema",
|
|
15405
|
+
"No broken queries",
|
|
15406
|
+
"Performance not degraded"
|
|
15407
|
+
]
|
|
15408
|
+
},
|
|
15409
|
+
{
|
|
15410
|
+
id: "migrate-tests",
|
|
15411
|
+
title: "Write migration tests",
|
|
15412
|
+
type: "test",
|
|
15413
|
+
risk: "high",
|
|
15414
|
+
status: "pending",
|
|
15415
|
+
context_scope: "isolated",
|
|
15416
|
+
depends_on: ["migrate-dal"],
|
|
15417
|
+
acceptance_criteria: [
|
|
15418
|
+
"Migration up/down test",
|
|
15419
|
+
"Data integrity test",
|
|
15420
|
+
"Integration tests with new schema"
|
|
15421
|
+
]
|
|
15422
|
+
}
|
|
15423
|
+
]
|
|
15424
|
+
}
|
|
15425
|
+
];
|
|
15426
|
+
var GENERIC_TEMPLATE = [
|
|
15427
|
+
{
|
|
15428
|
+
id: "plan-scope",
|
|
15429
|
+
title: "Clarify requirements and scope",
|
|
15430
|
+
type: "feature",
|
|
15431
|
+
risk: "low",
|
|
15432
|
+
status: "pending",
|
|
15433
|
+
context_scope: "isolated",
|
|
15434
|
+
depends_on: [],
|
|
15435
|
+
acceptance_criteria: ["Objective is well-defined", "Scope boundaries identified"]
|
|
15436
|
+
},
|
|
15437
|
+
{
|
|
15438
|
+
id: "plan-design",
|
|
15439
|
+
title: "Design technical approach",
|
|
15440
|
+
type: "feature",
|
|
15441
|
+
risk: "medium",
|
|
15442
|
+
status: "pending",
|
|
15443
|
+
context_scope: "isolated",
|
|
15444
|
+
depends_on: ["plan-scope"],
|
|
15445
|
+
acceptance_criteria: ["Architecture decisions documented", "API contracts defined"]
|
|
15446
|
+
},
|
|
15447
|
+
{
|
|
15448
|
+
id: "plan-impl",
|
|
15449
|
+
title: "Implement solution",
|
|
15450
|
+
type: "feature",
|
|
15451
|
+
risk: "medium",
|
|
15452
|
+
status: "pending",
|
|
15453
|
+
context_scope: "isolated",
|
|
15454
|
+
depends_on: ["plan-design"],
|
|
15455
|
+
acceptance_criteria: ["Core functionality implemented", "Follows project conventions"]
|
|
15456
|
+
},
|
|
15457
|
+
{
|
|
15458
|
+
id: "plan-tests",
|
|
15459
|
+
title: "Write tests and verify",
|
|
15460
|
+
type: "test",
|
|
15461
|
+
risk: "low",
|
|
15462
|
+
status: "pending",
|
|
15463
|
+
context_scope: "isolated",
|
|
15464
|
+
depends_on: ["plan-impl"],
|
|
15465
|
+
acceptance_criteria: ["Unit tests pass", "Integration tests pass", "No regressions"]
|
|
15466
|
+
}
|
|
15467
|
+
];
|
|
15468
|
+
function matchTemplate(objective) {
|
|
15469
|
+
const lower = objective.toLowerCase();
|
|
15470
|
+
for (const template of TEMPLATES) {
|
|
15471
|
+
const matched = template.keywords.some((kw) => lower.includes(kw));
|
|
15472
|
+
if (matched)
|
|
15473
|
+
return template.tasks;
|
|
15474
|
+
}
|
|
15475
|
+
return GENERIC_TEMPLATE;
|
|
15476
|
+
}
|
|
15477
|
+
function planGoal(objective) {
|
|
15478
|
+
const tasks = matchTemplate(objective);
|
|
15479
|
+
return {
|
|
15480
|
+
objective,
|
|
15481
|
+
tasks: tasks.map((t) => ({ ...t, status: "pending" })),
|
|
15482
|
+
created_at: new Date().toISOString()
|
|
15483
|
+
};
|
|
15484
|
+
}
|
|
15485
|
+
|
|
15486
|
+
// src/core/goal/goal-state.ts
|
|
15487
|
+
init_dist();
|
|
15488
|
+
init_schemas();
|
|
15489
|
+
import { mkdir as mkdir7, readFile as readFile10, writeFile as writeFile6 } from "node:fs/promises";
|
|
15490
|
+
import { resolve as resolve10 } from "node:path";
|
|
15491
|
+
function validateGoalGraph(graph) {
|
|
15492
|
+
const ids = new Set(graph.tasks.map((t) => t.id));
|
|
15493
|
+
if (ids.size !== graph.tasks.length) {
|
|
15494
|
+
return err(new Error("Duplicate task IDs in goal graph"));
|
|
15495
|
+
}
|
|
15496
|
+
for (const task of graph.tasks) {
|
|
15497
|
+
for (const dep of task.depends_on ?? []) {
|
|
15498
|
+
if (!ids.has(dep)) {
|
|
15499
|
+
return err(new Error(`Task "${task.id}" depends on unknown task "${dep}"`));
|
|
15500
|
+
}
|
|
15501
|
+
}
|
|
15502
|
+
}
|
|
15503
|
+
const visited = new Set;
|
|
15504
|
+
const inStack = new Set;
|
|
15505
|
+
function dfs(taskId) {
|
|
15506
|
+
if (inStack.has(taskId))
|
|
15507
|
+
return true;
|
|
15508
|
+
if (visited.has(taskId))
|
|
15509
|
+
return false;
|
|
15510
|
+
visited.add(taskId);
|
|
15511
|
+
inStack.add(taskId);
|
|
15512
|
+
const task = graph.tasks.find((t) => t.id === taskId);
|
|
15513
|
+
if (task) {
|
|
15514
|
+
for (const dep of task.depends_on ?? []) {
|
|
15515
|
+
if (dfs(dep))
|
|
15516
|
+
return true;
|
|
15517
|
+
}
|
|
15518
|
+
}
|
|
15519
|
+
inStack.delete(taskId);
|
|
15520
|
+
return false;
|
|
15521
|
+
}
|
|
15522
|
+
for (const task of graph.tasks) {
|
|
15523
|
+
if (dfs(task.id)) {
|
|
15524
|
+
return err(new Error(`Cycle detected involving task "${task.id}"`));
|
|
15525
|
+
}
|
|
15526
|
+
}
|
|
15527
|
+
return ok(graph);
|
|
15528
|
+
}
|
|
15529
|
+
async function writeGoal(projectRoot, graph) {
|
|
15530
|
+
const validation = validateGoalGraph(graph);
|
|
15531
|
+
if (!validation.success)
|
|
15532
|
+
return validation;
|
|
15533
|
+
const dir = resolve10(projectRoot, ".codeconductor");
|
|
15534
|
+
await mkdir7(dir, { recursive: true });
|
|
15535
|
+
const yaml = $stringify(graph);
|
|
15536
|
+
await writeFile6(resolve10(dir, "current-goal.yml"), yaml, "utf-8");
|
|
15537
|
+
return ok(undefined);
|
|
15538
|
+
}
|
|
15539
|
+
|
|
15540
|
+
// src/commands/goal.command.ts
|
|
15541
|
+
function renderDependencyTree(tasks) {
|
|
15542
|
+
const lines = [];
|
|
15543
|
+
const taskMap = new Map(tasks.map((t) => [t.id, t]));
|
|
15544
|
+
const roots = tasks.filter((t) => !t.depends_on || t.depends_on.length === 0);
|
|
15545
|
+
function render(taskId, prefix, isLast) {
|
|
15546
|
+
const task = taskMap.get(taskId);
|
|
15547
|
+
if (!task)
|
|
15548
|
+
return;
|
|
15549
|
+
const connector = isLast ? "└── " : "├── ";
|
|
15550
|
+
const label = `${task.id}: ${task.title}`;
|
|
15551
|
+
lines.push(`${prefix}${connector}${label}`);
|
|
15552
|
+
const children = tasks.filter((t) => t.depends_on && t.depends_on.includes(taskId));
|
|
15553
|
+
const childPrefix = prefix + (isLast ? " " : "│ ");
|
|
15554
|
+
children.forEach((child, i) => {
|
|
15555
|
+
render(child.id, childPrefix, i === children.length - 1);
|
|
15556
|
+
});
|
|
15557
|
+
}
|
|
15558
|
+
roots.forEach((root, i) => {
|
|
15559
|
+
render(root.id, "", i === roots.length - 1);
|
|
15560
|
+
});
|
|
15561
|
+
return lines.join(`
|
|
15562
|
+
`);
|
|
15563
|
+
}
|
|
15564
|
+
async function goalCommand(options) {
|
|
15565
|
+
const { objective, projectRoot, output } = options;
|
|
15566
|
+
if (!objective || objective.trim().length === 0) {
|
|
15567
|
+
return {
|
|
15568
|
+
code: 1,
|
|
15569
|
+
data: {
|
|
15570
|
+
success: false,
|
|
15571
|
+
command: "goal",
|
|
15572
|
+
errors: ['Objective is required. Usage: codeconductor goal "<objective>"']
|
|
15573
|
+
}
|
|
15574
|
+
};
|
|
15575
|
+
}
|
|
15576
|
+
try {
|
|
15577
|
+
const graph = planGoal(objective);
|
|
15578
|
+
const writeResult = await writeGoal(projectRoot, graph);
|
|
15579
|
+
if (!writeResult.success) {
|
|
15580
|
+
return {
|
|
15581
|
+
code: 1,
|
|
15582
|
+
data: {
|
|
15583
|
+
success: false,
|
|
15584
|
+
command: "goal",
|
|
15585
|
+
errors: [`Failed to write goal: ${writeResult.error.message}`]
|
|
15586
|
+
}
|
|
15587
|
+
};
|
|
15588
|
+
}
|
|
15589
|
+
if (output === "json") {
|
|
15590
|
+
return {
|
|
15591
|
+
code: 0,
|
|
15592
|
+
data: {
|
|
15593
|
+
success: true,
|
|
15594
|
+
command: "goal",
|
|
15595
|
+
objective: graph.objective,
|
|
15596
|
+
tasks: graph.tasks,
|
|
15597
|
+
file: ".codeconductor/current-goal.yml"
|
|
15598
|
+
}
|
|
15599
|
+
};
|
|
15600
|
+
}
|
|
15601
|
+
const tree = renderDependencyTree(graph.tasks);
|
|
15602
|
+
const lines = [
|
|
15603
|
+
`Objective: ${graph.objective}`,
|
|
15604
|
+
"",
|
|
15605
|
+
"Task dependency graph:",
|
|
15606
|
+
tree,
|
|
15607
|
+
"",
|
|
15608
|
+
`Tasks: ${graph.tasks.length} total`,
|
|
15609
|
+
`File: .codeconductor/current-goal.yml`
|
|
15610
|
+
];
|
|
15611
|
+
return {
|
|
15612
|
+
code: 0,
|
|
15613
|
+
data: {
|
|
15614
|
+
success: true,
|
|
15615
|
+
command: "goal",
|
|
15616
|
+
output: lines.join(`
|
|
15617
|
+
`)
|
|
15618
|
+
}
|
|
15619
|
+
};
|
|
15620
|
+
} catch (e) {
|
|
15621
|
+
return {
|
|
15622
|
+
code: 1,
|
|
15623
|
+
data: {
|
|
15624
|
+
success: false,
|
|
15625
|
+
command: "goal",
|
|
15626
|
+
errors: [e instanceof Error ? e.message : String(e)]
|
|
15627
|
+
}
|
|
15628
|
+
};
|
|
15629
|
+
}
|
|
15630
|
+
}
|
|
15631
|
+
|
|
15083
15632
|
// src/commands/help.command.ts
|
|
15084
15633
|
import { readdir as readdir3 } from "node:fs/promises";
|
|
15085
15634
|
import { join as join8 } from "node:path";
|
|
@@ -15207,8 +15756,8 @@ async function helpCommand(options) {
|
|
|
15207
15756
|
}
|
|
15208
15757
|
|
|
15209
15758
|
// src/commands/seo-audit.command.ts
|
|
15210
|
-
import { writeFile as
|
|
15211
|
-
import { dirname as dirname4, resolve as
|
|
15759
|
+
import { writeFile as writeFile7, mkdir as mkdir8 } from "node:fs/promises";
|
|
15760
|
+
import { dirname as dirname4, resolve as resolve11 } from "node:path";
|
|
15212
15761
|
|
|
15213
15762
|
// src/infrastructure/http/safe-fetch.ts
|
|
15214
15763
|
import { lookup } from "node:dns/promises";
|
|
@@ -15295,7 +15844,7 @@ async function safeFetch(urlString, options = {}) {
|
|
|
15295
15844
|
}
|
|
15296
15845
|
}
|
|
15297
15846
|
async function delay(ms) {
|
|
15298
|
-
return new Promise((
|
|
15847
|
+
return new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
15299
15848
|
}
|
|
15300
15849
|
|
|
15301
15850
|
// src/infrastructure/parsers/sitemap-parser.ts
|
|
@@ -16499,14 +17048,14 @@ async function seoAuditCommand(options) {
|
|
|
16499
17048
|
formattedOutput = formatCli(report);
|
|
16500
17049
|
}
|
|
16501
17050
|
if (output) {
|
|
16502
|
-
const outputPath =
|
|
16503
|
-
await
|
|
16504
|
-
await
|
|
17051
|
+
const outputPath = resolve11(options.projectRoot, output);
|
|
17052
|
+
await mkdir8(dirname4(outputPath), { recursive: true });
|
|
17053
|
+
await writeFile7(outputPath, formattedOutput, "utf-8");
|
|
16505
17054
|
} else if (format === "markdown") {
|
|
16506
17055
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
16507
|
-
const defaultPath =
|
|
16508
|
-
await
|
|
16509
|
-
await
|
|
17056
|
+
const defaultPath = resolve11(options.projectRoot, "seo-reports", `audit-report-${timestamp}.md`);
|
|
17057
|
+
await mkdir8(dirname4(defaultPath), { recursive: true });
|
|
17058
|
+
await writeFile7(defaultPath, formattedOutput, "utf-8");
|
|
16510
17059
|
process.stderr.write(`Report saved to: ${defaultPath}
|
|
16511
17060
|
`);
|
|
16512
17061
|
}
|
|
@@ -16518,7 +17067,7 @@ async function seoAuditCommand(options) {
|
|
|
16518
17067
|
command: "seo audit",
|
|
16519
17068
|
report,
|
|
16520
17069
|
output: formattedOutput,
|
|
16521
|
-
outputFile: output ?
|
|
17070
|
+
outputFile: output ? resolve11(options.projectRoot, output) : format === "markdown" ? resolve11(options.projectRoot, "seo-reports") : undefined
|
|
16522
17071
|
}
|
|
16523
17072
|
};
|
|
16524
17073
|
} catch (error) {
|
|
@@ -16534,8 +17083,8 @@ async function seoAuditCommand(options) {
|
|
|
16534
17083
|
}
|
|
16535
17084
|
|
|
16536
17085
|
// src/commands/seo-llms.command.ts
|
|
16537
|
-
import { writeFile as
|
|
16538
|
-
import { dirname as dirname5, resolve as
|
|
17086
|
+
import { writeFile as writeFile8, mkdir as mkdir9 } from "node:fs/promises";
|
|
17087
|
+
import { dirname as dirname5, resolve as resolve12 } from "node:path";
|
|
16539
17088
|
|
|
16540
17089
|
// src/domain/seo/llms-generator.ts
|
|
16541
17090
|
function extractTitle2(html) {
|
|
@@ -16678,9 +17227,9 @@ async function seoLlmsCommand(options) {
|
|
|
16678
17227
|
}
|
|
16679
17228
|
}) : await generateLlmsTxtFromUrl(url);
|
|
16680
17229
|
process.stderr.write("\r" + " ".repeat(80) + "\r");
|
|
16681
|
-
const outputPath = output ?
|
|
16682
|
-
await
|
|
16683
|
-
await
|
|
17230
|
+
const outputPath = output ? resolve12(options.projectRoot, output) : resolve12(options.projectRoot, "llms.txt");
|
|
17231
|
+
await mkdir9(dirname5(outputPath), { recursive: true });
|
|
17232
|
+
await writeFile8(outputPath, result.content, "utf-8");
|
|
16684
17233
|
process.stderr.write(`Generated: ${outputPath} (${result.entries.length} entries)
|
|
16685
17234
|
`);
|
|
16686
17235
|
return {
|
|
@@ -16707,8 +17256,8 @@ async function seoLlmsCommand(options) {
|
|
|
16707
17256
|
|
|
16708
17257
|
// src/commands/update.command.ts
|
|
16709
17258
|
import { homedir as homedir9 } from "node:os";
|
|
16710
|
-
import { resolve as
|
|
16711
|
-
import { mkdir as
|
|
17259
|
+
import { resolve as resolve13, dirname as dirname6 } from "node:path";
|
|
17260
|
+
import { mkdir as mkdir10, readFile as readFile11, writeFile as writeFile9, stat as stat3 } from "node:fs/promises";
|
|
16712
17261
|
init_package_paths();
|
|
16713
17262
|
async function updateCommand(options) {
|
|
16714
17263
|
const { dryRun, force, global: isGlobal, output, projectRoot } = options;
|
|
@@ -16774,23 +17323,23 @@ async function updateCommand(options) {
|
|
|
16774
17323
|
}
|
|
16775
17324
|
const updated = [];
|
|
16776
17325
|
if (updateResults.council) {
|
|
16777
|
-
const localCouncil =
|
|
16778
|
-
const bundledCouncil =
|
|
17326
|
+
const localCouncil = resolve13(basePath, ".codeconductor", "presets", "council.yml");
|
|
17327
|
+
const bundledCouncil = resolve13(SRC_PRESETS_DIR, "council", "council.yml");
|
|
16779
17328
|
try {
|
|
16780
|
-
const content = await
|
|
16781
|
-
await
|
|
16782
|
-
await
|
|
17329
|
+
const content = await readFile11(bundledCouncil, "utf-8");
|
|
17330
|
+
await mkdir10(dirname6(localCouncil), { recursive: true });
|
|
17331
|
+
await writeFile9(localCouncil, content, "utf-8");
|
|
16783
17332
|
updated.push(localCouncil);
|
|
16784
17333
|
} catch (e) {
|
|
16785
17334
|
throw new Error(`Failed to update council.yml: ${e}`);
|
|
16786
17335
|
}
|
|
16787
17336
|
}
|
|
16788
17337
|
if (updateResults.policy) {
|
|
16789
|
-
const localPolicy =
|
|
17338
|
+
const localPolicy = resolve13(basePath, ".codeconductor", "presets", "policy.yml");
|
|
16790
17339
|
try {
|
|
16791
|
-
const content = await
|
|
16792
|
-
await
|
|
16793
|
-
await
|
|
17340
|
+
const content = await readFile11(POLICY_PATH, "utf-8");
|
|
17341
|
+
await mkdir10(dirname6(localPolicy), { recursive: true });
|
|
17342
|
+
await writeFile9(localPolicy, content, "utf-8");
|
|
16794
17343
|
updated.push(localPolicy);
|
|
16795
17344
|
} catch (e) {
|
|
16796
17345
|
throw new Error(`Failed to update policy.yml: ${e}`);
|
|
@@ -16842,12 +17391,12 @@ async function updateCommand(options) {
|
|
|
16842
17391
|
let targetPath = f.path;
|
|
16843
17392
|
let targetBase = basePath;
|
|
16844
17393
|
if ((targetName === "agy" || targetName === "gemini") && isGlobal) {
|
|
16845
|
-
targetBase =
|
|
17394
|
+
targetBase = resolve13(homedir9(), ".gemini", "config");
|
|
16846
17395
|
targetPath = targetPath.replace(/^\.agents\/?/, "");
|
|
16847
17396
|
}
|
|
16848
17397
|
return {
|
|
16849
17398
|
...f,
|
|
16850
|
-
path:
|
|
17399
|
+
path: resolve13(targetBase, targetPath)
|
|
16851
17400
|
};
|
|
16852
17401
|
});
|
|
16853
17402
|
const filesToWrite = resolvedFiles.filter((f) => t.files.includes(f.path));
|
|
@@ -16875,19 +17424,19 @@ async function updateCommand(options) {
|
|
|
16875
17424
|
for (const s of updateResults.skills) {
|
|
16876
17425
|
newSkillsLock[s.id] = s.latestVersion;
|
|
16877
17426
|
}
|
|
16878
|
-
let lockDest =
|
|
17427
|
+
let lockDest = resolve13(basePath, ".codeconductor", "skills-lock.json");
|
|
16879
17428
|
try {
|
|
16880
|
-
const statAgents = await stat3(
|
|
17429
|
+
const statAgents = await stat3(resolve13(basePath, ".agents"));
|
|
16881
17430
|
if (statAgents.isDirectory()) {
|
|
16882
|
-
const statCodeConductor = await stat3(
|
|
17431
|
+
const statCodeConductor = await stat3(resolve13(basePath, ".codeconductor")).catch(() => null);
|
|
16883
17432
|
if (!statCodeConductor) {
|
|
16884
|
-
lockDest =
|
|
17433
|
+
lockDest = resolve13(basePath, ".agents", "skills-lock.json");
|
|
16885
17434
|
}
|
|
16886
17435
|
}
|
|
16887
17436
|
} catch {}
|
|
16888
17437
|
try {
|
|
16889
|
-
await
|
|
16890
|
-
await
|
|
17438
|
+
await mkdir10(dirname6(lockDest), { recursive: true });
|
|
17439
|
+
await writeFile9(lockDest, JSON.stringify(newSkillsLock, null, 2), "utf-8");
|
|
16891
17440
|
updated.push(lockDest);
|
|
16892
17441
|
} catch (e) {
|
|
16893
17442
|
throw new Error(`Failed to write skills-lock.json: ${e}`);
|
|
@@ -16998,6 +17547,7 @@ Commands:
|
|
|
16998
17547
|
update Update installed presets
|
|
16999
17548
|
help / cc-help Show preset inventory (skills, subagents, commands)
|
|
17000
17549
|
debt-harvest / harvest Scan source files for deferred debt items
|
|
17550
|
+
goal / cc-goal Plan goal into task graph with dependencies
|
|
17001
17551
|
|
|
17002
17552
|
Options:
|
|
17003
17553
|
--help, -h Show this help message
|
|
@@ -17123,6 +17673,13 @@ async function routeCommand(args, projectRoot) {
|
|
|
17123
17673
|
dir: options.dir,
|
|
17124
17674
|
output: flags.output
|
|
17125
17675
|
});
|
|
17676
|
+
case "goal":
|
|
17677
|
+
case "cc-goal":
|
|
17678
|
+
return goalCommand({
|
|
17679
|
+
objective: subcommand || options.objective || "",
|
|
17680
|
+
projectRoot,
|
|
17681
|
+
output: flags.output
|
|
17682
|
+
});
|
|
17126
17683
|
case "seo": {
|
|
17127
17684
|
if (subcommand === "audit") {
|
|
17128
17685
|
return seoAuditCommand({
|
package/package.json
CHANGED
package/presets/agy/AGENTS.md
CHANGED
|
@@ -248,6 +248,30 @@ High-risk checkpoint: [yes | no — if yes, describe what triggers a stop]
|
|
|
248
248
|
|
|
249
249
|
---
|
|
250
250
|
|
|
251
|
+
### goal-planner
|
|
252
|
+
|
|
253
|
+
**Role:** Transforms an objective string into a YAML task graph with dependencies. Pure function: objective → GoalGraph. No side effects.
|
|
254
|
+
|
|
255
|
+
**Use when:** User runs `codeconductor goal "<objective>"` or the orchestrator needs a multi-step plan before delegation.
|
|
256
|
+
|
|
257
|
+
**Permissions:**
|
|
258
|
+
- read: `allow`
|
|
259
|
+
- edit: `deny`
|
|
260
|
+
- bash: `deny`
|
|
261
|
+
- network: `deny`
|
|
262
|
+
|
|
263
|
+
**Model:** `{{MODEL_GEMINI}}`
|
|
264
|
+
|
|
265
|
+
**Does not:** Write files. Execute commands. Make routing decisions.
|
|
266
|
+
|
|
267
|
+
**Template matching:**
|
|
268
|
+
The planner matches objective keywords against built-in templates (auth, crud, search, notification, migration) and falls back to a generic 4-task chain: task-coach → architect → implementer → tester.
|
|
269
|
+
|
|
270
|
+
**Dependency order delegation (orchestrator):**
|
|
271
|
+
When the orchestrator receives a GoalGraph, it delegates tasks in dependency order. A task is only routed after all its `depends_on` targets complete with status `done`. If a dependency is `blocked`, the dependent task remains `pending`. The orchestrator tracks the graph state in `.codeconductor/current-goal.yml`.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
251
275
|
### architect
|
|
252
276
|
|
|
253
277
|
**Role:** Designs the technical approach. Produces ADRs, module boundaries, and API contracts.
|
package/presets/codex/AGENTS.md
CHANGED
|
@@ -790,6 +790,40 @@ module, or identifying the impact radius of a change.
|
|
|
790
790
|
|
|
791
791
|
---
|
|
792
792
|
|
|
793
|
+
### goal-planner
|
|
794
|
+
|
|
795
|
+
**Role:** Transforms an objective string into a YAML task graph with
|
|
796
|
+
dependencies. Pure function: objective → GoalGraph. No side effects.
|
|
797
|
+
|
|
798
|
+
**Use when:** User runs `codeconductor goal "<objective>"` or the orchestrator
|
|
799
|
+
needs a multi-step plan before delegation.
|
|
800
|
+
|
|
801
|
+
**Permissions:**
|
|
802
|
+
|
|
803
|
+
- read: `allow`
|
|
804
|
+
- edit: `deny`
|
|
805
|
+
- bash: `deny`
|
|
806
|
+
- network: `deny`
|
|
807
|
+
|
|
808
|
+
**Does not:** Write files. Execute commands. Make routing decisions.
|
|
809
|
+
|
|
810
|
+
**Template matching:**
|
|
811
|
+
|
|
812
|
+
The planner matches objective keywords against built-in templates (auth, crud,
|
|
813
|
+
search, notification, migration) and falls back to a generic 4-task chain:
|
|
814
|
+
`task-coach → architect → implementer → tester`.
|
|
815
|
+
|
|
816
|
+
**Dependency order delegation (orchestrator):**
|
|
817
|
+
|
|
818
|
+
When the orchestrator receives a GoalGraph, it delegates tasks in dependency
|
|
819
|
+
order. A task is only routed after all its `depends_on` targets complete with
|
|
820
|
+
status `done`. If a dependency is `blocked`, the dependent task remains `pending`.
|
|
821
|
+
The orchestrator tracks the graph state in `.codeconductor/current-goal.yml`.
|
|
822
|
+
|
|
823
|
+
**Model:** `{{MODEL_CODEX}}`
|
|
824
|
+
|
|
825
|
+
---
|
|
826
|
+
|
|
793
827
|
## Hard Rules (all agents)
|
|
794
828
|
|
|
795
829
|
These apply regardless of agent or task.
|
|
@@ -57,6 +57,13 @@ agents:
|
|
|
57
57
|
gemini: gemini-2.5-flash
|
|
58
58
|
cursor: gpt-5.4-mini
|
|
59
59
|
agy: gemini-2.5-flash
|
|
60
|
+
goal-planner:
|
|
61
|
+
claude: claude-haiku-4-5-20251001
|
|
62
|
+
opencode: opencode-go/qwen3.6-plus
|
|
63
|
+
codex: gpt-5.4-mini
|
|
64
|
+
gemini: gemini-2.5-flash
|
|
65
|
+
cursor: gpt-5.4-mini
|
|
66
|
+
agy: gemini-2.5-flash
|
|
60
67
|
tools:
|
|
61
68
|
Read:
|
|
62
69
|
agy: view_file
|
|
@@ -51,6 +51,12 @@ agents:
|
|
|
51
51
|
codex: gpt-5.4-mini
|
|
52
52
|
gemini: gemini-2.5-flash
|
|
53
53
|
cursor: gpt-5.4-mini
|
|
54
|
+
goal-planner:
|
|
55
|
+
claude: claude-haiku-4-5-20251001
|
|
56
|
+
opencode: opencode-go/qwen3.6-plus
|
|
57
|
+
codex: gpt-5.4-mini
|
|
58
|
+
gemini: gemini-2.5-flash
|
|
59
|
+
cursor: gpt-5.4-mini
|
|
54
60
|
tools:
|
|
55
61
|
Read:
|
|
56
62
|
claude: ViewCodeItem / ReadFile
|
|
@@ -52,6 +52,12 @@ agents:
|
|
|
52
52
|
codex: gpt-5.4-mini
|
|
53
53
|
gemini: gemini-2.5-flash
|
|
54
54
|
cursor: gpt-5.4-mini
|
|
55
|
+
goal-planner:
|
|
56
|
+
claude: claude-haiku-4-5-20251001
|
|
57
|
+
opencode: opencode-go/qwen3.6-plus
|
|
58
|
+
codex: gpt-5.4-mini
|
|
59
|
+
gemini: gemini-2.5-flash
|
|
60
|
+
cursor: gpt-5.4-mini
|
|
55
61
|
tools:
|
|
56
62
|
Read:
|
|
57
63
|
claude: ViewCodeItem / ReadFile
|
|
@@ -51,6 +51,12 @@ agents:
|
|
|
51
51
|
codex: gpt-5.4-mini
|
|
52
52
|
gemini: gemini-2.5-flash
|
|
53
53
|
cursor: gpt-5.4-mini
|
|
54
|
+
goal-planner:
|
|
55
|
+
claude: claude-haiku-4-5-20251001
|
|
56
|
+
opencode: opencode-go/qwen3.6-plus
|
|
57
|
+
codex: gpt-5.4-mini
|
|
58
|
+
gemini: gemini-2.5-flash
|
|
59
|
+
cursor: gpt-5.4-mini
|
|
54
60
|
tools:
|
|
55
61
|
Read:
|
|
56
62
|
claude: ViewCodeItem / ReadFile
|
|
@@ -51,6 +51,12 @@ agents:
|
|
|
51
51
|
codex: gpt-5.4-mini
|
|
52
52
|
gemini: gemini-2.5-flash
|
|
53
53
|
cursor: gpt-5.4-mini
|
|
54
|
+
goal-planner:
|
|
55
|
+
claude: claude-haiku-4-5-20251001
|
|
56
|
+
opencode: opencode-go/qwen3.6-plus
|
|
57
|
+
codex: gpt-5.4-mini
|
|
58
|
+
gemini: gemini-2.5-flash
|
|
59
|
+
cursor: gpt-5.4-mini
|
|
54
60
|
tools:
|
|
55
61
|
Read:
|
|
56
62
|
claude: ViewCodeItem / ReadFile
|
|
@@ -51,6 +51,12 @@ agents:
|
|
|
51
51
|
codex: gpt-5.4-mini
|
|
52
52
|
gemini: gemini-2.5-flash
|
|
53
53
|
cursor: gpt-5.4-mini
|
|
54
|
+
goal-planner:
|
|
55
|
+
claude: claude-haiku-4-5-20251001
|
|
56
|
+
opencode: opencode-go/deepseek-v4-flash
|
|
57
|
+
codex: gpt-5.4-mini
|
|
58
|
+
gemini: gemini-2.5-flash
|
|
59
|
+
cursor: gpt-5.4-mini
|
|
54
60
|
permissions:
|
|
55
61
|
Read: read
|
|
56
62
|
Write: edit
|