@open-agent-toolkit/cli 0.1.69 → 0.1.73

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 (79) hide show
  1. package/README.md +1 -0
  2. package/assets/docs/cli-utilities/configuration.md +34 -0
  3. package/assets/docs/cli-utilities/index.md +2 -1
  4. package/assets/docs/cli-utilities/project-log.md +183 -0
  5. package/assets/docs/cli-utilities/workflow-gates.md +126 -3
  6. package/assets/docs/reference/cli-reference.md +6 -1
  7. package/assets/docs/workflows/projects/dispatch-ceiling.md +14 -5
  8. package/assets/docs/workflows/projects/orchestration-model.md +21 -0
  9. package/assets/docs/workflows/projects/review-flavors.md +9 -0
  10. package/assets/public-package-versions.json +4 -4
  11. package/assets/skills/oat-dispatch-subagents/SKILL.md +21 -1
  12. package/assets/skills/oat-dispatch-subagents/references/provider-claude.md +21 -0
  13. package/assets/skills/oat-dispatch-subagents/references/provider-codex.md +16 -0
  14. package/assets/skills/oat-dispatch-subagents/references/provider-cursor.md +21 -0
  15. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +6 -2
  16. package/assets/skills/oat-project-complete/SKILL.md +60 -1
  17. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +6 -2
  18. package/assets/skills/oat-project-implement/SKILL.md +18 -2
  19. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +6 -2
  20. package/assets/skills/oat-project-plan-writing/SKILL.md +23 -33
  21. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +6 -2
  22. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +6 -2
  23. package/assets/skills/oat-project-review-provide/SKILL.md +62 -1
  24. package/assets/skills/oat-project-summary/SKILL.md +122 -18
  25. package/assets/templates/project-log.md +47 -0
  26. package/dist/commands/config/index.d.ts.map +1 -1
  27. package/dist/commands/config/index.js +106 -1
  28. package/dist/commands/gate/__fixtures__/fake-runtime.d.mts +3 -0
  29. package/dist/commands/gate/__fixtures__/fake-runtime.d.mts.map +1 -0
  30. package/dist/commands/gate/__fixtures__/fake-runtime.mjs +167 -0
  31. package/dist/commands/gate/activity-probes.d.ts +35 -0
  32. package/dist/commands/gate/activity-probes.d.ts.map +1 -0
  33. package/dist/commands/gate/activity-probes.js +135 -0
  34. package/dist/commands/gate/branch-local-cli.d.ts +31 -0
  35. package/dist/commands/gate/branch-local-cli.d.ts.map +1 -0
  36. package/dist/commands/gate/branch-local-cli.js +116 -0
  37. package/dist/commands/gate/index.d.ts +31 -0
  38. package/dist/commands/gate/index.d.ts.map +1 -1
  39. package/dist/commands/gate/index.js +533 -32
  40. package/dist/commands/gate/route.d.ts +22 -0
  41. package/dist/commands/gate/route.d.ts.map +1 -0
  42. package/dist/commands/gate/route.js +109 -0
  43. package/dist/commands/init/tools/shared/skill-manifest.d.ts +1 -1
  44. package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
  45. package/dist/commands/init/tools/shared/skill-manifest.js +1 -0
  46. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  47. package/dist/commands/project/dispatch-ceiling/index.js +100 -16
  48. package/dist/commands/project/index.d.ts.map +1 -1
  49. package/dist/commands/project/index.js +2 -0
  50. package/dist/commands/project/log/append.d.ts +41 -0
  51. package/dist/commands/project/log/append.d.ts.map +1 -0
  52. package/dist/commands/project/log/append.js +241 -0
  53. package/dist/commands/project/log/check.d.ts +66 -0
  54. package/dist/commands/project/log/check.d.ts.map +1 -0
  55. package/dist/commands/project/log/check.js +194 -0
  56. package/dist/commands/project/log/grammar.d.ts +28 -0
  57. package/dist/commands/project/log/grammar.d.ts.map +1 -0
  58. package/dist/commands/project/log/grammar.js +31 -0
  59. package/dist/commands/project/log/index.d.ts +9 -0
  60. package/dist/commands/project/log/index.d.ts.map +1 -0
  61. package/dist/commands/project/log/index.js +13 -0
  62. package/dist/commands/project/log/rollup.d.ts +40 -0
  63. package/dist/commands/project/log/rollup.d.ts.map +1 -0
  64. package/dist/commands/project/log/rollup.js +203 -0
  65. package/dist/commands/project/log/synthesize.d.ts +23 -0
  66. package/dist/commands/project/log/synthesize.d.ts.map +1 -0
  67. package/dist/commands/project/log/synthesize.js +112 -0
  68. package/dist/commands/project/new/index.d.ts +1 -0
  69. package/dist/commands/project/new/index.d.ts.map +1 -1
  70. package/dist/commands/project/new/index.js +7 -0
  71. package/dist/commands/project/new/scaffold.d.ts +1 -0
  72. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  73. package/dist/commands/project/new/scaffold.js +24 -0
  74. package/dist/config/oat-config.d.ts +12 -0
  75. package/dist/config/oat-config.d.ts.map +1 -1
  76. package/dist/config/oat-config.js +30 -0
  77. package/dist/config/resolve.d.ts.map +1 -1
  78. package/dist/config/resolve.js +9 -0
  79. package/package.json +2 -2
