thoth-agents 0.3.11 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +182 -389
  2. package/dist/agents/prompt-dialects.d.ts +4 -1
  3. package/dist/agents/prompt-sections.d.ts +2 -1
  4. package/dist/{chunk-CB3EBA7H.js → chunk-5EBXGMOK.js} +1 -1
  5. package/dist/chunk-62L3ORXN.js +30 -0
  6. package/dist/{chunk-GIUU6FNE.js → chunk-Q6SDM4KP.js} +208 -106
  7. package/dist/chunk-SECDI3TL.js +312 -0
  8. package/dist/{chunk-ZEAAWBF2.js → chunk-WJ2YMM2E.js} +2877 -290
  9. package/dist/cli/codex-plugin-install.d.ts +16 -2
  10. package/dist/cli/index.js +188 -15
  11. package/dist/cli/install-completion.d.ts +13 -0
  12. package/dist/cli/install-ledger.d.ts +1 -1
  13. package/dist/cli/install.d.ts +11 -1
  14. package/dist/cli/operations/pi.d.ts +43 -0
  15. package/dist/cli/owned-skills.d.ts +17 -0
  16. package/dist/cli/pi-effort.d.ts +10 -0
  17. package/dist/cli/pi-install.d.ts +131 -0
  18. package/dist/cli/pi-migration.d.ts +12 -0
  19. package/dist/cli/pi-native-probe.d.ts +34 -0
  20. package/dist/cli/pi-package-receipt.d.ts +59 -0
  21. package/dist/cli/pi-paths.d.ts +20 -0
  22. package/dist/cli/pi-resources.d.ts +15 -0
  23. package/dist/cli/skills.d.ts +1 -1
  24. package/dist/cli/tui/index.js +12 -4
  25. package/dist/cli/tui/operations.d.ts +1 -0
  26. package/dist/cli/types.d.ts +4 -2
  27. package/dist/harness/adapters/pi.d.ts +8 -0
  28. package/dist/harness/core/agent-pack.d.ts +26 -6
  29. package/dist/harness/core/sdd.d.ts +27 -15
  30. package/dist/harness/pi-specialists.d.ts +6 -0
  31. package/dist/harness/types.d.ts +2 -2
  32. package/dist/harness/writers/codex-plugin-package.d.ts +1 -0
  33. package/dist/harness/writers/pi-agent.d.ts +16 -0
  34. package/dist/index.js +6 -4
  35. package/dist/pi.d.ts +11 -0
  36. package/dist/pi.js +46 -0
  37. package/package.json +17 -6
  38. package/pi/.thoth-agents-assets.json +12 -0
  39. package/pi/agents/thoth-deep.md +81 -0
  40. package/pi/agents/thoth-designer.md +81 -0
  41. package/pi/agents/thoth-explorer.md +81 -0
  42. package/pi/agents/thoth-librarian.md +83 -0
  43. package/pi/agents/thoth-oracle.md +83 -0
  44. package/pi/agents/thoth-quick.md +81 -0
  45. package/plugin/.claude-plugin/.thoth-agents-plugin-assets.json +2 -2
  46. package/plugin/.claude-plugin/plugin.json +1 -1
  47. package/plugin/.codex-plugin/plugin.json +1 -1
  48. package/plugin/agents/oracle.md +3 -3
  49. package/plugin/agents/orchestrator.md +35 -30
  50. package/plugin/skills/plan-reviewer/SKILL.md +54 -15
  51. package/plugin/skills/thoth-archive/SKILL.md +5 -0
  52. package/plugin/skills/thoth-constitution/SKILL.md +5 -0
  53. package/plugin/skills/thoth-constitution/templates/constitution.md +19 -2
  54. package/plugin/skills/thoth-init/SKILL.md +5 -0
  55. package/plugin/skills/thoth-sdd/SKILL.md +35 -10
  56. package/plugin/skills/thoth-sdd/references/phases/implement.md +13 -2
  57. package/plugin/skills/thoth-sdd/references/phases/tasks.md +23 -2
  58. package/plugin/skills/thoth-sdd/references/phases/verify.md +7 -5
  59. package/plugin/skills/thoth-sdd/scripts/validate.mjs +263 -30
  60. package/plugin/skills/thoth-sdd/templates/tasks.md +18 -2
  61. package/skills/README.md +2 -1
  62. package/skills/plan-reviewer/SKILL.md +54 -15
  63. package/skills/thoth-archive/SKILL.md +5 -0
  64. package/skills/thoth-constitution/SKILL.md +5 -0
  65. package/skills/thoth-constitution/templates/constitution.md +19 -2
  66. package/skills/thoth-init/SKILL.md +5 -0
  67. package/skills/thoth-sdd/SKILL.md +35 -10
  68. package/skills/thoth-sdd/references/phases/implement.md +13 -2
  69. package/skills/thoth-sdd/references/phases/tasks.md +23 -2
  70. package/skills/thoth-sdd/references/phases/verify.md +7 -5
  71. package/skills/thoth-sdd/scripts/validate.mjs +263 -30
  72. package/skills/thoth-sdd/templates/tasks.md +18 -2
  73. package/.agents/plugins/marketplace.json +0 -20
  74. package/.claude-plugin/marketplace.json +0 -21
