thoth-agents 0.2.8 → 0.2.10
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 +11 -4
- package/dist/agents/prompt-dialects.d.ts +8 -0
- package/dist/{chunk-75JOF37E.js → chunk-MF5NNCPC.js} +1 -1
- package/dist/{chunk-YLRPDTU7.js → chunk-WBRGPRRB.js} +51 -16
- package/dist/{chunk-FM7HCZSW.js → chunk-YYVE7YHR.js} +41 -27
- package/dist/cli/codex-install.d.ts +2 -0
- package/dist/cli/index.js +3 -3
- package/dist/cli/tui/index.js +2 -2
- package/dist/harness/adapters/codex-surfaces.d.ts +7 -8
- package/dist/harness/core/sdd.d.ts +2 -0
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/src/skills/sdd-tasks/SKILL.md +39 -15
package/README.md
CHANGED
|
@@ -22,8 +22,9 @@ surface that fits it best.
|
|
|
22
22
|
OpenCode remains the stable default path: native plugin install, native `task`
|
|
23
23
|
delegation, optional tmux monitoring, and generated config. Codex is supported
|
|
24
24
|
through an explicit agent-pack and Personal plugin setup path, with documented
|
|
25
|
-
trust review and
|
|
26
|
-
|
|
25
|
+
trust review and the current `collaboration.*` delegation surface. Codex can
|
|
26
|
+
spawn and coordinate generic tasks programmatically, while named installed-role
|
|
27
|
+
selection and per-role enforcement remain instruction-level. Claude Code is a first-class path: a
|
|
27
28
|
single auto-discovered plugin package with native subagents, harness-enforced
|
|
28
29
|
hooks, MCP, skills, and per-agent tool permissions.
|
|
29
30
|
|
|
@@ -55,7 +56,7 @@ hooks, MCP, skills, and per-agent tool permissions.
|
|
|
55
56
|
| Harness | Status | Setup path | Notes |
|
|
56
57
|
| ----------- | -------------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
57
58
|
| OpenCode | Stable default | `npx thoth-agents@latest install` or `npx thoth-agents@latest install --agent=opencode` | Native plugin config, native`task` delegation, optional tmux panes, OpenCode provider auth. |
|
|
58
|
-
| Codex | Supported explicit path | `npx thoth-agents@latest install --agent=codex` | Installs ambient/root guidance, six role subagents, and a Personal plugin source. Requires`/plugins` and `/hooks` trust review.
|
|
59
|
+
| Codex | Supported explicit path | `npx thoth-agents@latest install --agent=codex` | Installs ambient/root guidance, six role subagents, and a Personal plugin source. Uses the current `collaboration.*` tools for generic delegation; named-role selection and per-role enforcement remain instruction-level. Requires `/plugins` and `/hooks` trust review. |
|
|
59
60
|
| Claude Code | Supported first-class path | `npx thoth-agents@latest install --agent=claude` | Installs one Claude Code plugin: six specialist subagents (`Task(subagent_type: ...)`), an `orchestrator` agent activated as the main thread via `settings.json`, `.mcp.json`, and bundled skills. Role permissions are enforced by subagent `tools`. |
|
|
60
61
|
|
|
61
62
|
OpenCode can load the plugin with:
|
|
@@ -128,6 +129,12 @@ Codex install does not create a selectable orchestrator TOML, does not bypass
|
|
|
128
129
|
trust review, and does not make role permissions or memory governance hard
|
|
129
130
|
runtime guarantees unless Codex exposes those controls.
|
|
130
131
|
|
|
132
|
+
Generated root guidance binds delegation to direct `collaboration.*` tools:
|
|
133
|
+
`spawn_agent({ task_name, message, fork_turns? })`, mailbox-oriented
|
|
134
|
+
`wait_agent`, live status through `list_agents`, non-triggering `send_message`,
|
|
135
|
+
turn-triggering `followup_task`, and explicit `interrupt_agent`. A wait timeout
|
|
136
|
+
or silence remains in progress; it is not a collected result body.
|
|
137
|
+
|
|
131
138
|
### Claude Code
|
|
132
139
|
|
|
133
140
|
Preview, then install the plugin package:
|
|
@@ -363,7 +370,7 @@ supports that delivery surface.
|
|
|
363
370
|
| ---------------- | ---------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------- | ----------------------------------------------------------------- |
|
|
364
371
|
| Skills | Requirements, SDD, review, execution workflows | Copied into the OpenCode skills directory when`--skills=yes` | Packaged as plugin-bundled skills for the Personal plugin source | Bundled in the plugin`skills/` directory |
|
|
365
372
|
| MCPs | `exa`, `context7`, `grep_app`, `thoth_mem` | Registered by generated OpenCode plugin config | Packaged/configured only on validated Codex surfaces | Bundled in the plugin`.mcp.json` (`type: "http"` for URL servers) |
|
|
366
|
-
| Delegation | Seven-role specialist workflow | Native`task` tool |
|
|
373
|
+
| Delegation | Seven-role specialist workflow | Native`task` tool | Direct `collaboration.*` generic task delegation; role behavior carried by task name/message | Native`Task(subagent_type: ...)` over auto-discovered subagents |
|
|
367
374
|
| Blocking choices | Use a structured question surface | OpenCode`question` tool | `request_user_input` when enabled and available | `AskUserQuestion` tool |
|
|
368
375
|
|
|
369
376
|
See [docs/skills-and-mcps.md](docs/skills-and-mcps.md) for the detailed matrix.
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { AgentDispatchMethod, AgentRoleName } from '../harness/core/agent-pack';
|
|
2
2
|
import type { HarnessCapabilities, HarnessId } from '../harness/types';
|
|
3
3
|
export type AgentPromptRole = AgentRoleName;
|
|
4
|
+
export interface LifecycleNomenclature {
|
|
5
|
+
statusAction: string;
|
|
6
|
+
terminalState: string;
|
|
7
|
+
nonterminalState: string;
|
|
8
|
+
sameSessionProbe: string;
|
|
9
|
+
enforcement: 'runtime-supported' | 'instruction-only' | 'unknown';
|
|
10
|
+
}
|
|
4
11
|
export interface ToolNomenclature {
|
|
5
12
|
delegationTool: string;
|
|
6
13
|
backgroundDelegationTool?: string;
|
|
@@ -8,6 +15,7 @@ export interface ToolNomenclature {
|
|
|
8
15
|
userQuestionTool: string;
|
|
9
16
|
progressTool: string;
|
|
10
17
|
hostStatusSurface?: string;
|
|
18
|
+
lifecycle: LifecycleNomenclature;
|
|
11
19
|
roleReference(role: AgentPromptRole): string;
|
|
12
20
|
}
|
|
13
21
|
export interface CapabilityProfile {
|
|
@@ -710,8 +710,8 @@ var OPENCODE_CAPABILITIES = {
|
|
|
710
710
|
};
|
|
711
711
|
var CODEX_PROMPT_CAPABILITIES = {
|
|
712
712
|
agentDefinitions: "supported",
|
|
713
|
-
delegatedExecution: "
|
|
714
|
-
parallelDelegation: "
|
|
713
|
+
delegatedExecution: "supported",
|
|
714
|
+
parallelDelegation: "supported",
|
|
715
715
|
runtimeHooks: "unknown",
|
|
716
716
|
mcpConfiguration: "supported",
|
|
717
717
|
skillPackaging: "supported",
|
|
@@ -755,6 +755,13 @@ var OPENCODE_PROMPT_DIALECT = {
|
|
|
755
755
|
userQuestionTool: "question",
|
|
756
756
|
progressTool: "todowrite",
|
|
757
757
|
hostStatusSurface: "task_status",
|
|
758
|
+
lifecycle: {
|
|
759
|
+
statusAction: "wait, poll, and collect",
|
|
760
|
+
terminalState: "terminal task_status result",
|
|
761
|
+
nonterminalState: "nonterminal task_status result",
|
|
762
|
+
sameSessionProbe: "task_status on the same task session",
|
|
763
|
+
enforcement: "runtime-supported"
|
|
764
|
+
},
|
|
758
765
|
roleReference: (role) => `@${role}`
|
|
759
766
|
},
|
|
760
767
|
capabilities: supportedCapabilityProfile(OPENCODE_CAPABILITIES),
|
|
@@ -775,12 +782,19 @@ var OPENCODE_PROMPT_DIALECT = {
|
|
|
775
782
|
var CODEX_PROMPT_DIALECT = {
|
|
776
783
|
harness: "codex",
|
|
777
784
|
tools: {
|
|
778
|
-
delegationTool: "
|
|
779
|
-
backgroundDelegationTool: "
|
|
780
|
-
backgroundStatusTool: "
|
|
785
|
+
delegationTool: "collaboration.spawn_agent",
|
|
786
|
+
backgroundDelegationTool: "collaboration.spawn_agent",
|
|
787
|
+
backgroundStatusTool: "collaboration.wait_agent",
|
|
781
788
|
userQuestionTool: "request_user_input",
|
|
782
789
|
progressTool: "functions.update_plan",
|
|
783
|
-
hostStatusSurface: "
|
|
790
|
+
hostStatusSurface: "collaboration.list_agents",
|
|
791
|
+
lifecycle: {
|
|
792
|
+
statusAction: "wait and inspect status",
|
|
793
|
+
terminalState: "terminal mailbox completion or failure update",
|
|
794
|
+
nonterminalState: "collaboration.wait_agent timeout or silence",
|
|
795
|
+
sameSessionProbe: "collaboration.list_agents on the same task path",
|
|
796
|
+
enforcement: "runtime-supported"
|
|
797
|
+
},
|
|
784
798
|
roleReference: (role) => `${role} role agent`
|
|
785
799
|
},
|
|
786
800
|
capabilities: {
|
|
@@ -792,9 +806,9 @@ var CODEX_PROMPT_DIALECT = {
|
|
|
792
806
|
case "root-coordinator":
|
|
793
807
|
return "ambient Codex root session coordinator";
|
|
794
808
|
case "task":
|
|
795
|
-
return "
|
|
809
|
+
return "collaboration.spawn_agent";
|
|
796
810
|
case "synchronous-task-only":
|
|
797
|
-
return "synchronous
|
|
811
|
+
return "synchronous collaboration.spawn_agent only";
|
|
798
812
|
}
|
|
799
813
|
},
|
|
800
814
|
renderRoleInvocation(role) {
|
|
@@ -814,6 +828,13 @@ var CLAUDE_CODE_PROMPT_DIALECT = {
|
|
|
814
828
|
userQuestionTool: "AskUserQuestion",
|
|
815
829
|
progressTool: "TodoWrite",
|
|
816
830
|
hostStatusSurface: "TodoWrite",
|
|
831
|
+
lifecycle: {
|
|
832
|
+
statusAction: "wait, poll, and collect",
|
|
833
|
+
terminalState: "terminal TaskOutput result",
|
|
834
|
+
nonterminalState: "nonterminal TaskOutput result",
|
|
835
|
+
sameSessionProbe: "TaskOutput on the same task session",
|
|
836
|
+
enforcement: "runtime-supported"
|
|
837
|
+
},
|
|
817
838
|
roleReference: (role) => role === "orchestrator" ? "the main-thread orchestrator" : `Task(subagent_type: ${claudeCodeSubagentType(role)})`
|
|
818
839
|
},
|
|
819
840
|
capabilities: supportedCapabilityProfile(CLAUDE_CODE_PROMPT_CAPABILITIES),
|
|
@@ -943,6 +964,7 @@ var SDD_PHASES = [
|
|
|
943
964
|
artifactSkill: "sdd-tasks",
|
|
944
965
|
defaultAgentRole: "quick",
|
|
945
966
|
alternateAgentRoles: ["deep"],
|
|
967
|
+
alternateAgentCondition: "Only when the task plan is complex.",
|
|
946
968
|
delegationReason: "Mechanical conversion of settled design into dependency-ordered execution tasks."
|
|
947
969
|
},
|
|
948
970
|
{
|
|
@@ -1131,6 +1153,10 @@ function alternateSddRoles(id) {
|
|
|
1131
1153
|
const phase = getDelegatedSddPhase(id);
|
|
1132
1154
|
return phase.alternateAgentRoles?.length ? renderRoleList(phase.alternateAgentRoles) : "";
|
|
1133
1155
|
}
|
|
1156
|
+
function alternateSddCondition(id) {
|
|
1157
|
+
const condition = getDelegatedSddPhase(id).alternateAgentCondition;
|
|
1158
|
+
return condition ? condition.replace(/^Only/, "only").replace(/\.$/, "") : "";
|
|
1159
|
+
}
|
|
1134
1160
|
function supportSddRoles(id) {
|
|
1135
1161
|
const phase = getDelegatedSddPhase(id);
|
|
1136
1162
|
return phase.supportingAgentRoles?.length ? renderRoleList(phase.supportingAgentRoles) : "";
|
|
@@ -1142,7 +1168,7 @@ function persistenceSddRole(id) {
|
|
|
1142
1168
|
function renderSddDelegationMatrix() {
|
|
1143
1169
|
return `<sdd-delegation-matrix>
|
|
1144
1170
|
- sdd-init -> ${primarySddRole("init")} (+${supportSddRoles("init")}, if openspec/ missing); sdd-explore -> ${primarySddRole("explore")} (+${supportSddRoles("explore")})
|
|
1145
|
-
- sdd-propose/sdd-spec/sdd-design -> ${primarySddRole("proposal")}; sdd-clarify -> ${primarySddRole("clarify")}; sdd-tasks -> ${primarySddRole("tasks")} (fallback: ${alternateSddRoles("tasks")})
|
|
1171
|
+
- sdd-propose/sdd-spec/sdd-design -> ${primarySddRole("proposal")}; sdd-clarify -> ${primarySddRole("clarify")}; sdd-tasks -> ${primarySddRole("tasks")} (fallback: ${alternateSddRoles("tasks")} ${alternateSddCondition("tasks")})
|
|
1146
1172
|
- plan-reviewer -> ${primarySddRole("plan-review")}; sdd-apply -> ${primarySddRole("apply")} (fallback: ${alternateSddRoles("apply")}); sdd-verify -> ${primarySddRole("verify")} (persistence: ${persistenceSddRole("verify")}); sdd-archive -> ${primarySddRole("archive")}
|
|
1147
1173
|
</sdd-delegation-matrix>`;
|
|
1148
1174
|
}
|
|
@@ -1280,11 +1306,9 @@ For {{role.explorer}}/{{role.librarian}}, ask narrow fact-finding questions for
|
|
|
1280
1306
|
- Experimental background \`{{backgroundDelegationTool}}\` is allowed only for {{role.explorer}} and {{role.librarian}} for asynchronous delegation.
|
|
1281
1307
|
- {{role.oracle}}, {{role.designer}}, {{role.quick}}, and {{role.deep}} always use normal synchronous \`{{delegationTool}}\` execution.
|
|
1282
1308
|
- When using background \`{{delegationTool}}\`, treat it as conditional and non-portable: if the host does not expose the experimental path, fall back to normal synchronous \`{{delegationTool}}\`.
|
|
1283
|
-
- Use \`{{backgroundStatusTool}}\` to
|
|
1284
|
-
-
|
|
1285
|
-
-
|
|
1286
|
-
- Never switch to \`default\`, \`worker\`, or any other role.
|
|
1287
|
-
- After 3 failures, stay on the same role; if a same-role model override exists, use it. Otherwise report a capacity blocker.
|
|
1309
|
+
- Use \`{{backgroundStatusTool}}\` to {{lifecycleStatusAction}}: treat \`{{lifecycleNonterminalState}}\` as in progress and probe the same session via \`{{lifecycleSameSessionProbe}}\`; no retry/reroute/interruption before \`{{lifecycleTerminalState}}\`, an explicit user deadline, user cancellation, or a superseding request.
|
|
1310
|
+
- Terminal result-quality and required-artifact checks share one sharpened retry; nonterminal probes use none.
|
|
1311
|
+
- Capacity is separate: retry the named role up to 3 times; never switch to \`default\`, \`worker\`, or another role; then use a same-role model override or report a blocker.
|
|
1288
1312
|
- Write-capable dispatches must include task instructions and handoff retrieval instructions when a root-owned handoff summary exists, so implementers can recover context without rediscovering settled scope.
|
|
1289
1313
|
- Never tell sub-agents to discard working-tree changes.
|
|
1290
1314
|
</dispatch>
|
|
@@ -1311,7 +1335,6 @@ Hard gates:
|
|
|
1311
1335
|
- Group consecutive ready SDD tasks for the same execution agent into one dispatch when dependencies, scope, and verification can be handled together. Keep per-task tracking and evidence; do not split a compatible {{role.designer}}/{{role.quick}}/{{role.deep}} run into one delegation per checkbox.
|
|
1312
1336
|
|
|
1313
1337
|
SDD dispatch envelope must include: skill name, persistence mode, pipeline type, change name, project name, needed prior artifact context, verification expectation, and return envelope.
|
|
1314
|
-
After each phase, verify the sub-agent reported the openspec path and/or thoth-mem topic_key. Retry once if missing.
|
|
1315
1338
|
|
|
1316
1339
|
Artifact governance handoff:
|
|
1317
1340
|
- After \`sdd-tasks\`, you may surface report-only artifact governance findings before execution preparation starts.
|
|
@@ -1614,7 +1637,19 @@ function renderRoleText(section, dialect) {
|
|
|
1614
1637
|
).replaceAll(
|
|
1615
1638
|
"{{backgroundStatusTool}}",
|
|
1616
1639
|
dialect.tools.backgroundStatusTool ?? dialect.tools.hostStatusSurface ?? ""
|
|
1617
|
-
).replaceAll("{{userQuestionTool}}", dialect.tools.userQuestionTool).replaceAll("{{progressTool}}", dialect.tools.progressTool).replaceAll(
|
|
1640
|
+
).replaceAll("{{userQuestionTool}}", dialect.tools.userQuestionTool).replaceAll("{{progressTool}}", dialect.tools.progressTool).replaceAll(
|
|
1641
|
+
"{{lifecycleStatusAction}}",
|
|
1642
|
+
dialect.tools.lifecycle.statusAction
|
|
1643
|
+
).replaceAll(
|
|
1644
|
+
"{{lifecycleTerminalState}}",
|
|
1645
|
+
dialect.tools.lifecycle.terminalState
|
|
1646
|
+
).replaceAll(
|
|
1647
|
+
"{{lifecycleNonterminalState}}",
|
|
1648
|
+
dialect.tools.lifecycle.nonterminalState
|
|
1649
|
+
).replaceAll(
|
|
1650
|
+
"{{lifecycleSameSessionProbe}}",
|
|
1651
|
+
dialect.tools.lifecycle.sameSessionProbe
|
|
1652
|
+
).replaceAll("{{dispatch.task}}", dialect.dispatchLabel("task")).replaceAll(
|
|
1618
1653
|
"{{dispatch.synchronous-task-only}}",
|
|
1619
1654
|
dialect.dispatchLabel("synchronous-task-only")
|
|
1620
1655
|
).replace(
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
renderRolePrompt,
|
|
38
38
|
writeConfig,
|
|
39
39
|
writeLiteConfig
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-WBRGPRRB.js";
|
|
41
41
|
|
|
42
42
|
// src/cli/codex-paths.ts
|
|
43
43
|
import { homedir } from "os";
|
|
@@ -611,26 +611,31 @@ var CODEX_SURFACES = [
|
|
|
611
611
|
id: "per-agent-runtime-permissions",
|
|
612
612
|
target: "permission-control",
|
|
613
613
|
status: "unsupported",
|
|
614
|
-
fields: [
|
|
614
|
+
fields: [
|
|
615
|
+
"named installed-role selection",
|
|
616
|
+
"per-role permission enforcement",
|
|
617
|
+
"per-agent tool allow/deny equivalent to OpenCode permissions"
|
|
618
|
+
],
|
|
615
619
|
diagnosticCode: "codex.permission.memory.enforcement_gap",
|
|
616
|
-
summary: "
|
|
620
|
+
summary: "Named installed-role selection and per-role permission enforcement are instruction-only because collaboration.spawn_agent has no role selector; OpenCode-style per-agent MCP/tool deny maps are not validated.",
|
|
617
621
|
evidence: "Codex approvals/security docs cover sandbox and approval policies, not exact OpenCode per-agent permission maps.",
|
|
618
622
|
fallback: "instruction-only"
|
|
619
623
|
},
|
|
620
624
|
{
|
|
621
625
|
id: "programmatic-delegation-runtime",
|
|
622
626
|
target: "delegation-runtime",
|
|
623
|
-
status: "
|
|
627
|
+
status: "validated",
|
|
624
628
|
fields: [
|
|
625
|
-
"
|
|
626
|
-
"
|
|
627
|
-
"
|
|
628
|
-
"
|
|
629
|
+
"collaboration.spawn_agent",
|
|
630
|
+
"collaboration.wait_agent",
|
|
631
|
+
"collaboration.list_agents",
|
|
632
|
+
"collaboration.send_message",
|
|
633
|
+
"collaboration.followup_task",
|
|
634
|
+
"collaboration.interrupt_agent"
|
|
629
635
|
],
|
|
630
|
-
diagnosticCode: "codex.delegation.runtime.
|
|
631
|
-
summary: "Codex
|
|
632
|
-
evidence: "
|
|
633
|
-
fallback: "instruction-only"
|
|
636
|
+
diagnosticCode: "codex.delegation.runtime.validated",
|
|
637
|
+
summary: "The current Codex collaboration surface supports generic programmatic delegation, mailbox waits, live task-tree inspection, messages, follow-up turns, and explicit interruption.",
|
|
638
|
+
evidence: "The callable runtime exposes collaboration.spawn_agent with task_name, message, and optional fork_turns plus wait_agent, list_agents, send_message, followup_task, and interrupt_agent."
|
|
634
639
|
},
|
|
635
640
|
{
|
|
636
641
|
id: "parent-context-injection",
|
|
@@ -1432,15 +1437,18 @@ function renderCodexRolePrompt(roleName, config, model) {
|
|
|
1432
1437
|
function codexInternalHandoffGuidance() {
|
|
1433
1438
|
return [
|
|
1434
1439
|
"<codex-delegation-guidance>",
|
|
1435
|
-
"- The user has explicitly authorized this generated Codex orchestrator to use `
|
|
1436
|
-
"-
|
|
1440
|
+
"- The user has explicitly authorized this generated Codex orchestrator to use `collaboration.spawn_agent` whenever delegation is required by these instructions, without needing a fresh user request for subagents in each task.",
|
|
1441
|
+
"- Collaboration tools are direct tools and must not be called from inside `functions.exec`.",
|
|
1442
|
+
"- Delegate with `collaboration.spawn_agent` using `task_name`, `message`, and optional `fork_turns`; `fork_turns` must be `none`, `all`, or a positive integer string.",
|
|
1443
|
+
"- Role behavior is carried by `task_name` and `message`; named installed-role selection and hard role/profile enforcement are instruction-level because this surface has no role selector.",
|
|
1437
1444
|
"- Pass the self-contained delegated task instructions plus handoff retrieval instructions in `message`; do not embed the root-owned handoff summary body in `message`.",
|
|
1438
1445
|
'- When memory recovery is delegated, include parent `session_id`, project, permissions, and the recovery funnel `mem_recall(mode="compact")` -> `mem_recall(mode="context")` -> `mem_get(...)`.',
|
|
1439
1446
|
'- For that funnel, use `mem_recall` `limit` from 1 to 20; use `mem_get` with `kind="observation"|"prompt"`, `include_timeline=true` plus `before`/`after`, and `offset`/`max_length`; `mem_project(action="graph")` relations are `HAS_TYPE`, `IN_PROJECT`, `HAS_TOPIC_KEY`, `HAS_WHAT`, `HAS_WHY`, `HAS_WHERE`, and `HAS_LEARNED`.',
|
|
1440
|
-
"- Do not include the handoff body in `message
|
|
1441
|
-
"-
|
|
1442
|
-
"-
|
|
1443
|
-
"- Use `
|
|
1447
|
+
"- Do not include the handoff body in `message`.",
|
|
1448
|
+
"- `collaboration.wait_agent` waits for mailbox updates. A `collaboration.wait_agent` timeout or silence is nonterminal and remains in progress, so inspect `collaboration.list_agents` with the same task path before deciding what to do next.",
|
|
1449
|
+
"- `collaboration.send_message` delivers a message without triggering a turn; `collaboration.followup_task` triggers a turn when an idle task must continue.",
|
|
1450
|
+
"- Use `collaboration.interrupt_agent` only for explicit cancellation, a deadline, or supersession.",
|
|
1451
|
+
"- Do not invent result payloads or numeric wait, poll, or timeout rules.",
|
|
1444
1452
|
"- Memory ownership, handoff recovery, permissions, and prompt-body exclusion are instruction-level unless the active Codex runtime documents stronger enforcement.",
|
|
1445
1453
|
"</codex-delegation-guidance>"
|
|
1446
1454
|
].join("\n");
|
|
@@ -1488,8 +1496,7 @@ function renderCodexRootInstructions(config) {
|
|
|
1488
1496
|
"- If metadata tooling is unavailable, or the required fields are missing, disclose that memory bootstrap could not run and continue without claiming memory was saved.",
|
|
1489
1497
|
'- Before delegating after meaningful context changes, save or refresh the handoff body with root-owned mem_session(action="summary") or mem_save(kind="session_summary") when available; if unavailable, disclose that root-owned compaction could not be persisted.',
|
|
1490
1498
|
"- Use the ambient Codex root session as the delegate-first root coordinator; do not generate or select an orchestrator TOML.",
|
|
1491
|
-
"- Delegate by invoking `
|
|
1492
|
-
"- After receiving a delegated subagent response, close that subagent session unless you will retry or intentionally keep using that exact same session; explorer and librarian sessions must always be closed immediately after their response, and retry sessions must be closed after the retry result unless explicit same-session reuse is still required.",
|
|
1499
|
+
"- Delegate by invoking `collaboration.spawn_agent`; use role-prefixed task names and explicit role instructions for the installed Codex role agents: explorer, librarian, oracle, designer, quick, and deep.",
|
|
1493
1500
|
"- Use packaged thoth-agents plugin capabilities through Codex plugin, skill, MCP, and hook review surfaces after enabling them with /plugins and /hooks.",
|
|
1494
1501
|
"- For blocking user decisions in Codex Default mode, use request_user_input after features.default_mode_request_user_input is enabled; do not ask those questions in plain prose.",
|
|
1495
1502
|
"- Whenever the root orchestrator calls `request_user_input`, it MUST NEVER set or pass `autoResolutionMs`; omit the field entirely.",
|
|
@@ -1998,6 +2005,10 @@ ${content}`;
|
|
|
1998
2005
|
function roleManagedModelStateKey(path4) {
|
|
1999
2006
|
return basename(path4);
|
|
2000
2007
|
}
|
|
2008
|
+
function normalizeCodexRuntimeModel(model) {
|
|
2009
|
+
const separator = model.indexOf("/");
|
|
2010
|
+
return separator === -1 ? model : model.slice(separator + 1);
|
|
2011
|
+
}
|
|
2001
2012
|
function applyCodexManagedModelOverrides(config, overrides) {
|
|
2002
2013
|
if (config.dryRun) {
|
|
2003
2014
|
return {
|
|
@@ -2044,7 +2055,8 @@ function applyCodexManagedModelOverrides(config, overrides) {
|
|
|
2044
2055
|
);
|
|
2045
2056
|
}
|
|
2046
2057
|
const before = existsSync5(roleItem.targetPath) ? readFileSync5(roleItem.targetPath, "utf8") : roleItem.content;
|
|
2047
|
-
|
|
2058
|
+
const model = normalizeCodexRuntimeModel(override.model);
|
|
2059
|
+
let updated = replaceRoleTomlModel(before, model);
|
|
2048
2060
|
if (override.clearEffort) {
|
|
2049
2061
|
updated = replaceRoleTomlEffort(updated, void 0);
|
|
2050
2062
|
} else if (override.effort !== void 0) {
|
|
@@ -2054,9 +2066,11 @@ function applyCodexManagedModelOverrides(config, overrides) {
|
|
|
2054
2066
|
changed.push(roleItem.targetPath);
|
|
2055
2067
|
}
|
|
2056
2068
|
const key = roleManagedModelStateKey(roleItem.targetPath);
|
|
2057
|
-
nextState.models[key] =
|
|
2069
|
+
nextState.models[key] = normalizeCodexRuntimeModel(
|
|
2070
|
+
roleItem.renderedModel ?? model
|
|
2071
|
+
);
|
|
2058
2072
|
nextState.configuredModels ??= {};
|
|
2059
|
-
nextState.configuredModels[key] =
|
|
2073
|
+
nextState.configuredModels[key] = model;
|
|
2060
2074
|
if (override.clearEffort) {
|
|
2061
2075
|
if (nextState.configuredEfforts) {
|
|
2062
2076
|
delete nextState.configuredEfforts[key];
|
|
@@ -2186,6 +2200,9 @@ function buildCodexSetupPlan(config) {
|
|
|
2186
2200
|
description: `Materialize Codex role subagent ${target.role}.`,
|
|
2187
2201
|
requiresBackup: existsSync5(target.path),
|
|
2188
2202
|
role: target.role,
|
|
2203
|
+
renderedModel: parseRoleTomlModel(
|
|
2204
|
+
roleArtifactContent(target.role, render.artifacts)
|
|
2205
|
+
),
|
|
2189
2206
|
content: resolveRoleTomlContent({
|
|
2190
2207
|
renderedContent: roleArtifactContent(target.role, render.artifacts),
|
|
2191
2208
|
targetPath: target.path,
|
|
@@ -3930,10 +3947,7 @@ function buildCodexInstallPlan(context2 = { cwd: process.cwd() }) {
|
|
|
3930
3947
|
);
|
|
3931
3948
|
}
|
|
3932
3949
|
function normalizeCodexModel(input) {
|
|
3933
|
-
|
|
3934
|
-
return `${input.provider}/${input.model}`;
|
|
3935
|
-
}
|
|
3936
|
-
return input.model;
|
|
3950
|
+
return normalizeCodexRuntimeModel(input.model);
|
|
3937
3951
|
}
|
|
3938
3952
|
var CODEX_DOCUMENTED_EFFORTS = /* @__PURE__ */ new Set([
|
|
3939
3953
|
"none",
|
|
@@ -21,6 +21,7 @@ export interface CodexSetupPlanItem {
|
|
|
21
21
|
requiresBackup: boolean;
|
|
22
22
|
content?: string;
|
|
23
23
|
role?: CodexRoleName;
|
|
24
|
+
renderedModel?: string;
|
|
24
25
|
}
|
|
25
26
|
export interface CodexSetupPlan {
|
|
26
27
|
dryRun: boolean;
|
|
@@ -44,6 +45,7 @@ export declare function replaceRoleTomlModel(content: string, model: string): st
|
|
|
44
45
|
export declare function parseRoleTomlEffort(content: string): string | undefined;
|
|
45
46
|
export declare function replaceRoleTomlEffort(content: string, effort: string | undefined): string;
|
|
46
47
|
export declare function roleManagedModelStateKey(path: string): string;
|
|
48
|
+
export declare function normalizeCodexRuntimeModel(model: string): string;
|
|
47
49
|
export interface CodexManagedModelOverride {
|
|
48
50
|
role: CodexRoleName;
|
|
49
51
|
model: string;
|
package/dist/cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getOpenCodeVersion,
|
|
5
5
|
isOpenCodeInstalled,
|
|
6
6
|
opencodeAdapter
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-MF5NNCPC.js";
|
|
8
8
|
import {
|
|
9
9
|
CODEX_ROLE_NAMES,
|
|
10
10
|
RECOMMENDED_SKILLS,
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
installRecommendedSkill,
|
|
42
42
|
listOperationHarnesses,
|
|
43
43
|
normalizeEffortSelection
|
|
44
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-YYVE7YHR.js";
|
|
45
45
|
import {
|
|
46
46
|
ALL_AGENT_NAMES,
|
|
47
47
|
CUSTOM_SKILLS,
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
getExistingLiteConfigPath,
|
|
54
54
|
installCustomSkills,
|
|
55
55
|
writeLiteConfig
|
|
56
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-WBRGPRRB.js";
|
|
57
57
|
|
|
58
58
|
// src/cli/index.ts
|
|
59
59
|
import { pathToFileURL } from "url";
|
package/dist/cli/tui/index.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
defaultTuiOperations,
|
|
3
3
|
effortChoicesForModel,
|
|
4
4
|
listOperationHarnesses
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
5
|
+
} from "../../chunk-YYVE7YHR.js";
|
|
6
|
+
import "../../chunk-WBRGPRRB.js";
|
|
7
7
|
|
|
8
8
|
// src/cli/tui/index.tsx
|
|
9
9
|
import { render } from "ink";
|
|
@@ -170,20 +170,19 @@ export declare const CODEX_SURFACES: readonly [{
|
|
|
170
170
|
readonly id: "per-agent-runtime-permissions";
|
|
171
171
|
readonly target: "permission-control";
|
|
172
172
|
readonly status: "unsupported";
|
|
173
|
-
readonly fields: ["per-agent tool allow/deny equivalent to OpenCode permissions"];
|
|
173
|
+
readonly fields: ["named installed-role selection", "per-role permission enforcement", "per-agent tool allow/deny equivalent to OpenCode permissions"];
|
|
174
174
|
readonly diagnosticCode: "codex.permission.memory.enforcement_gap";
|
|
175
|
-
readonly summary: "
|
|
175
|
+
readonly summary: "Named installed-role selection and per-role permission enforcement are instruction-only because collaboration.spawn_agent has no role selector; OpenCode-style per-agent MCP/tool deny maps are not validated.";
|
|
176
176
|
readonly evidence: "Codex approvals/security docs cover sandbox and approval policies, not exact OpenCode per-agent permission maps.";
|
|
177
177
|
readonly fallback: "instruction-only";
|
|
178
178
|
}, {
|
|
179
179
|
readonly id: "programmatic-delegation-runtime";
|
|
180
180
|
readonly target: "delegation-runtime";
|
|
181
|
-
readonly status: "
|
|
182
|
-
readonly fields: ["
|
|
183
|
-
readonly diagnosticCode: "codex.delegation.runtime.
|
|
184
|
-
readonly summary: "Codex
|
|
185
|
-
readonly evidence: "
|
|
186
|
-
readonly fallback: "instruction-only";
|
|
181
|
+
readonly status: "validated";
|
|
182
|
+
readonly fields: ["collaboration.spawn_agent", "collaboration.wait_agent", "collaboration.list_agents", "collaboration.send_message", "collaboration.followup_task", "collaboration.interrupt_agent"];
|
|
183
|
+
readonly diagnosticCode: "codex.delegation.runtime.validated";
|
|
184
|
+
readonly summary: "The current Codex collaboration surface supports generic programmatic delegation, mailbox waits, live task-tree inspection, messages, follow-up turns, and explicit interruption.";
|
|
185
|
+
readonly evidence: "The callable runtime exposes collaboration.spawn_agent with task_name, message, and optional fork_turns plus wait_agent, list_agents, send_message, followup_task, and interrupt_agent.";
|
|
187
186
|
}, {
|
|
188
187
|
readonly id: "parent-context-injection";
|
|
189
188
|
readonly target: "parent-context-injection";
|
|
@@ -15,6 +15,7 @@ export interface SddPhaseContract {
|
|
|
15
15
|
condition?: string;
|
|
16
16
|
defaultAgentRole?: AgentRoleName;
|
|
17
17
|
alternateAgentRoles?: AgentRoleName[];
|
|
18
|
+
alternateAgentCondition?: string;
|
|
18
19
|
supportingAgentRoles?: AgentRoleName[];
|
|
19
20
|
persistenceAgentRole?: AgentRoleName;
|
|
20
21
|
delegationReason?: string;
|
|
@@ -117,6 +118,7 @@ export declare const SDD_PHASES: readonly [{
|
|
|
117
118
|
readonly artifactSkill: "sdd-tasks";
|
|
118
119
|
readonly defaultAgentRole: "quick";
|
|
119
120
|
readonly alternateAgentRoles: ["deep"];
|
|
121
|
+
readonly alternateAgentCondition: "Only when the task plan is complex.";
|
|
120
122
|
readonly delegationReason: "Mechanical conversion of settled design into dependency-ordered execution tasks.";
|
|
121
123
|
}, {
|
|
122
124
|
readonly id: "plan-review";
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
renderOpenCodeAgentConfigs,
|
|
4
4
|
spawn,
|
|
5
5
|
spawnSync
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MF5NNCPC.js";
|
|
7
7
|
import {
|
|
8
8
|
DEFAULT_THOTH_COMMAND,
|
|
9
9
|
POLL_INTERVAL_BACKGROUND_MS,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
installCustomSkills,
|
|
15
15
|
loadPluginConfig,
|
|
16
16
|
stripJsonComments
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-WBRGPRRB.js";
|
|
18
18
|
|
|
19
19
|
// src/index.ts
|
|
20
20
|
import path4 from "path";
|
package/package.json
CHANGED
|
@@ -47,19 +47,43 @@ The orchestrator passes the artifact store mode (`thoth-mem`, `openspec`, or
|
|
|
47
47
|
- In accelerated pipeline, derive task structure directly from the proposal.
|
|
48
48
|
3. If a task plan already exists, recover `sdd/{change-name}/tasks` with the
|
|
49
49
|
same mode-aware retrieval rules before rewriting it.
|
|
50
|
-
4. **
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
4. **Reuse settled evidence before validating**: Reuse settled proposal, design, exploration, and handoff evidence first. Treat accepted scope, success
|
|
51
|
+
criteria, recorded assumptions, and surfaced `handoffHints` as preservation
|
|
52
|
+
constraints. Do not repeat broad discovery merely because the accelerated
|
|
53
|
+
pipeline has no design artifact or because an available artifact omits a
|
|
54
|
+
path.
|
|
55
|
+
5. **Run bounded validation**: Validate only the accepted affected areas, the
|
|
56
|
+
authoritative command source, task-referenced existing files, and neighboring relevant tests needed to make the plan executable.
|
|
57
|
+
- Identify the authoritative command source from project instructions and
|
|
58
|
+
existing conventions (for example `package.json`, `Makefile`, `Cargo.toml`,
|
|
59
|
+
`.csproj`, or `pyproject.toml`). Use only commands confirmed there in
|
|
60
|
+
`Run:` fields; never invent commands or imply that an unchecked command
|
|
61
|
+
exists.
|
|
62
|
+
- For every task that modifies an existing file, verify that path within the
|
|
63
|
+
accepted affected areas. Check neighboring relevant tests only where they
|
|
64
|
+
support a planned task or its Verification block. Never present an unverified path, command, or test reference as confirmed.
|
|
65
|
+
- Do not expand this pass into repository-wide discovery. If a required
|
|
66
|
+
reference remains unresolved, defer or omit the dependent task, add a
|
|
67
|
+
bounded discovery or coordination task when appropriate, and record the
|
|
68
|
+
unresolved reference once under `## Validation Gaps`.
|
|
69
|
+
- Emit one entry per unresolved reference using this exact structure:
|
|
70
|
+
|
|
71
|
+
```md
|
|
72
|
+
## Validation Gaps
|
|
73
|
+
|
|
74
|
+
| Target | Checks performed | Impact / task disposition | Next action |
|
|
75
|
+
| --- | --- | --- | --- |
|
|
76
|
+
| {unverified path, command, or test} | {bounded checks completed} | {blocked, deferred, omitted, or follow-up task} | {specific discovery, owner, or decision needed} |
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- Escalate a gap that prevents an executable plan. If the accumulated gaps or
|
|
80
|
+
cross-area validation exceed bounded mechanical planning, recommend
|
|
81
|
+
escalation or complexity-based routing; do not use role changes as generic
|
|
82
|
+
failure recovery.
|
|
59
83
|
6. Build a phased checklist for `openspec/changes/{change-name}/tasks.md`. In
|
|
60
84
|
`thoth-mem` mode, produce the same canonical checklist content without
|
|
61
85
|
creating the file.
|
|
62
|
-
|
|
86
|
+
7. Use hierarchical numbering and Markdown checkboxes with per-task verification:
|
|
63
87
|
|
|
64
88
|
```md
|
|
65
89
|
# Tasks: {Change Title}
|
|
@@ -112,21 +136,21 @@ The orchestrator passes the artifact store mode (`thoth-mem`, `openspec`, or
|
|
|
112
136
|
- `- [x]` completed
|
|
113
137
|
- `- [-]` skipped — always append a reason: `- [-] 1.2 Task name — skipped: reason here`
|
|
114
138
|
|
|
115
|
-
|
|
116
|
-
|
|
139
|
+
8. Reference concrete file paths and specific spec scenarios in the tasks.
|
|
140
|
+
9. If the selected mode includes thoth-mem, persist the full checklist with:
|
|
117
141
|
|
|
118
142
|
Use the memory tool binding for `mem_save` with the canonical SDD topic key
|
|
119
143
|
and required metadata fields: `title`, `topic_key`, `type`, `project`,
|
|
120
144
|
`scope`, and `content`.
|
|
121
145
|
|
|
122
|
-
|
|
146
|
+
10. After `tasks.md` is generated, the workflow proceeds to an optional oracle
|
|
123
147
|
plan review via the `plan-reviewer` skill. This is managed outside the scope
|
|
124
148
|
of this skill.
|
|
125
|
-
|
|
149
|
+
11. The artifact governance validator may run **after** `sdd-tasks` as a
|
|
126
150
|
report-only handoff. It captures placement guidance for the future
|
|
127
151
|
pre-`sdd-apply` entrypoint, but it does not enforce execution or overlap
|
|
128
152
|
with plan review.
|
|
129
|
-
|
|
153
|
+
12. The orchestrator handles the `[OKAY]` / `[REJECT]` review loop and any
|
|
130
154
|
necessary fixes before proceeding to execution.
|
|
131
155
|
|
|
132
156
|
## Traceability, TDD Ordering, and Handoff Hints
|