@@ -0,0 +1,22 @@
1
+ import type { CommandContext, GlobalOptions } from '../../app/command-context.js';
2
+ import { Command } from 'commander';
3
+ export type GateRoute = 'inline' | 'delegate-sync' | 'refuse';
4
+ export interface GateRouteDecision {
5
+ route: GateRoute;
6
+ reason: string;
7
+ }
8
+ interface GateRouteInput {
9
+ expectRuntime: string;
10
+ expectModel: string;
11
+ canAwait: boolean;
12
+ env: NodeJS.ProcessEnv;
13
+ }
14
+ interface GateRouteCommandDependencies {
15
+ processEnv: NodeJS.ProcessEnv;
16
+ buildCommandContext: (options: GlobalOptions) => CommandContext;
17
+ cliRoot?: string;
18
+ }
19
+ export declare function resolveGateRoute(input: GateRouteInput): GateRouteDecision;
20
+ export declare function createGateRouteCommand(dependencies: GateRouteCommandDependencies): Command;
21
+ export {};
22
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,eAAe,GAAG,QAAQ,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,cAAc;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED,UAAU,4BAA4B;IACpC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;IAC9B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkCD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,CAyDzE;AAoBD,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,4BAA4B,GACzC,OAAO,CAgDT"}
@@ -0,0 +1,109 @@
1
+ import { writeFileSync } from 'node:fs';
2
+ import { readGlobalOptions } from '../shared/shared.utils.js';
3
+ import { Command } from 'commander';
4
+ import { currentGateCliRoot } from './branch-local-cli.js';
5
+ const PROVIDER_MARKERS = [
6
+ { runtime: 'claude', keys: ['CLAUDECODE'] },
7
+ { runtime: 'cursor', keys: ['CURSOR_AGENT'] },
8
+ { runtime: 'codex', keys: ['CODEX_THREAD_ID', 'CODEX_SESSION_ID'] },
9
+ ];
10
+ const PROVIDER_MODEL_EVIDENCE_KEYS = {
11
+ claude: ['ANTHROPIC_MODEL', 'CLAUDE_MODEL'],
12
+ cursor: ['CURSOR_MODEL'],
13
+ codex: ['CODEX_MODEL'],
14
+ };
15
+ function nonEmptyEnvValue(env, key) {
16
+ const value = env[key]?.trim();
17
+ return value ? value : undefined;
18
+ }
19
+ function fallbackRoute(canAwait, reason) {
20
+ return canAwait
21
+ ? { route: 'delegate-sync', reason }
22
+ : { route: 'refuse', reason };
23
+ }
24
+ export function resolveGateRoute(input) {
25
+ const expectedRuntime = input.expectRuntime.trim().toLowerCase();
26
+ const expectedModel = input.expectModel.trim();
27
+ const activeMarkers = PROVIDER_MARKERS.flatMap(({ keys, runtime }) => {
28
+ const activeKeys = keys.filter((key) => nonEmptyEnvValue(input.env, key));
29
+ return activeKeys.length > 0 ? [{ keys: activeKeys, runtime }] : [];
30
+ });
31
+ const expectedRuntimeMarker = activeMarkers.find(({ runtime }) => runtime === expectedRuntime);
32
+ if (!expectedRuntimeMarker && activeMarkers.length !== 1) {
33
+ return fallbackRoute(input.canAwait, activeMarkers.length === 0
34
+ ? 'No provider runtime marker is available; inline reviewer identity is ambiguous.'
35
+ : `Multiple provider runtime markers are present (${activeMarkers.flatMap(({ keys }) => keys).join(', ')}), but none identifies expected runtime ${expectedRuntime}.`);
36
+ }
37
+ if (!expectedRuntimeMarker) {
38
+ const activeRuntime = activeMarkers[0].runtime;
39
+ return fallbackRoute(input.canAwait, `Provider runtime marker identifies ${activeRuntime}, not expected runtime ${expectedRuntime}.`);
40
+ }
41
+ const providerModelEvidenceKeys = expectedRuntime in PROVIDER_MODEL_EVIDENCE_KEYS
42
+ ? PROVIDER_MODEL_EVIDENCE_KEYS[expectedRuntime]
43
+ : [];
44
+ const modelEvidence = providerModelEvidenceKeys.flatMap((key) => {
45
+ const value = nonEmptyEnvValue(input.env, key);
46
+ return value ? [{ key, value }] : [];
47
+ });
48
+ const enforceExpectedModel = expectedModel !== 'unknown' && expectedModel !== 'provider-default';
49
+ const contradictoryModel = enforceExpectedModel
50
+ ? modelEvidence.find(({ value }) => value !== expectedModel)
51
+ : undefined;
52
+ if (contradictoryModel) {
53
+ return fallbackRoute(input.canAwait, `Model evidence ${contradictoryModel.key}=${contradictoryModel.value} contradicts expected model ${expectedModel}.`);
54
+ }
55
+ return {
56
+ route: 'inline',
57
+ reason: modelEvidence.length > 0
58
+ ? `Provider runtime marker matches expected runtime ${expectedRuntime}; available model evidence matches ${expectedModel}.`
59
+ : `Provider runtime marker matches expected runtime ${expectedRuntime}; model evidence is unavailable.`,
60
+ };
61
+ }
62
+ function parseRequiredOption(value, name) {
63
+ const parsed = value?.trim();
64
+ if (!parsed) {
65
+ throw new Error(`${name} must be a non-empty string.`);
66
+ }
67
+ return parsed;
68
+ }
69
+ function parseCanAwait(value) {
70
+ if (value === 'true') {
71
+ return true;
72
+ }
73
+ if (value === 'false') {
74
+ return false;
75
+ }
76
+ throw new Error('--can-await must be true or false.');
77
+ }
78
+ export function createGateRouteCommand(dependencies) {
79
+ return new Command('route')
80
+ .description('Choose a headless-safe reviewer execution route')
81
+ .requiredOption('--expect-runtime <runtime>', 'Expected reviewer runtime from gate invocation metadata')
82
+ .requiredOption('--expect-model <model>', 'Expected reviewer model from gate invocation metadata')
83
+ .requiredOption('--can-await <boolean>', 'Whether the host can synchronously await a delegated reviewer')
84
+ .option('--json', 'Print the route decision as JSON')
85
+ .action((options, command) => {
86
+ const context = dependencies.buildCommandContext(readGlobalOptions(command));
87
+ const expectedRuntime = parseRequiredOption(options.expectRuntime, '--expect-runtime');
88
+ const decision = resolveGateRoute({
89
+ expectRuntime: expectedRuntime,
90
+ expectModel: parseRequiredOption(options.expectModel, '--expect-model'),
91
+ canAwait: parseCanAwait(options.canAwait),
92
+ env: dependencies.processEnv,
93
+ });
94
+ if (context.json) {
95
+ const envelope = {
96
+ ...decision,
97
+ cliRoot: dependencies.cliRoot ?? currentGateCliRoot(),
98
+ };
99
+ const receiptPath = dependencies.processEnv.OAT_GATE_ROUTE_RECEIPT_PATH;
100
+ if (receiptPath) {
101
+ writeFileSync(receiptPath, `${JSON.stringify({ ...envelope, runtime: expectedRuntime })}\n`, { mode: 0o600 });
102
+ }
103
+ context.logger.json(envelope);
104
+ }
105
+ else {
106
+ context.logger.info(`${decision.route}: ${decision.reason}`);
107
+ }
108
+ });
109
+ }
@@ -13,7 +13,7 @@ export declare const PACK_METADATA: Record<string, PackMetadata>;
13
13
  export declare function resolvePackDefaultScope(packName: string): 'user' | 'project';