@@ -0,0 +1,131 @@
1
+ import { type PiPackageReceipt, type PiPackageReceiptOptions } from './pi-package-receipt';
2
+ import { type PiPathOptions, type PiPaths } from './pi-paths';
3
+ export declare const PI_MINIMUM_VERSION = "0.84.4";
4
+ export declare const PI_NODE_MINIMUM = "22.19.0";
5
+ export declare const PI_COMMAND_TIMEOUT_MS = 120000;
6
+ export declare const PI_PACKAGE_SPECS: readonly [{
7
+ readonly id: "delegation";
8
+ readonly source: "npm:pi-subagents-j0k3r@1.5.9";
9
+ readonly packageName: "pi-subagents-j0k3r";
10
+ readonly version: "1.5.9";
11
+ }, {
12
+ readonly id: "context7";
13
+ readonly source: "npm:@upstash/context7-pi@0.1.2";
14
+ readonly packageName: "@upstash/context7-pi";
15
+ readonly version: "0.1.2";
16
+ }, {
17
+ readonly id: "web-access";
18
+ readonly source: "npm:pi-web-access@0.27.0";
19
+ readonly packageName: "pi-web-access";
20
+ readonly version: "0.27.0";
21
+ }, {
22
+ readonly id: "grep-adapter";
23
+ readonly source: "npm:pi-mcp-adapter@2.32.1";
24
+ readonly packageName: "pi-mcp-adapter";
25
+ readonly version: "2.32.1";
26
+ }, {
27
+ readonly id: "ask-user-question";
28
+ readonly source: "npm:@juicesharp/rpiv-ask-user-question@2.9.0";
29
+ readonly packageName: "@juicesharp/rpiv-ask-user-question";
30
+ readonly version: "2.9.0";
31
+ }, {
32
+ readonly id: "todo";
33
+ readonly source: "npm:@juicesharp/rpiv-todo@2.9.0";
34
+ readonly packageName: "@juicesharp/rpiv-todo";
35
+ readonly version: "2.9.0";
36
+ }];
37
+ export declare const PI_GREP_MCP_ENTRY: {
38
+ readonly url: "https://mcp.grep.app";
39
+ readonly protocolVersion: "legacy";
40
+ readonly lifecycle: "lazy";
41
+ };
42
+ export interface PiCommandResult {
43
+ exitCode: number | null;
44
+ stdout: string;
45
+ stderr: string;
46
+ error?: unknown;
47
+ }
48
+ export type PiCommandExecutor = (command: string, args: readonly string[]) => PiCommandResult;
49
+ export interface PiSetupOptions extends PiPathOptions {
50
+ dryRun?: boolean;
51
+ commandExecutor?: PiCommandExecutor;
52
+ expectedVersion?: string;
53
+ packageRoot?: string;
54
+ firstPartySource?: string;
55
+ receiptOptions?: PiPackageReceiptOptions;
56
+ verifyFirstParty?: (input: {
57
+ source: string;
58
+ installSource: string;
59
+ version: string;
60
+ packageRoot: string;
61
+ }) => {
62
+ success: true;
63
+ receipt: PiPackageReceipt;
64
+ } | {
65
+ success: false;
66
+ error: string;
67
+ };
68
+ }
69
+ export interface PiSetupPlanItem {
70
+ kind: 'preflight' | 'package' | 'root' | 'agent' | 'mcp';
71
+ description: string;
72
+ target: string;
73
+ command?: {
74
+ command: string;
75
+ args: string[];
76
+ };
77
+ content?: string;
78
+ }
79
+ export interface PiSetupPlan {
80
+ dryRun: boolean;
81
+ ready: boolean;
82
+ paths: PiPaths;
83
+ items: PiSetupPlanItem[];
84
+ blockers: string[];
85
+ diagnostics: string[];
86
+ disclaimers: string[];
87
+ options: PiSetupOptions;
88
+ }
89
+ export interface PiApplyResult {
90
+ success: boolean;
91
+ changed: string[];
92
+ diagnostics: string[];
93
+ error?: string;
94
+ failedStep?: string;
95
+ installedPackages: string[];
96
+ receiptCommitted?: boolean;
97
+ rollbackFailed?: boolean;
98
+ manualRecovery?: string;
99
+ configuredPackageRoot?: string;
100
+ }
101
+ export declare function getPiFirstPartySource(version: string): string;
102
+ export declare function verifyPiFirstPartyPackage(input: {
103
+ source: string;
104
+ installSource: string;
105
+ version: string;
106
+ packageRoot: string;
107
+ }): {
108
+ success: true;
109
+ receipt: PiPackageReceipt;
110
+ } | {
111
+ success: false;
112
+ error: string;
113
+ };
114
+ export declare function mergePiGrepMcpConfig(current: Record<string, unknown>): Record<string, unknown>;
115
+ export declare function mergePiRootBlock(current: string, managedBlock: string): string;
116
+ export declare function buildPiSetupPlan(options?: PiSetupOptions): PiSetupPlan;
117
+ export declare function formatPiSetupPlan(plan: PiSetupPlan): string;
118
+ export declare function isVersionAtLeast(actual: string, expected: string): boolean;
119
+ export declare function hasExactInstalledPiPackage(output: string, source: string): boolean;
120
+ export interface PiConfiguredPackage {
121
+ scope: 'user' | 'project';
122
+ source: string;
123
+ installedPath?: string;
124
+ packageName?: string;
125
+ packageVersion?: string;
126
+ }
127
+ export declare function parsePiPackageList(output: string): PiConfiguredPackage[];
128
+ export declare function isThothPackageLocation(candidate: PiConfiguredPackage, knownSource?: string): boolean;
129
+ export declare function getPiFirstPartyPackages(packages: readonly PiConfiguredPackage[], knownSource?: string): PiConfiguredPackage[];
130
+ export declare function writePiManagedText(path: string, content: string): boolean;
131
+ export declare function applyPiSetup(plan: PiSetupPlan): PiApplyResult;
@@ -0,0 +1,12 @@
1
+ export interface PiLegacyMigrationOptions {
2
+ packageRoot: string;
3
+ piRoot: string;
4
+ dryRun?: boolean;
5
+ }
6
+ export interface PiLegacyMigrationResult {
7
+ success: boolean;
8
+ changed: string[];
9
+ manualActions: string[];
10
+ error?: string;
11
+ }
12
+ export declare function migrateLegacyPiResources(options: PiLegacyMigrationOptions): PiLegacyMigrationResult;
@@ -0,0 +1,34 @@
1
+ export type PiNativeObservationState = 'observed-at-install' | 'unobserved' | 'unavailable';
2
+ export interface PiNativeProbeCommandResult {
3
+ exitCode: number | null;
4
+ stdout: string;
5
+ stderr: string;
6
+ error?: unknown;
7
+ }
8
+ export type PiNativeProbeExecutor = (command: string, args: readonly string[], env: Readonly<Record<string, string | undefined>>) => PiNativeProbeCommandResult;
9
+ export interface PiNativeProbeOptions {
10
+ extensionPath: string;
11
+ packageRoot?: string;
12
+ piHome?: string;
13
+ manifestSha256: string;
14
+ extensionSha256: string;
15
+ commandExecutor?: PiNativeProbeExecutor;
16
+ piCommand?: string;
17
+ probePrompt?: string;
18
+ }
19
+ export interface PiNativeProbeResult {
20
+ state: PiNativeObservationState;
21
+ basis: string[];
22
+ command: {
23
+ command: string;
24
+ args: string[];
25
+ };
26
+ discoveredSkills?: Array<{
27
+ name: string;
28
+ location: string;
29
+ }>;
30
+ materializedSpecialists?: string[];
31
+ orchestratorChild?: boolean;
32
+ sessionStartCount?: number;
33
+ }
34
+ export declare function observePiNativeRoot(options: PiNativeProbeOptions): PiNativeProbeResult;
@@ -0,0 +1,59 @@
1
+ export declare const PI_PACKAGE_RECEIPT_SCHEMA_VERSION: 1;
2
+ export interface PiPackageReceipt {
3
+ schemaVersion: typeof PI_PACKAGE_RECEIPT_SCHEMA_VERSION;
4
+ owner: 'thoth-agents';
5
+ scope: 'user';
6
+ packageName: 'thoth-agents';
7
+ source: string;
8
+ installSource: string;
9
+ version: string;
10
+ manifestSha256: string;
11
+ extensionSha256: string;
12
+ }
13
+ export interface PiPackageReceiptOptions {
14
+ configRoot?: string;
15
+ homeDir?: string;
16
+ env?: Readonly<Record<string, string | undefined>>;
17
+ }
18
+ export type PiPackageReceiptReadResult = {
19
+ status: 'missing';
20
+ path: string;
21
+ } | {
22
+ status: 'invalid';
23
+ path: string;
24
+ error: string;
25
+ } | {
26
+ status: 'valid';
27
+ path: string;
28
+ receipt: PiPackageReceipt;
29
+ };
30
+ export type PiPackageOwnershipState = 'missing' | 'configured-unowned' | 'owned-missing' | 'owned-current' | 'conflicting';
31
+ export declare function piPackagePathsEqual(left: string, right: string): boolean;
32
+ export declare function getPiPackageReceiptPath(options?: PiPackageReceiptOptions): string;
33
+ export declare function readPiPackageReceipt(options?: PiPackageReceiptOptions): PiPackageReceiptReadResult;
34
+ export declare function writePiPackageReceipt(receipt: PiPackageReceipt, options?: PiPackageReceiptOptions): {
35
+ success: true;
36
+ path: string;
37
+ } | {
38
+ success: false;
39
+ path: string;
40
+ error: string;
41
+ };
42
+ export declare function classifyPiPackageOwnership(input: {
43
+ receipt: PiPackageReceiptReadResult;
44
+ globalPackages: readonly {
45
+ source: string;
46
+ installedPath?: string;
47
+ packageName?: string;
48
+ packageVersion?: string;
49
+ }[];
50
+ projectPackages: readonly {
51
+ source: string;
52
+ installedPath?: string;
53
+ packageName?: string;
54
+ packageVersion?: string;
55
+ }[];
56
+ }): {
57
+ state: PiPackageOwnershipState;
58
+ reason?: string;
59
+ };
@@ -0,0 +1,20 @@
1
+ export interface PiPathOptions {
2
+ homeDir?: string;
3
+ cwd?: string;
4
+ env?: Readonly<Record<string, string | undefined>>;
5
+ }
6
+ export interface PiPaths {
7
+ homeDir: string;
8
+ piRoot: string;
9
+ defaultPiRoot: string;
10
+ customPiRoot: boolean;
11
+ skillsDestinationCompatible: boolean;
12
+ appendSystemPath: string;
13
+ agentsRoot: string;
14
+ alternateAgentsRoot: string;
15
+ ownedSkillsRoot: string;
16
+ mcpConfigPath: string;
17
+ projectAgentRoots: string[];
18
+ projectMcpPaths: string[];
19
+ }
20
+ export declare function resolvePiPaths(options?: PiPathOptions): PiPaths;
@@ -0,0 +1,15 @@
1
+ export declare const PI_SPECIALIST_NAMES: ("thoth-explorer" | "thoth-librarian" | "thoth-oracle" | "thoth-designer" | "thoth-quick" | "thoth-deep")[];
2
+ export interface PiSpecialistSyncOptions {
3
+ packageRoot: string;
4
+ piRoot: string;
5
+ dryRun?: boolean;
6
+ projectRoots?: readonly string[];
7
+ }
8
+ export interface PiSpecialistSyncResult {
9
+ success: boolean;
10
+ changed: string[];
11
+ conflicts: string[];
12
+ diagnostics: string[];
13
+ error?: string;
14
+ }
15
+ export declare function syncPiSpecialists(options: PiSpecialistSyncOptions): PiSpecialistSyncResult;
@@ -1,5 +1,5 @@
1
1
  import { type NpxCommand, type NpxCommandOptions } from './npx-command';