14
14
  export declare const WORKFLOW_SKILLS: readonly ["oat-cursor-cloud-projects", "oat-project-autonomous", "oat-project-capture", "oat-project-clear-active", "oat-project-complete", "oat-project-design", "oat-project-dispatch-subagents", "oat-project-discover", "oat-project-document", "oat-project-implement", "oat-project-import-plan", "oat-project-new", "oat-project-next", "oat-project-open", "oat-project-plan", "oat-project-plan-writing", "oat-project-pr-final", "oat-project-pr-progress", "oat-project-progress", "oat-project-promote-spec-driven", "oat-project-quick-start", "oat-project-reconcile", "oat-project-revise", "oat-project-review-provide", "oat-project-review-provide-remote", "oat-project-review-receive", "oat-project-review-receive-remote", "oat-project-spec", "oat-project-split", "oat-project-summary", "oat-repo-knowledge-index", "oat-worktree-bootstrap", "oat-worktree-bootstrap-auto", "oat-wrap-up"];
15
15
  export declare const WORKFLOW_AGENTS: readonly ["oat-codebase-mapper.md", "oat-phase-implementer.md", "oat-reviewer.md"];
16
- export declare const WORKFLOW_TEMPLATES: readonly ["state.md", "discovery.md", "spec.md", "design.md", "plan.md", "implementation.md", "summary.md"];
16
+ export declare const WORKFLOW_TEMPLATES: readonly ["state.md", "discovery.md", "spec.md", "design.md", "plan.md", "implementation.md", "summary.md", "project-log.md"];
17
17
  export declare const WORKFLOW_SCRIPTS: readonly ["generate-oat-state.sh", "generate-thin-index.sh", "resolve-tracking.sh"];