2
- export type SkillInstallHarness = 'opencode' | 'codex' | 'claude';
2
+ export type SkillInstallHarness = 'opencode' | 'codex' | 'claude' | 'pi';
3
3
  /** An external skill required by every supported thoth-agents harness. */
4
4
  export interface RequiredSkill {
5
5
  name: string;
@@ -2,8 +2,10 @@ import {
2
2
  defaultTuiOperations,
3
3
  effortChoicesForModel,
4
4
  listOperationHarnesses
5
- } from "../../chunk-ZEAAWBF2.js";
6
- import "../../chunk-GIUU6FNE.js";
5
+ } from "../../chunk-WJ2YMM2E.js";
6
+ import "../../chunk-62L3ORXN.js";
7
+ import "../../chunk-SECDI3TL.js";
8
+ import "../../chunk-Q6SDM4KP.js";
7
9
 
8
10
  // src/cli/tui/index.tsx
9
11
  import { render } from "ink";
@@ -190,7 +192,7 @@ function ModelScreen({
190
192
  actions
191
193
  }) {
192
194
  return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
193
- /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: harness === "codex" ? "Codex writes generated subagent model lines only." : harness === "claude" ? "Claude Code writes subagent frontmatter model lines (sonnet, opus, haiku, inherit)." : "OpenCode writes role model overrides in thoth-agents config." }),
195
+ /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: harness === "codex" ? "Codex writes generated subagent model lines only." : harness === "claude" ? "Claude Code writes subagent frontmatter model lines (sonnet, opus, haiku, inherit)." : harness === "pi" ? "Pi writes model and effort only in thoth-agents-owned specialist frontmatter; the ambient root model remains Pi-owned." : "OpenCode writes role model overrides in thoth-agents config." }),
194
196
  harness === "codex" ? CODEX_MODEL_CATALOG_NOTE.map((note) => /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: note }, note)) : null,
195
197
  roles.map((role, index) => /* @__PURE__ */ jsxs4(
196
198
  Text4,
@@ -792,6 +794,12 @@ function buildHarnessItems() {
792
794
  { id: "back", action: "back", label: "Back", detail: "Return" }
793
795
  ];
794
796
  }
797
+ function harnessDisplayName(harness) {
798
+ if (harness === "codex") return "Codex";
799
+ if (harness === "claude") return "Claude Code";
800
+ if (harness === "pi") return "Pi";
801
+ return "OpenCode";
802
+ }
795
803
  function moveSelection(current, direction, items) {
796
804
  let next = current;
797
805
  for (let index = 0; index < items.length; index += 1) {
@@ -1361,7 +1369,7 @@ function App({
1361
1369
  /* @__PURE__ */ jsx8(
1362
1370
  Header,
1363
1371
  {
1364
- title: `${modelHarness === "codex" ? "Codex" : modelHarness === "claude" ? "Claude Code" : "OpenCode"} Models`,
1372
+ title: `${harnessDisplayName(modelHarness)} Models`,
1365
1373
  subtitle: "Enter edits a role. Dirty rows are marked with *."
1366
1374
  }
1367
1375
  ),
@@ -17,5 +17,6 @@ export declare const opencodeModelRoles: ModelRoleInput[];
17
17
  export declare const codexModelRoles: ModelRoleInput[];
18
18
  export declare function getCodexModelRoles(source?: CodexOperationContext): ModelRoleInput[];
19
19
  export declare function getClaudeCodeModelRoles(_source?: ClaudeCodeOperationContext): ModelRoleInput[];
20
+ export declare function getPiModelRoles(): ModelRoleInput[];
20
21
  export declare function getOpenCodeModelRoles(): ModelRoleInput[];
21
22
  export declare const defaultTuiOperations: TuiOperations;
@@ -1,8 +1,9 @@
1
1
  export type BooleanArg = 'yes' | 'no';
2
- export type InstallAgent = 'opencode' | 'codex' | 'claude';
2
+ export type InstallAgent = 'opencode' | 'codex' | 'claude' | 'pi';
3
3
  export interface InstallArgs {
4
4
  tui: boolean;
5
5
  agent?: InstallAgent;
6
+ localPackageRoot?: string;
6
7
  tmux?: BooleanArg;
7
8
  dryRun?: boolean;
8
9
  reset?: boolean;
@@ -12,7 +13,7 @@ export interface GenerateArgs {
12
13
  dryRun?: boolean;
13
14
  outputRoot?: string;
14
15
  }
15
- export type OperationHarnessArg = 'opencode' | 'codex' | 'claude';
16
+ export type OperationHarnessArg = 'opencode' | 'codex' | 'claude' | 'pi';
16
17
  export interface CliModelRoleArg {
17
18
  role: string;
18
19
  model?: string;
@@ -53,6 +54,7 @@ export interface OpenCodeConfig {
53
54
  export interface InstallConfig {
54
55
  agent: InstallAgent;
55
56
  hasTmux: boolean;
57
+ localPackageRoot?: string;
56
58
  dryRun?: boolean;
57
59
  reset: boolean;
58
60
  }
@@ -0,0 +1,8 @@
1
+ import { type PluginConfig } from '../../config';
2
+ import type { HarnessAdapter, HarnessCapabilities, HarnessRenderContext } from '../types';
3
+ export interface PiRenderContext extends HarnessRenderContext {
4
+ config?: PluginConfig;
5
+ }
6
+ export declare const PI_CAPABILITIES: HarnessCapabilities;
7
+ export declare function renderPiRootInstructions(config?: PluginConfig): string;
8
+ export declare const piAdapter: HarnessAdapter;
@@ -19,8 +19,28 @@ export interface OrchestrationPolicy {
19
19
  maxDelegationDepth: number;
20
20
  singleWriter: boolean;
21
21
  implementationOwnership: ImplementationOwnershipPolicy;
22
+ taskShaping: TaskShapingPolicy;
23
+ specialistDirectory: SpecialistDecision[];
22
24
  rules: string[];
23
25
  }
26
+ export type TaskShapingStep = 'bound-work' | 'map-dependencies' | 'assign-ownership' | 'select-specialists' | 'mark-ready-and-blocked' | 'dispatch-ready-wave' | 'wait-for-terminal-evidence' | 'reconcile-and-verify';
27
+ export interface TaskShapingPolicy {
28
+ steps: TaskShapingStep[];
29
+ nativeAuthority: boolean;
30
+ boundedWidth: boolean;
31
+ decisions: {
32
+ dependency: string;
33
+ ownershipConflict: string;
34
+ readyWave: string;
35
+ terminalEvidence: string;
36
+ degradation: string;
37
+ };
38
+ }
39
+ export interface SpecialistDecision {
40
+ role: Exclude<AgentRoleName, 'orchestrator'>;
41
+ selectWhen: string;
42
+ rejectWhen: string;
43
+ }
24
44
  export type ImplementationOwner = 'orchestrator' | 'designer' | 'quick' | 'deep';
25
45
  export interface ImplementationOwnershipPolicy {
26
46
  eligibleOwners: ImplementationOwner[];
@@ -43,12 +63,12 @@ export declare const AGENT_ROLES: readonly [{
43
63
  readonly dispatch: "root-coordinator";
44
64
  readonly canMutateWorkspace: true;
45
65
  readonly scope: "requirements, SDD coordination, routing, bounded implementation, decisions, and synthesis";
46
- readonly responsibility: "Keep requirements, decisions, sequential SDD coordination, and final synthesis in the root thread; evaluate implementation ownership independently in every route and implement directly or delegate according to explicit user direction and demonstrated net gain.";
66
+ readonly responsibility: "Keep requirements, decisions, sequential SDD coordination, and final synthesis in the root thread; evaluate implementation ownership independently in every route, implement directly or delegate by demonstrated net gain, and run focused verification for trivial deterministic Direct work.";
47
67
  readonly useWhen: ["Coordinate requirements, governed artifacts, routing, and synthesis.", "Implement an accepted mutable surface in any route when accumulated context and continuity outweigh delegation overhead."];
48
- readonly doNotUseWhen: ["Not for independent plan review or final verification."];
68
+ readonly doNotUseWhen: ["Not for independent plan review or Oracle-required final verification."];
49
69
  readonly escalateWhen: ["Delegate implementation when specialization, context isolation, or independent bounded work creates a demonstrated net gain; then select designer, quick, or deep by task shape."];
50
- readonly toolGovernance: ["may inspect and edit the accepted bounded implementation surface in every route, but every verification is delegated to oracle", "loads the matching thoth-sdd phase contract on demand instead of carrying every phase protocol in its prompt", "owns governed coordination writes under openspec/ and uses append-only tasks.md updates during convergence", "delegates independent or specialist work only when it produces a net gain", "keeps requirements, decisions, and final synthesis in the root thread"];
51
- readonly verification: ["delegates selected plan-review and every verify phase to oracle; plan review stays optional and final verification stays mandatory", "consolidates summarized evidence returned by child agents"];
70
+ readonly toolGovernance: ["may inspect and edit the accepted bounded implementation surface in every route and may verify trivial deterministic Direct work without self-approval", "loads the matching thoth-sdd phase contract on demand instead of carrying every phase protocol in its prompt", "owns governed coordination writes under openspec/ and uses append-only tasks.md updates during convergence", "delegates independent or specialist work only when it produces a net gain", "keeps requirements, decisions, and final synthesis in the root thread"];
71
+ readonly verification: ["runs focused checks for trivial deterministic Direct work while final verification remains mandatory", "delegates selected plan review plus Accelerated, Full, and material-risk Direct final verification to a fresh oracle", "consolidates summarized evidence returned by child agents"];
52
72
  }, {
53
73
  readonly name: "explorer";
54
74
  readonly mode: "read-only";
@@ -79,8 +99,8 @@ export declare const AGENT_ROLES: readonly [{
79
99
  readonly dispatch: "synchronous-task-only";
80
100
  readonly canMutateWorkspace: false;
81
101
  readonly scope: "diagnosis, architecture, optional plan review, and independent verification";
82
- readonly responsibility: "Independently review plans when the user requests it and perform every implementation verification, exposing correctness risks and judging whether results satisfy their contracts.";
83
- readonly useWhen: ["Selected plan review, diagnosis, or final verification needs independent judgment."];
102
+ readonly responsibility: "Independently review plans when the user requests it and provide independent judgment for artifact-backed or material-risk final verification, exposing correctness risks and judging whether results satisfy their contracts.";
103
+ readonly useWhen: ["Selected plan review, persistent diagnosis, material architecture or security risk, contradictory evidence, high failure cost, or artifact-backed final verification needs independent judgment."];
84
104
  readonly doNotUseWhen: ["Not for implementation, mutation, persistence, or self-review."];
85
105
  readonly escalateWhen: ["Return blockers and remediation anchors to root."];
86
106
  readonly toolGovernance: ["performs read-only analysis and independent review and is never the implementer of the work it judges", "does not implement, persist artifacts, or delegate further"];
@@ -5,6 +5,14 @@ export type SddIntent = 'documentation' | 'mechanical' | 'behavior' | 'architect
5
5
  export type SddScope = 'local' | 'multi-file' | 'cross-cutting';
6
6
  export type SddClarity = 'clear' | 'partial' | 'uncertain';
7
7
  export type SddRisk = 'low' | 'medium' | 'high';
8
+ export type SddFinalVerificationRisk = 'trivial-deterministic' | 'architecture' | 'security' | 'cross-cutting-regression' | 'persistent-diagnosis' | 'contradictory-evidence' | 'high-failure-cost' | 'material-uncertainty';
9
+ export type SddFinalVerificationOwner = 'orchestrator' | 'oracle';
10
+ export interface SddFinalVerificationDecision {
11
+ verificationRequired: true;
12
+ owner: SddFinalVerificationOwner;
13
+ oracleRequired: boolean;
14
+ freshOracleRequired: boolean;
15
+ }
8
16
  export type SddPlanningMode = 'none' | 'fast-forward' | 'gated';
9
17
  export type SddValidationGate = 'specify' | 'plan' | 'tasks' | 'checklist' | 'ready' | 'closeout';
10
18
  export type SddArtifactRevisionPolicy = 'none' | 'revalidate-affected-downstream';
@@ -24,7 +32,7 @@ export interface SddRoutingDecision {
24
32
  }
25
33
  export type SddPhaseId = 'explore' | 'specify' | 'clarify' | 'plan' | 'checklist' | 'tasks' | 'plan-review' | 'implement' | 'verify' | 'converge' | 'archive';
26
34
  export type SddPhaseActivation = 'required' | 'conditional';
27
- export type SddPhaseOwner = AgentRoleName | 'adaptive-implementation';
35
+ export type SddPhaseOwner = AgentRoleName | 'adaptive-implementation' | 'adaptive-verification';
28
36
  export interface SddPhaseContract {
29
37
  id: SddPhaseId;
30
38
  order: number;
@@ -161,8 +169,8 @@ export declare const SDD_PHASES: readonly [{
161
169
  readonly producesArtifact: true;
162
170
  readonly defaultAgentRole: "oracle";
163
171
  readonly eligibleAgentRoles: ["oracle"];
164
- readonly reason: "Offer independent blocker-only plan review when the user selects it after planning passes ready.";
165
- readonly condition: "Activate only after ready when the user chooses Review plan with Oracle (Recommended).";
172
+ readonly reason: "Offer independent blocker-only plan review after explicit or bounded recommended-default selection once planning passes ready.";
173
+ readonly condition: "Activate after ready when review is selected explicitly or by the bounded recommended default after three answerless attempts.";
166
174
  }, {
167
175
  readonly id: "implement";
168
176
  readonly order: 7;
@@ -182,9 +190,9 @@ export declare const SDD_PHASES: readonly [{
182
190
  readonly activation: "required";
183
191
  readonly prerequisites: ["implement"];
184
192
  readonly producesArtifact: true;
185
- readonly defaultAgentRole: "oracle";
186
- readonly eligibleAgentRoles: ["oracle"];
187
- readonly reason: "Independently judge the result against requirements, contracts, and focused checks.";
193
+ readonly defaultAgentRole: "adaptive-verification";
194
+ readonly eligibleAgentRoles: ["orchestrator", "oracle"];
195
+ readonly reason: "Keep verification mandatory while selecting root for trivial deterministic Direct checks and a fresh Oracle for material-risk Direct or artifact-backed judgment.";
188
196
  }, {
189
197
  readonly id: "converge";
190
198
  readonly order: 9;
@@ -357,17 +365,17 @@ export declare const SDD_PHASE_PROTOCOLS: readonly [{
357
365
  readonly outputSchema: ["tasks.md path", "requirement coverage", "dependency order"];
358
366
  readonly doneWhen: ["Every FR and buildable SC has executable task coverage and every task has a verification step."];
359
367
  readonly blockingConditions: ["A task requires an unresolved requirement, architecture choice, or hidden prerequisite."];
360
- readonly handoff: ["After ready, pass spec.md, plan.md, tasks.md, dependencies, and verification commands to the user-selected plan-review path or implement."];
368
+ readonly handoff: ["After ready, pass spec.md, plan.md, tasks.md, dependencies, and verification commands to the explicitly or bounded-default selected plan-review path, or implement when the user explicitly proceeds without review."];
361
369
  }, {
362
370
  readonly id: "plan-review";
363
- readonly objective: "Perform the user-selected read-only blocker review before Accelerated or Full implementation.";
364
- readonly requiredInputs: ["spec.md", "plan.md", "tasks.md", "Optional active requirements checklist", "Project constitution", "Explicit user choice to review after the ready gate"];
365
- readonly instructions: ["Load the bundled plan-reviewer skill and review executability, completeness, correctness, and coherence without redesigning the plan.", "Require task coverage for every FR and buildable SC; assess outcome SC as measurable verification targets without manufacturing implementation tasks.", "Return exact [OKAY] or [REJECT] semantics, default to [OKAY], and report at most three true blockers with the smallest fixes.", "Provide the reviewed artifact set so root can persist plan-review.md with SHA-256 freshness evidence; Oracle never writes it.", "Keep plan-review approval separate from implementation confirmation and mandatory final verify."];
371
+ readonly objective: "Perform the explicitly or recommended-default selected read-only blocker review before Accelerated or Full implementation.";
372
+ readonly requiredInputs: ["spec.md", "plan.md", "tasks.md", "Optional active requirements checklist", "Project constitution", "Review selection after the ready gate, from an explicit answer or the bounded recommended fallback"];
373
+ readonly instructions: ["At the ready gate, make at most three total attempts when the native review question returns answerless; after the third answerless result, treat Review plan with Oracle (Recommended) as selected, while any explicit Proceed without review answer wins.", "Load the bundled plan-reviewer skill and review executability, completeness, correctness, and coherence without redesigning the plan.", "Require task coverage for every FR and buildable SC; assess outcome SC as measurable verification targets without manufacturing implementation tasks.", "For every declared parallel group, independently assess semantic independence, each lane path union and owner, real cross-lane data flow, prerequisites and barrier, and whether native capacity supports dispatch-before-wait waves with refill; require a truthful sequential fallback when concurrency is unavailable or unproven.", "Return exact [OKAY] or [REJECT] semantics, default to [OKAY], and report at most three true blockers with the smallest fixes.", "After [REJECT], root must repair actionable same-intent planning artifacts, revalidate affected gates, and start a fresh Oracle approval round until [OKAY]; stop instead on a material human-owned blocker.", "Provide the reviewed artifact set so root can persist plan-review.md with SHA-256 freshness evidence; Oracle never writes it.", "Keep plan-review approval separate from implementation confirmation and mandatory final verify."];
366
374
  readonly allowedWrites: ["None; Oracle is read-only. Root persists plan-review.md when review runs."];
367
- readonly outputSchema: ["status: [OKAY] or [REJECT]", "zero to three blocker findings with smallest fixes", "non-blocking cautions", "requirement coverage percentage", "constitution alignment", "reviewed artifact freshness manifest input"];
375
+ readonly outputSchema: ["status: [OKAY] or [REJECT]", "zero to three blocker findings with smallest fixes", "non-blocking cautions", "requirement coverage percentage", "parallel executability disposition when tasks declare groups or an evidence-backed None reason", "constitution alignment", "reviewed artifact freshness manifest input"];
368
376
  readonly doneWhen: ["Oracle has returned an exact status and every true blocker has a concrete remediation anchor."];
369
377
  readonly blockingConditions: ["[REJECT] blocks the review path until root repairs planning blockers, the user explicitly proceeds without review, or an explicit override is recorded."];
370
- readonly handoff: ["On [OKAY], root persists review evidence, presents the approved-plan overview, and asks whether to implement or stop.", "A plan-review result never satisfies mandatory final verify."];
378
+ readonly handoff: ["On [OKAY], root persists review evidence and summarizes the approved scope, approach, ownership, verification, and material risks before asking Implement (Recommended) or Stop.", "For an answerless implementation question, root makes at most three total attempts; after the third answerless result, implementation counts as selected, while any explicit Stop answer wins.", "[OKAY] alone does not authorize implementation before that explicit choice or bounded fallback resolves.", "A plan-review result never satisfies mandatory final verify."];
371
379
  }, {
372
380
  readonly id: "implement";
373
381
  readonly objective: "Execute the accepted task slice with one writer and focused verification.";
@@ -377,12 +385,12 @@ export declare const SDD_PHASE_PROTOCOLS: readonly [{
377
385
  readonly outputSchema: ["status: completed | partial | failed", "per-task outcome", "files changed", "executed verification and results", "deviations, issues, and remaining work"];
378
386
  readonly doneWhen: ["The assigned task slice is complete and its focused checks pass with concrete evidence."];
379
387
  readonly blockingConditions: ["A task needs scope expansion, a material unresolved decision, or fails repeatedly without a safe bounded recovery."];
380
- readonly handoff: ["Pass changed files, per-task evidence, deviations, and verification results to a fresh Oracle for independent verify."];
388
+ readonly handoff: ["Pass changed files, per-task evidence, deviations, and verification results into the route- and risk-aware final-verification decision."];
381
389
  }, {
382
390
  readonly id: "verify";
383
391
  readonly objective: "Judge the implementation against accepted requirements using executed evidence.";
384
392
  readonly requiredInputs: ["Implemented change or task results", "spec.md, plan.md, and tasks.md for artifact-backed routes", "Changed files and project verification commands"];
385
- readonly instructions: ["Oracle must be independent from the implementation writer; self-review never satisfies this phase.", "Run or inspect the smallest sufficient executed checks; static confidence alone is not evidence.", "Judge completeness, correctness, and coherence independently so a passing test cannot hide missing or contradictory scope.", "Build a compliance matrix from every accepted requirement to code and executed checks.", "Record every outcome SC as PASS with concrete observed evidence or RISK with an explicit residual-risk entry.", "For accelerated and full routes, the root persists the read-only oracle result as verify-report.md."];
393
+ readonly instructions: ["Trivial deterministic Direct work may use root-owned focused verification; materially risky Direct plus Accelerated and Full final verification use a fresh independent Oracle, and no implementation writer self-approves.", "Run or inspect the smallest sufficient executed checks; static confidence alone is not evidence.", "Judge completeness, correctness, and coherence independently so a passing test cannot hide missing or contradictory scope.", "Build a compliance matrix from every accepted requirement to code and executed checks.", "Record every outcome SC as PASS with concrete observed evidence or RISK with an explicit residual-risk entry.", "For accelerated and full routes, the root persists the read-only oracle result as verify-report.md."];
386
394
  readonly allowedWrites: ["Root persistence only: openspec/changes/<feature>/verify-report.md for accelerated and full routes"];
387
395
  readonly outputSchema: ["verdict: pass | fail", "compliance matrix", "executed checks and results", "critical issues with remediation anchors", "warnings and residual risks"];
388
396
  readonly doneWhen: ["Every accepted requirement is represented in the compliance matrix and the verdict matches the evidence."];
@@ -419,7 +427,11 @@ export declare function getSddPhaseProtocol(id: SddPhaseId): SddPhaseProtocol;
419
427
  export declare function getSddPhaseProtocolsForRole(role: AgentRoleName): SddPhaseProtocol[];
420
428
  export declare function renderSddPhaseDispatchEnvelope(input: SddPhaseDispatchInput): string;
421
429
  export declare function renderSddPhaseDispatchTemplate(): string;
422
- export declare function getSddPhaseOwner(_route: SddRoute, phaseId: SddPhaseId): SddPhaseOwner;
430
+ export declare function getSddFinalVerificationDecision({ route, risk, }: {
431
+ route: SddRoute;
432
+ risk: SddFinalVerificationRisk;
433
+ }): SddFinalVerificationDecision;
434
+ export declare function getSddPhaseOwner(route: SddRoute, phaseId: SddPhaseId, verificationRisk?: SddFinalVerificationRisk): SddPhaseOwner;
423
435
  export declare function getRequiredSddPhaseOrder(route: SddRoute): SddPhaseId[];
424
436
  export declare function canEnterSddPhase({ route, completed, target, }: {
425
437
  route: SddRoute;
@@ -0,0 +1,6 @@
1
+ import type { AgentRoleName } from './core/agent-pack';
2
+ export type PiSpecialistRole = Exclude<AgentRoleName, 'orchestrator'>;
3
+ export type PiSpecialistName = `thoth-${PiSpecialistRole}`;
4
+ export declare const PI_SPECIALIST_ROLES: readonly PiSpecialistRole[];
5
+ export declare function isPiSpecialistRole(role: string): role is PiSpecialistRole;
6
+ export declare function piSpecialistName(role: PiSpecialistRole): PiSpecialistName;
@@ -1,8 +1,8 @@
1
- export type HarnessId = 'opencode' | 'codex' | 'claude';
1
+ export type HarnessId = 'opencode' | 'codex' | 'claude' | 'pi';
2
2
  export type HarnessArtifactKind = 'agent-config' | 'harness-config' | 'mcp-config' | 'skill' | 'hook-config' | 'manifest' | 'documentation';
3
3
  export type HarnessDiagnosticSeverity = 'info' | 'warning' | 'error';
4
4
  export type HarnessDiagnosticCode = 'harness.unsupported' | 'harness.capability_gap' | 'harness.surface_unvalidated' | 'harness.artifact_skipped' | (string & {});
5
- export type HarnessCapabilityStatus = 'supported' | 'unsupported' | 'instruction-only' | 'unknown';
5
+ export type HarnessCapabilityStatus = 'supported' | 'conditional' | 'adapter-backed' | 'provider-dependent' | 'degraded' | 'unsupported' | 'instruction-only' | 'unknown';
6
6
  export type ProviderCapabilityState = 'supported' | 'degraded' | 'unsupported';
7
7
  export type ProviderCapabilityEvidenceSource = 'provider' | 'harness' | 'none';
8
8
  /**
@@ -11,6 +11,7 @@ export interface CodexPluginPackageAsset {
11
11
  sourcePath?: string;
12
12
  }
13
13
  export interface CodexPluginHookDefinition extends CodexHookValidationInput {
14
+ matcher?: string;
14
15
  handler: CodexHookValidationInput['handler'] & {
15
16
  command?: unknown;
16
17
  };
@@ -0,0 +1,16 @@
1
+ import type { AgentRoleContract } from '../core/agent-pack';
2
+ import { type PiSpecialistRole } from '../pi-specialists';
3
+ export declare const PI_MANAGED_OWNER = "thoth-agents";
4
+ export declare const PI_ROOT_START = "<!-- thoth-agents:pi-root:start -->";
5
+ export declare const PI_ROOT_END = "<!-- thoth-agents:pi-root:end -->";
6
+ export interface PiAgentDefinitionInput {
7
+ role: AgentRoleContract & {
8
+ name: PiSpecialistRole;
9
+ };
10
+ description: string;
11
+ instructions: string;
12
+ model?: string;
13
+ effort?: string;
14
+ }
15
+ export declare function renderPiAgentDefinition(input: PiAgentDefinitionInput): string;
16
+ export declare function renderPiRootBlock(instructions: string): string;
package/dist/index.js CHANGED
@@ -3,16 +3,18 @@ import {
3
3
  renderOpenCodeAgentConfigs,
4
4
  spawn,
5
5
  spawnSync
6
- } from "./chunk-CB3EBA7H.js";
6
+ } from "./chunk-5EBXGMOK.js";
7
7
  import {
8
- POLL_INTERVAL_BACKGROUND_MS,
9
8
  context7,
10
9
  exa,
10
+ grep_app
11
+ } from "./chunk-62L3ORXN.js";
12
+ import {
13
+ POLL_INTERVAL_BACKGROUND_MS,
11
14
  getOpenCodeConfigPaths,
12
- grep_app,
13
15
  loadPluginConfig,
14
16
  stripJsonComments
15
- } from "./chunk-GIUU6FNE.js";
17
+ } from "./chunk-Q6SDM4KP.js";
16
18
 
17
19
  // src/index.ts
18
20
  import { fileURLToPath as fileURLToPath3 } from "url";
package/dist/pi.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ type PiHandler = (event: Record<string, unknown>, context?: unknown) => unknown;
2
+ export interface PiExtensionApi {
3
+ on(event: 'before_agent_start' | 'session_start', handler: PiHandler): void;
4
+ }
5
+ export interface PiExtensionOptions {
6
+ packageRoot?: string;
7
+ piRoot?: string;
8
+ }
9
+ export declare function injectPiRoot(systemPrompt: string): string;
10
+ export default function thothAgentsPiExtension(pi: PiExtensionApi, options?: PiExtensionOptions): void;
11
+ export {};