18
18
  export declare const IDEA_SKILLS: readonly ["oat-idea-new", "oat-idea-ideate", "oat-idea-summarize", "oat-idea-scratchpad"];
19
19
  export declare const CORE_SKILLS: readonly ["oat-docs", "oat-doctor"];
@@ -1 +1 @@
1
- {"version":3,"file":"skill-manifest.d.ts","sourceRoot":"","sources":["../../../../../src/commands/init/tools/shared/skill-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAKtD,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5E;AAID,eAAO,MAAM,eAAe,s3BAmClB,CAAC;AAEX,eAAO,MAAM,eAAe,oFAIlB,CAAC;AAEX,eAAO,MAAM,kBAAkB,6GAQrB,CAAC;AAEX,eAAO,MAAM,gBAAgB,qFAInB,CAAC;AAIX,eAAO,MAAM,WAAW,2FAKd,CAAC;AAIX,eAAO,MAAM,WAAW,qCAAsC,CAAC;AAI/D,eAAO,MAAM,WAAW,iLAQd,CAAC;AAEX,eAAO,MAAM,YAAY,kCAAmC,CAAC;AAI7D,eAAO,MAAM,cAAc,2NASjB,CAAC;AAIX,eAAO,MAAM,yBAAyB,sHAK5B,CAAC;AAEX,eAAO,MAAM,4BAA4B,yIAQ/B,CAAC;AAEX,eAAO,MAAM,0BAA0B,aAAc,CAAC;AAItD,eAAO,MAAM,iBAAiB,6BAA8B,CAAC;AAI7D,eAAO,MAAM,eAAe,2EAMlB,CAAC;AAEX,eAAO,MAAM,eAAe,qCAAsC,CAAC"}
1
+ {"version":3,"file":"skill-manifest.d.ts","sourceRoot":"","sources":["../../../../../src/commands/init/tools/shared/skill-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAKtD,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5E;AAID,eAAO,MAAM,eAAe,s3BAmClB,CAAC;AAEX,eAAO,MAAM,eAAe,oFAIlB,CAAC;AAEX,eAAO,MAAM,kBAAkB,+HASrB,CAAC;AAEX,eAAO,MAAM,gBAAgB,qFAInB,CAAC;AAIX,eAAO,MAAM,WAAW,2FAKd,CAAC;AAIX,eAAO,MAAM,WAAW,qCAAsC,CAAC;AAI/D,eAAO,MAAM,WAAW,iLAQd,CAAC;AAEX,eAAO,MAAM,YAAY,kCAAmC,CAAC;AAI7D,eAAO,MAAM,cAAc,2NASjB,CAAC;AAIX,eAAO,MAAM,yBAAyB,sHAK5B,CAAC;AAEX,eAAO,MAAM,4BAA4B,yIAQ/B,CAAC;AAEX,eAAO,MAAM,0BAA0B,aAAc,CAAC;AAItD,eAAO,MAAM,iBAAiB,6BAA8B,CAAC;AAI7D,eAAO,MAAM,eAAe,2EAMlB,CAAC;AAEX,eAAO,MAAM,eAAe,qCAAsC,CAAC"}
@@ -64,6 +64,7 @@ export const WORKFLOW_TEMPLATES = [
64
64
  'plan.md',
65
65
  'implementation.md',
66
66
  'summary.md',
67
+ 'project-log.md',
67
68
  ];
68
69
  export const WORKFLOW_SCRIPTS = [
69
70
  'generate-oat-state.sh',
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAsBzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAi/ED,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAkGT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAsBzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAqmFD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAkGT"}
@@ -1243,9 +1243,58 @@ async function resolveCodexProviderDefaultEffort(repoRoot, context, dependencies
1243
1243
  }
1244
1244
  return 'unknown';
1245
1245
  }
1246
- function blockMessage(provider) {
1247
- const label = providerLabel(provider);
1248
- return `BLOCKED: ${label} dispatch policy is unresolved in non-interactive mode.\nSet workflow.dispatchPolicy.mode/workflow.dispatchPolicy.policy, workflow.dispatchCeiling.providers.${provider}, oat_dispatch_policy, or legacy oat_dispatch_ceiling.`;
1246
+ function mergeEffectiveDispatchMatrix(resolvedConfig) {
1247
+ const merged = {};
1248
+ const layers = [
1249
+ resolvedConfig.user.workflow?.dispatchCeiling?.providers,
1250
+ resolvedConfig.shared.workflow?.dispatchCeiling?.providers,
1251
+ resolvedConfig.local.workflow?.dispatchCeiling?.providers,
1252
+ ];
1253
+ for (const providers of layers) {
1254
+ for (const [provider, value] of Object.entries(providers ?? {})) {
1255
+ const previous = merged[provider];
1256
+ merged[provider] =
1257
+ typeof value === 'object' &&
1258
+ value !== null &&
1259
+ !Array.isArray(value) &&
1260
+ typeof previous === 'object' &&
1261
+ previous !== null &&
1262
+ !Array.isArray(previous)
1263
+ ? { ...previous, ...value }
1264
+ : value;
1265
+ }
1266
+ }
1267
+ return merged;
1268
+ }
1269
+ function inspectLadderCompleteness(matrix) {
1270
+ const missingCells = [];
1271
+ for (const provider of ['codex', 'claude', 'cursor']) {
1272
+ const providerValue = matrix[provider];
1273
+ for (const tier of VALID_DISPATCH_MATRIX_TIERS) {
1274
+ const cell = typeof providerValue === 'object' &&
1275
+ providerValue !== null &&
1276
+ !Array.isArray(providerValue)
1277
+ ? providerValue[tier]
1278
+ : undefined;
1279
+ if (cell === undefined ||
1280
+ !isWorkflowDispatchCandidateLadder(cell) ||
1281
+ cell.candidates.length === 0) {
1282
+ missingCells.push(`${provider}.${tier}`);
1283
+ }
1284
+ }
1285
+ }
1286
+ return { complete: missingCells.length === 0, missingCells };
1287
+ }
1288
+ function unresolvedMessage(reason, missingCells) {
1289
+ const policyFix = 'set `oat_dispatch_policy` in project state (normally at plan time) or select Inherit Host Defaults';
1290
+ const ladderFix = `adopt a dispatch matrix${missingCells.length > 0 ? `; missing cells: ${missingCells.join(', ')}` : ''}`;
1291
+ if (reason === 'policy') {
1292
+ return `BLOCKED: project dispatch policy is unresolved; ${policyFix}.`;
1293
+ }
1294
+ if (reason === 'ladder') {
1295
+ return `BLOCKED: dispatch ladder is unresolved; ${ladderFix}.`;
1296
+ }
1297
+ return `BLOCKED: project dispatch policy and dispatch ladder are unresolved; ${policyFix}; ${ladderFix}.`;
1249
1298
  }
1250
1299
  function isNonInteractiveEnv(env) {
1251
1300
  return env['OAT_NON_INTERACTIVE'] === '1';
@@ -1260,6 +1309,9 @@ async function resolveDispatchCeiling(context, dependencies, options) {
1260
1309
  dependencies.resolveEffectiveConfig(repoRoot, userConfigDir, dependencies.processEnv),
1261
1310
  resolveProjectPath(repoRoot, dependencies, options),
1262
1311
  ]);
1312
+ const effectiveMatrix = mergeEffectiveDispatchMatrix(resolvedConfig);
1313
+ const ladderCompleteness = inspectLadderCompleteness(effectiveMatrix);
1314
+ const reportedMatrix = Object.keys(effectiveMatrix).length > 0 ? effectiveMatrix : null;
1263
1315
  const providerDefaultEffort = provider === 'codex'
1264
1316
  ? await resolveCodexProviderDefaultEffort(repoRoot, context, dependencies)
1265
1317
  : 'not-applicable';
@@ -1267,6 +1319,8 @@ async function resolveDispatchCeiling(context, dependencies, options) {
1267
1319
  const preferredValue = normalizePreferredValue(provider, options.preferred);
1268
1320
  const ceilingTier = normalizeCeilingTier(options.ceilingTier, role);
1269
1321
  const escalationLevel = normalizeEscalationLevel(options.escalationLevel);
1322
+ const policyResolution = readResolvedConfigCeiling(provider, resolvedConfig) ??
1323
+ (await resolveProjectStateCeiling(provider, projectPath, dependencies));
1270
1324
  const resolvedValue = await resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel, role, preferredValue, requestedCandidate, ceilingTier);
1271
1325
  for (const warning of resolvedValue?.warnings ?? []) {
1272
1326
  context.logger.warn(warning);
@@ -1299,21 +1353,35 @@ async function resolveDispatchCeiling(context, dependencies, options) {
1299
1353
  projectPath,
1300
1354
  providerDefaultEffort,
1301
1355
  matrix: resolvedValue.matrix,
1356
+ ladderCompleteness,
1302
1357
  providers,
1303
1358
  message: managedCodexDepthBlockMessage(scope, depth),
1304
1359
  };
1305
1360
  }
1306
1361
  }
1362
+ const activeTier = policyTier(resolvedValue.policy);
1363
+ const activeCell = activeTier
1364
+ ? resolveProviderMatrixCellDefinition(provider, activeTier, resolvedConfig, resolvedValue.matrix)
1365
+ : null;
1366
+ const activeLadderMissing = options.preflight === true &&
1367
+ resolvedValue.mode === 'managed' &&
1368
+ activeTier !== null &&
1369
+ (activeCell === null ||
1370
+ !isWorkflowDispatchCandidateLadder(activeCell.cell) ||
1371
+ activeCell.cell.candidates.length === 0);
1307
1372
  const incompleteManagedPreflight = options.preflight === true &&
1308
1373
  resolvedValue.mode === 'managed' &&
1309
- providerResolution.mode === 'advisory' &&
1310
- providerResolution.selection.target?.crossHarness !== true &&
1311
- providerResolution.selection.selectionMode !== 'no-review-target';
1374
+ (activeLadderMissing ||
1375
+ (providerResolution.mode === 'advisory' &&
1376
+ providerResolution.selection.target?.crossHarness !== true &&
1377
+ providerResolution.selection.selectionMode !== 'no-review-target'));
1312
1378
  if (incompleteManagedPreflight) {
1313
1379
  const shouldBlock = options.nonInteractive === true ||
1314
1380
  isNonInteractiveEnv(dependencies.processEnv) ||
1315
1381
  (!context.interactive && !context.json);
1316
- const message = shouldBlock ? blockMessage(provider) : undefined;
1382
+ const message = shouldBlock
1383
+ ? unresolvedMessage('ladder', ladderCompleteness.missingCells)
1384
+ : undefined;
1317
1385
  return {
1318
1386
  status: shouldBlock ? 'blocked' : 'unresolved',
1319
1387
  provider,
@@ -1325,7 +1393,11 @@ async function resolveDispatchCeiling(context, dependencies, options) {
1325
1393
  unresolved: true,
1326
1394
  projectPath,
1327
1395
  providerDefaultEffort,
1328
- matrix: resolvedValue.matrixCompatibility ?? resolvedValue.matrix,
1396
+ matrix: resolvedValue.matrixCompatibility ??
1397
+ resolvedValue.matrix ??
1398
+ reportedMatrix,
1399
+ ladderCompleteness,
1400
+ unresolvedReason: 'ladder',
1329
1401
  providers,
1330
1402
  message,
1331
1403
  };
@@ -1341,26 +1413,38 @@ async function resolveDispatchCeiling(context, dependencies, options) {
1341
1413
  unresolved: false,
1342
1414
  projectPath,
1343
1415
  providerDefaultEffort,
1344
- matrix: resolvedValue.matrixCompatibility ?? resolvedValue.matrix,
1416
+ matrix: resolvedValue.matrixCompatibility ??
1417
+ resolvedValue.matrix ??
1418
+ reportedMatrix,
1419
+ ladderCompleteness,
1345
1420
  providers,
1346
1421
  };
1347
1422
  }
1348
1423
  const shouldBlock = options.nonInteractive === true ||
1349
1424
  isNonInteractiveEnv(dependencies.processEnv) ||
1350
1425
  (options.preflight === true && !context.interactive && !context.json);
1351
- const message = shouldBlock ? blockMessage(provider) : undefined;
1426
+ const unresolvedReason = policyResolution
1427
+ ? 'ladder'
1428
+ : ladderCompleteness.complete
1429
+ ? 'policy'
1430
+ : 'both';
1431
+ const message = shouldBlock
1432
+ ? unresolvedMessage(unresolvedReason, ladderCompleteness.missingCells)
1433
+ : undefined;
1352
1434
  return {
1353
1435
  status: shouldBlock ? 'blocked' : 'unresolved',
1354
1436
  provider,
1355
- value: null,
1356
- policyMode: null,
1357
- policy: null,
1358
- source: null,
1359
- preset: null,
1437
+ value: policyResolution?.value ?? null,
1438
+ policyMode: policyResolution?.mode ?? null,
1439
+ policy: policyResolution?.policy ?? null,
1440
+ source: policyResolution?.source ?? null,
1441
+ preset: policyResolution?.preset ?? null,
1360
1442
  unresolved: true,
1361
1443
  projectPath,
1362
1444
  providerDefaultEffort,
1363
- matrix: null,
1445
+ matrix: reportedMatrix,
1446
+ ladderCompleteness,
1447
+ unresolvedReason,
1364
1448
  providers,
1365
1449
  message,
1366
1450
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,oBAAoB,IAAI,OAAO,CAe9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,oBAAoB,IAAI,OAAO,CAgB9C"}
@@ -4,6 +4,7 @@ import { createProjectCompleteDiscoveryCommand } from './complete-discovery/inde
4
4
  import { createProjectCompleteStateCommand } from './complete-state/index.js';
5
5
  import { createProjectDispatchCeilingCommand } from './dispatch-ceiling/index.js';
6
6
  import { createProjectListCommand } from './list.js';
7
+ import { createProjectLogCommand } from './log/index.js';
7
8
  import { createProjectNewCommand } from './new/index.js';
8
9
  import { createProjectOpenCommand } from './open/index.js';
9
10
  import { createProjectPauseCommand } from './pause/index.js';
@@ -19,6 +20,7 @@ export function createProjectCommand() {
19
20
  .addCommand(createProjectCompleteStateCommand())
20
21
  .addCommand(createProjectDispatchCeilingCommand())
21
22
  .addCommand(createProjectListCommand())
23
+ .addCommand(createProjectLogCommand())
22
24
  .addCommand(createProjectNewCommand())
23
25
  .addCommand(createProjectOpenCommand())
24
26
  .addCommand(createProjectPauseCommand())
@@ -0,0 +1,41 @@
1
+ import { type CommandContext, type GlobalOptions } from '../../../app/command-context.js';
2
+ import { type ActiveProjectResolution } from '../../../config/oat-config.js';
3
+ import { type ResolvedConfig } from '../../../config/resolve.js';
4
+ import { Command } from 'commander';
5
+ export interface AppendProjectLogInput {
6
+ repoRoot: string;
7
+ home?: string;
8
+ project?: string;
9
+ structural?: boolean;
10
+ type?: string;
11
+ scope?: string;
12
+ area?: string;
13
+ producer?: string;
14
+ ref?: string;
15
+ body?: string;
16
+ versionNote?: string;
17
+ }
18
+ export type ProjectLogAppendResult = {
19
+ status: 'appended';
20
+ logPath: string;
21
+ heading: string;
22
+ created: boolean;
23
+ } | {
24
+ status: 'skipped';
25
+ reason: 'projectLog=false';
26
+ };
27
+ export interface AppendProjectLogDependencies {
28
+ resolveActiveProject: (repoRoot: string) => Promise<ActiveProjectResolution>;
29
+ resolveEffectiveConfig: (repoRoot: string, userConfigDir: string, env?: NodeJS.ProcessEnv) => Promise<ResolvedConfig>;
30
+ resolveAssetsRoot: () => Promise<string>;
31
+ now: () => Date;
32
+ }
33
+ export interface ProjectLogAppendCommandDependencies extends AppendProjectLogDependencies {
34
+ buildCommandContext: (options: GlobalOptions) => CommandContext;
35
+ resolveProjectRoot: (cwd: string) => Promise<string>;
36
+ readStdin: () => Promise<string>;
37
+ }
38
+ export declare function instantiateProjectLogTemplate(template: string, projectName: string, date: string): string;
39
+ export declare function appendProjectLog(input: AppendProjectLogInput, overrides?: Partial<AppendProjectLogDependencies>): Promise<ProjectLogAppendResult>;
40
+ export declare function createProjectLogAppendCommand(overrides?: Partial<ProjectLogAppendCommandDependencies>): Command;
41
+ //# sourceMappingURL=append.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/log/append.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAI9E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,sBAAsB,GAC9B;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEN,MAAM,WAAW,4BAA4B;IAC3C,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,KACpB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;AAqBD,MAAM,WAAW,mCAAoC,SAAQ,4BAA4B;IACvF,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAClC;AA4LD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,MAAM,CAOR;AAiCD,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,EAC5B,SAAS,GAAE,OAAO,CAAC,4BAA4B,CAAM,GACpD,OAAO,CAAC,sBAAsB,CAAC,CAoCjC;AAsCD,wBAAgB,6BAA6B,CAC3C,SAAS,GAAE,OAAO,CAAC,mCAAmC,CAAM,GAC3D,OAAO,CA8CT"}