@open-agent-toolkit/cli 0.1.46 → 0.1.50
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/assets/agents/oat-phase-implementer.md +202 -191
- package/assets/agents/oat-reviewer.md +11 -1
- package/assets/config/dispatch-matrix-recommendation.json +120 -13
- package/assets/docs/cli-utilities/configuration.md +213 -113
- package/assets/docs/cli-utilities/workflow-gates.md +178 -27
- package/assets/docs/contributing/skills.md +14 -8
- package/assets/docs/provider-sync/providers.md +46 -8
- package/assets/docs/provider-sync/scope-and-surface.md +2 -2
- package/assets/docs/reference/cli-reference.md +3 -1
- package/assets/docs/reference/oat-directory-structure.md +27 -26
- package/assets/docs/workflows/projects/artifacts.md +31 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +297 -197
- package/assets/docs/workflows/projects/implementation-execution.md +306 -249
- package/assets/docs/workflows/projects/lifecycle.md +26 -5
- package/assets/docs/workflows/projects/reviews.md +27 -2
- package/assets/migration/pjm-restructure.md +1 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-implement/SKILL.md +290 -149
- package/assets/skills/oat-project-import-plan/SKILL.md +173 -16
- package/assets/skills/oat-project-next/SKILL.md +2 -2
- package/assets/skills/oat-project-plan/SKILL.md +122 -92
- package/assets/skills/oat-project-plan-writing/SKILL.md +246 -15
- package/assets/skills/oat-project-quick-start/SKILL.md +157 -107
- package/assets/skills/oat-project-review-provide/SKILL.md +110 -22
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +28 -1
- package/dist/commands/config/index.d.ts +3 -0
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +92 -125
- package/dist/commands/doctor/index.d.ts +3 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +57 -95
- package/dist/commands/gate/index.d.ts +7 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +615 -67
- package/dist/commands/gate/review-verdict.d.ts +16 -0
- package/dist/commands/gate/review-verdict.d.ts.map +1 -1
- package/dist/commands/gate/review-verdict.js +72 -9
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +567 -99
- package/dist/commands/providers/codex/materialize.d.ts.map +1 -1
- package/dist/commands/providers/codex/materialize.js +6 -1
- package/dist/commands/shared/frontmatter.d.ts +4 -0
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +23 -0
- package/dist/commands/status/index.d.ts +1 -0
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +10 -4
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +10 -3
- package/dist/commands/sync/sync.types.d.ts +1 -0
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/config/dispatch-matrix.d.ts +59 -0
- package/dist/config/dispatch-matrix.d.ts.map +1 -0
- package/dist/config/dispatch-matrix.js +264 -0
- package/dist/config/oat-config.d.ts +9 -18
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +99 -120
- package/dist/config/resolve.d.ts +8 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +66 -1
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/engine/scanner.d.ts +1 -0
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +17 -1
- package/dist/fs/paths.d.ts +4 -0
- package/dist/fs/paths.d.ts.map +1 -1
- package/dist/fs/paths.js +18 -1
- package/dist/providers/ceiling/registry.d.ts +1 -0
- package/dist/providers/ceiling/registry.d.ts.map +1 -1
- package/dist/providers/ceiling/registry.js +12 -5
- package/dist/providers/codex/codec/catalog.d.ts +14 -0
- package/dist/providers/codex/codec/catalog.d.ts.map +1 -0
- package/dist/providers/codex/codec/catalog.js +21 -0
- package/dist/providers/codex/codec/materialize.d.ts.map +1 -1
- package/dist/providers/codex/codec/materialize.js +6 -5
- package/dist/providers/codex/codec/shared.d.ts +19 -0
- package/dist/providers/codex/codec/shared.d.ts.map +1 -1
- package/dist/providers/codex/codec/shared.js +98 -5
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +142 -32
- package/dist/providers/identity/availability.d.ts +12 -0
- package/dist/providers/identity/availability.d.ts.map +1 -1
- package/dist/providers/identity/availability.js +72 -29
- package/dist/providers/identity/dispatch-report.d.ts +124 -0
- package/dist/providers/identity/dispatch-report.d.ts.map +1 -0
- package/dist/providers/identity/dispatch-report.js +285 -0
- package/dist/providers/identity/dispatch-validation.d.ts +28 -0
- package/dist/providers/identity/dispatch-validation.d.ts.map +1 -0
- package/dist/providers/identity/dispatch-validation.js +149 -0
- package/dist/providers/identity/stamp.d.ts +2 -0
- package/dist/providers/identity/stamp.d.ts.map +1 -1
- package/dist/providers/identity/stamp.js +7 -1
- package/dist/shared/types.d.ts +1 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js +4 -0
- package/package.json +2 -2
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { lstat, readFile } from 'node:fs/promises';
|
|
3
3
|
import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
4
|
import { atomicWriteJson, dirExists, fileExists } from '../fs/io.js';
|
|
5
|
-
import { normalizeToPosixPath } from '../fs/paths.js';
|
|
5
|
+
import { normalizeToPosixPath, validateRealPathWithinScope } from '../fs/paths.js';
|
|
6
|
+
import { normalizeDispatchMatrix, } from './dispatch-matrix.js';
|
|
6
7
|
import { parseJsonConfig } from './json.js';
|
|
8
|
+
export { VALID_DISPATCH_MATRIX_TIERS, isCodexMaterializedRouteTarget, isWorkflowDispatchCandidateLadder, isWorkflowDispatchFallbackRoute, toWorkflowDispatchCandidateLadder, validateDispatchRouteTarget, } from './dispatch-matrix.js';
|
|
7
9
|
const VALID_HILL_CHECKPOINT_DEFAULTS = ['every', 'final'];
|
|
8
10
|
const VALID_POST_IMPLEMENT_SEQUENCES = ['wait', 'summary', 'pr', 'docs-pr'];
|
|
9
11
|
const VALID_REVIEW_EXECUTION_MODELS = [
|
|
@@ -16,12 +18,11 @@ const VALID_DESIGN_MODES = [
|
|
|
16
18
|
'selective',
|
|
17
19
|
'draft',
|
|
18
20
|
];
|
|
19
|
-
export const VALID_CODEX_DISPATCH_CEILINGS = ['low', 'medium', 'high', 'xhigh'];
|
|
21
|
+
export const VALID_CODEX_DISPATCH_CEILINGS = ['low', 'medium', 'high', 'xhigh', 'max'];
|
|
20
22
|
export const VALID_CLAUDE_DISPATCH_CEILINGS = ['haiku', 'sonnet', 'opus', 'fable'];
|
|
21
23
|
export const VALID_DISPATCH_CEILING_PRESETS = ['balanced', 'maximum', 'cost-conscious'];
|
|
22
24
|
export const VALID_DISPATCH_POLICY_MODES = ['managed', 'inherit'];
|
|
23
25
|
export const VALID_MANAGED_DISPATCH_POLICIES = ['economy', 'balanced', 'high', 'frontier', 'uncapped'];
|
|
24
|
-
export const VALID_DISPATCH_MATRIX_TIERS = ['economy', 'balanced', 'high', 'frontier'];
|
|
25
26
|
const VALID_GATE_ON_FAILURES = [
|
|
26
27
|
'block',
|
|
27
28
|
'prompt',
|
|
@@ -31,6 +32,10 @@ export const BUILTIN_EXEC_TARGETS = {
|
|
|
31
32
|
'codex-default': {
|
|
32
33
|
runtime: 'codex',
|
|
33
34
|
baseCommand: ['codex', 'exec'],
|
|
35
|
+
invocation: {
|
|
36
|
+
model: 'provider-default',
|
|
37
|
+
reasoningEffort: 'provider-default',
|
|
38
|
+
},
|
|
34
39
|
hostDetectionCommand: [
|
|
35
40
|
'sh',
|
|
36
41
|
'-c',
|
|
@@ -42,6 +47,10 @@ export const BUILTIN_EXEC_TARGETS = {
|
|
|
42
47
|
'claude-default': {
|
|
43
48
|
runtime: 'claude',
|
|
44
49
|
baseCommand: ['claude', '-p'],
|
|
50
|
+
invocation: {
|
|
51
|
+
model: 'provider-default',
|
|
52
|
+
reasoningEffort: 'provider-default',
|
|
53
|
+
},
|
|
45
54
|
hostDetectionCommand: ['sh', '-c', 'test -n "$CLAUDECODE"'],
|
|
46
55
|
availabilityCommand: ['claude', '--version'],
|
|
47
56
|
priority: 100,
|
|
@@ -49,6 +58,10 @@ export const BUILTIN_EXEC_TARGETS = {
|
|
|
49
58
|
'cursor-default': {
|
|
50
59
|
runtime: 'cursor',
|
|
51
60
|
baseCommand: ['cursor-agent', '-p'],
|
|
61
|
+
invocation: {
|
|
62
|
+
model: 'provider-default',
|
|
63
|
+
reasoningEffort: 'provider-default',
|
|
64
|
+
},
|
|
52
65
|
hostDetectionCommand: ['sh', '-c', 'test -n "$CURSOR_AGENT"'],
|
|
53
66
|
availabilityCommand: [
|
|
54
67
|
'sh',
|
|
@@ -58,21 +71,6 @@ export const BUILTIN_EXEC_TARGETS = {
|
|
|
58
71
|
priority: 70,
|
|
59
72
|
},
|
|
60
73
|
};
|
|
61
|
-
export function isCodexMaterializedRouteTarget(provider, target) {
|
|
62
|
-
return (target.harness ?? provider) === 'codex';
|
|
63
|
-
}
|
|
64
|
-
export function validateDispatchRouteTarget(provider, target) {
|
|
65
|
-
if (!isCodexMaterializedRouteTarget(provider, target)) {
|
|
66
|
-
return { valid: true };
|
|
67
|
-
}
|
|
68
|
-
if (!target.model || !target.effort) {
|
|
69
|
-
return {
|
|
70
|
-
valid: false,
|
|
71
|
-
reason: 'Codex materialized dispatch targets must provide both model and effort.',
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
return { valid: true };
|
|
75
|
-
}
|
|
76
74
|
function normalizeMaxAttempts(value) {
|
|
77
75
|
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
78
76
|
return 2;
|
|
@@ -124,82 +122,6 @@ function normalizeGateConfig(value) {
|
|
|
124
122
|
}
|
|
125
123
|
return gate;
|
|
126
124
|
}
|
|
127
|
-
function normalizeProviderBareValue(providerKey, value) {
|
|
128
|
-
const trimmed = trimNonEmptyString(value);
|
|
129
|
-
if (trimmed === undefined) {
|
|
130
|
-
return undefined;
|
|
131
|
-
}
|
|
132
|
-
if (providerKey === 'codex' &&
|
|
133
|
-
!VALID_CODEX_DISPATCH_CEILINGS.includes(trimmed)) {
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
if (providerKey === 'claude' &&
|
|
137
|
-
!VALID_CLAUDE_DISPATCH_CEILINGS.includes(trimmed)) {
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
return trimmed;
|
|
141
|
-
}
|
|
142
|
-
function normalizeDispatchRouteTarget(value) {
|
|
143
|
-
if (!isRecord(value)) {
|
|
144
|
-
return undefined;
|
|
145
|
-
}
|
|
146
|
-
const target = {};
|
|
147
|
-
const harness = trimNonEmptyString(value.harness);
|
|
148
|
-
if (harness !== undefined) {
|
|
149
|
-
target.harness = harness;
|
|
150
|
-
}
|
|
151
|
-
const model = trimNonEmptyString(value.model);
|
|
152
|
-
if (model !== undefined) {
|
|
153
|
-
target.model = model;
|
|
154
|
-
}
|
|
155
|
-
const effort = trimNonEmptyString(value.effort);
|
|
156
|
-
if (effort !== undefined) {
|
|
157
|
-
target.effort = effort;
|
|
158
|
-
}
|
|
159
|
-
return Object.keys(target).length > 0 ? target : undefined;
|
|
160
|
-
}
|
|
161
|
-
function normalizeDispatchMatrixCell(providerKey, value) {
|
|
162
|
-
const bareValue = normalizeProviderBareValue(providerKey, value);
|
|
163
|
-
if (bareValue !== undefined) {
|
|
164
|
-
return bareValue;
|
|
165
|
-
}
|
|
166
|
-
if (!Array.isArray(value) || value.length === 0) {
|
|
167
|
-
return undefined;
|
|
168
|
-
}
|
|
169
|
-
const route = [];
|
|
170
|
-
for (const entry of value) {
|
|
171
|
-
const bareEntry = normalizeProviderBareValue(providerKey, entry);
|
|
172
|
-
if (bareEntry !== undefined) {
|
|
173
|
-
route.push(bareEntry);
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
const target = normalizeDispatchRouteTarget(entry);
|
|
177
|
-
if (target !== undefined) {
|
|
178
|
-
route.push(target);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return route.length > 0 ? route : undefined;
|
|
182
|
-
}
|
|
183
|
-
function normalizeDispatchProviderValue(providerKey, value) {
|
|
184
|
-
const bareValue = normalizeProviderBareValue(providerKey, value);
|
|
185
|
-
if (bareValue !== undefined) {
|
|
186
|
-
return bareValue;
|
|
187
|
-
}
|
|
188
|
-
if (!isRecord(value)) {
|
|
189
|
-
return undefined;
|
|
190
|
-
}
|
|
191
|
-
const tierMap = {};
|
|
192
|
-
for (const [tier, rawCell] of Object.entries(value)) {
|
|
193
|
-
if (!VALID_DISPATCH_MATRIX_TIERS.includes(tier)) {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
const normalized = normalizeDispatchMatrixCell(providerKey, rawCell);
|
|
197
|
-
if (normalized !== undefined) {
|
|
198
|
-
tierMap[tier] = normalized;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return Object.keys(tierMap).length > 0 ? tierMap : undefined;
|
|
202
|
-
}
|
|
203
125
|
function normalizeExecTarget(value) {
|
|
204
126
|
if (value === null) {
|
|
205
127
|
return null;
|
|
@@ -216,6 +138,16 @@ function normalizeExecTarget(value) {
|
|
|
216
138
|
if (baseCommand !== undefined) {
|
|
217
139
|
target.baseCommand = baseCommand;
|
|
218
140
|
}
|
|
141
|
+
if (isRecord(value.invocation)) {
|
|
142
|
+
const model = trimNonEmptyString(value.invocation.model);
|
|
143
|
+
const reasoningEffort = trimNonEmptyString(value.invocation.reasoningEffort);
|
|
144
|
+
if (model !== undefined || reasoningEffort !== undefined) {
|
|
145
|
+
target.invocation = {
|
|
146
|
+
...(model !== undefined ? { model } : {}),
|
|
147
|
+
...(reasoningEffort !== undefined ? { reasoningEffort } : {}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
219
151
|
const models = normalizeStringList(value.models);
|
|
220
152
|
if (models !== undefined) {
|
|
221
153
|
target.models = models;
|
|
@@ -328,15 +260,12 @@ function normalizeWorkflowConfig(parsed) {
|
|
|
328
260
|
dispatchCeiling.recommendationVersion = recommendationVersion;
|
|
329
261
|
}
|
|
330
262
|
if (isRecord(parsed.dispatchCeiling.providers)) {
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
if (Object.keys(providers).length > 0) {
|
|
339
|
-
dispatchCeiling.providers = providers;
|
|
263
|
+
const normalized = normalizeDispatchMatrix(parsed.dispatchCeiling.providers, {
|
|
264
|
+
pathPrefix: 'workflow.dispatchCeiling.providers',
|
|
265
|
+
compatibilityMode: 'layered-config',
|
|
266
|
+
});
|
|
267
|
+
if (Object.keys(normalized.providers).length > 0) {
|
|
268
|
+
dispatchCeiling.providers = normalized.providers;
|
|
340
269
|
}
|
|
341
270
|
}
|
|
342
271
|
if (Object.keys(dispatchCeiling).length > 0) {
|
|
@@ -405,7 +334,7 @@ function normalizeKnownStrays(value) {
|
|
|
405
334
|
.filter((pathValue) => pathValue !== undefined);
|
|
406
335
|
return normalized.length > 0 ? [...new Set(normalized)].sort() : undefined;
|
|
407
336
|
}
|
|
408
|
-
function normalizeProjectPath(repoRoot, pathValue) {
|
|
337
|
+
export function normalizeProjectPath(repoRoot, pathValue) {
|
|
409
338
|
if (pathValue == null) {
|
|
410
339
|
return null;
|
|
411
340
|
}
|
|
@@ -413,25 +342,42 @@ function normalizeProjectPath(repoRoot, pathValue) {
|
|
|
413
342
|
if (!trimmed) {
|
|
414
343
|
return null;
|
|
415
344
|
}
|
|
416
|
-
if (!isAbsolute(trimmed)) {
|
|
417
|
-
const normalizedRelative = trimPathValue(normalizeToPosixPath(trimmed));
|
|
418
|
-
return normalizedRelative && normalizedRelative !== '.'
|
|
419
|
-
? normalizedRelative
|
|
420
|
-
: null;
|
|
421
|
-
}
|
|
422
345
|
const repoRootResolved = resolve(repoRoot);
|
|
423
|
-
const absoluteResolved = resolve(trimmed);
|
|
424
|
-
const
|
|
425
|
-
|
|
346
|
+
const absoluteResolved = resolve(repoRootResolved, trimmed);
|
|
347
|
+
const relativePath = relative(repoRootResolved, absoluteResolved);
|
|
348
|
+
const isInsideRepo = !isAbsolute(relativePath) &&
|
|
349
|
+
relativePath !== '..' &&
|
|
350
|
+
!relativePath.startsWith(`..${sep}`);
|
|
426
351
|
if (!isInsideRepo) {
|
|
427
352
|
return null;
|
|
428
353
|
}
|
|
429
|
-
const
|
|
430
|
-
const normalizedRelative = trimPathValue(relativePath);
|
|
354
|
+
const normalizedRelative = trimPathValue(normalizeToPosixPath(relativePath));
|
|
431
355
|
return normalizedRelative && normalizedRelative !== '.'
|
|
432
356
|
? normalizedRelative
|
|
433
357
|
: null;
|
|
434
358
|
}
|
|
359
|
+
async function normalizeReadableProjectPath(repoRoot, pathValue) {
|
|
360
|
+
const normalizedPath = normalizeProjectPath(repoRoot, pathValue);
|
|
361
|
+
if (!normalizedPath) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
const absolutePath = join(repoRoot, normalizedPath);
|
|
365
|
+
try {
|
|
366
|
+
await lstat(absolutePath);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
return isMissingFileError(error) ? normalizedPath : null;
|
|
370
|
+
}
|
|
371
|
+
try {
|
|
372
|
+
const validated = await validateRealPathWithinScope(absolutePath, repoRoot);
|
|
373
|
+
return (await dirExists(validated.realPath))
|
|
374
|
+
? normalizeProjectPath(validated.realScopeRoot, validated.realPath)
|
|
375
|
+
: null;
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
435
381
|
function normalizeOatConfig(parsed) {
|
|
436
382
|
const next = { ...DEFAULT_OAT_CONFIG };
|
|
437
383
|
if (!isRecord(parsed)) {
|
|
@@ -598,7 +544,11 @@ export async function readOatLocalConfig(repoRoot) {
|
|
|
598
544
|
const configPath = getLocalConfigPath(repoRoot);
|
|
599
545
|
try {
|
|
600
546
|
const raw = await readFile(configPath, 'utf8');
|
|
601
|
-
|
|
547
|
+
const normalized = normalizeOatLocalConfig(repoRoot, parseJsonConfig(raw, configPath));
|
|
548
|
+
if (normalized.activeProject !== undefined) {
|
|
549
|
+
normalized.activeProject = await normalizeReadableProjectPath(repoRoot, normalized.activeProject);
|
|
550
|
+
}
|
|
551
|
+
return normalized;
|
|
602
552
|
}
|
|
603
553
|
catch (error) {
|
|
604
554
|
if (isMissingFileError(error)) {
|
|
@@ -623,12 +573,29 @@ export async function resolveActiveProject(repoRoot) {
|
|
|
623
573
|
if (!projectPath) {
|
|
624
574
|
return { name: null, path: null, status: 'unset' };
|
|
625
575
|
}
|
|
626
|
-
|
|
576
|
+
let resolvedProjectPath = projectPath;
|
|
577
|
+
let absoluteProjectPath = join(repoRoot, projectPath);
|
|
578
|
+
try {
|
|
579
|
+
const validated = await validateRealPathWithinScope(absoluteProjectPath, repoRoot);
|
|
580
|
+
const canonicalProjectPath = normalizeProjectPath(validated.realScopeRoot, validated.realPath);
|
|
581
|
+
if (!canonicalProjectPath) {
|
|
582
|
+
throw new Error('Project path resolves to the repository root.');
|
|
583
|
+
}
|
|
584
|
+
resolvedProjectPath = canonicalProjectPath;
|
|
585
|
+
absoluteProjectPath = validated.realPath;
|
|
586
|
+
}
|
|
587
|
+
catch {
|
|
588
|
+
return {
|
|
589
|
+
name: basename(absoluteProjectPath),
|
|
590
|
+
path: projectPath,
|
|
591
|
+
status: 'missing',
|
|
592
|
+
};
|
|
593
|
+
}
|
|
627
594
|
const statePath = join(absoluteProjectPath, 'state.md');
|
|
628
595
|
const isValid = (await dirExists(absoluteProjectPath)) && (await fileExists(statePath));
|
|
629
596
|
return {
|
|
630
597
|
name: basename(absoluteProjectPath),
|
|
631
|
-
path:
|
|
598
|
+
path: resolvedProjectPath,
|
|
632
599
|
status: isValid ? 'active' : 'missing',
|
|
633
600
|
};
|
|
634
601
|
}
|
|
@@ -637,10 +604,22 @@ export async function setActiveProject(repoRoot, projectRelativePath) {
|
|
|
637
604
|
if (!normalizedPath) {
|
|
638
605
|
throw new Error(`Active project path must be repo-relative or inside repo root: ${projectRelativePath}`);
|
|
639
606
|
}
|
|
607
|
+
let canonicalPath;
|
|
608
|
+
try {
|
|
609
|
+
const validated = await validateRealPathWithinScope(join(repoRoot, normalizedPath), repoRoot);
|
|
610
|
+
const canonicalProjectPath = normalizeProjectPath(validated.realScopeRoot, validated.realPath);
|
|
611
|
+
if (!canonicalProjectPath || !(await dirExists(validated.realPath))) {
|
|
612
|
+
throw new Error('Project directory is missing.');
|
|
613
|
+
}
|
|
614
|
+
canonicalPath = canonicalProjectPath;
|
|
615
|
+
}
|
|
616
|
+
catch {
|
|
617
|
+
throw new Error(`Active project path must be repo-relative or inside repo root: ${projectRelativePath}`);
|
|
618
|
+
}
|
|
640
619
|
const localConfig = await readOatLocalConfig(repoRoot);
|
|
641
620
|
await writeOatLocalConfig(repoRoot, {
|
|
642
621
|
...localConfig,
|
|
643
|
-
activeProject:
|
|
622
|
+
activeProject: canonicalPath,
|
|
644
623
|
});
|
|
645
624
|
}
|
|
646
625
|
export async function clearActiveProject(repoRoot, options) {
|
package/dist/config/resolve.d.ts
CHANGED
|
@@ -18,4 +18,12 @@ export interface ResolveEffectiveConfigDependencies {
|
|
|
18
18
|
export declare function resolveEffectiveConfig(repoRoot: string, userConfigDir: string, env?: NodeJS.ProcessEnv, overrides?: Partial<ResolveEffectiveConfigDependencies>): Promise<ResolvedConfig>;
|
|
19
19
|
export declare function resolveGate(effective: ResolvedConfig, skillName: string): GateConfig | null;
|
|
20
20
|
export declare function resolveExecTargets(effective: ResolvedConfig): Record<string, ExecTarget>;
|
|
21
|
+
export type ExecTargetOrigin = 'builtin' | 'user' | 'shared' | 'local';
|
|
22
|
+
export interface ResolvedExecTargetView {
|
|
23
|
+
target: ExecTarget;
|
|
24
|
+
origin: ExecTargetOrigin;
|
|
25
|
+
explicitlyConfigured: boolean;
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function resolveExecTargetViews(effective: ResolvedConfig): Record<string, ResolvedExecTargetView>;
|
|
21
29
|
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,GACR,OAAO,GACP,MAAM,GACN,KAAK,GACL,SAAS,CAAC;AAEd,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,kCAAkC;IACjD,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAClE,cAAc,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CAChE;AAmFD,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,GAAE,OAAO,CAAC,kCAAkC,CAAM,GAC1D,OAAO,CAAC,cAAc,CAAC,CAgFzB;AAED,wBAAgB,WAAW,CACzB,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,MAAM,GAChB,UAAU,GAAG,IAAI,CAcnB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,cAAc,GACxB,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAY5B;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,cAAc,GACxB,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAoDxC"}
|
package/dist/config/resolve.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isWorkflowDispatchCandidateLadder } from './dispatch-matrix.js';
|
|
1
2
|
import { BUILTIN_EXEC_TARGETS, readOatConfig, readOatLocalConfig, readUserConfig, } from './oat-config.js';
|
|
2
3
|
const DEFAULT_DEPENDENCIES = {
|
|
3
4
|
readOatConfig,
|
|
@@ -167,6 +168,53 @@ export function resolveExecTargets(effective) {
|
|
|
167
168
|
}
|
|
168
169
|
return targets;
|
|
169
170
|
}
|
|
171
|
+
export function resolveExecTargetViews(effective) {
|
|
172
|
+
const targets = cloneExecTargetRegistry(BUILTIN_EXEC_TARGETS);
|
|
173
|
+
const views = Object.fromEntries(Object.entries(targets).map(([id, target]) => [
|
|
174
|
+
id,
|
|
175
|
+
{
|
|
176
|
+
target: cloneExecTarget(target),
|
|
177
|
+
origin: 'builtin',
|
|
178
|
+
explicitlyConfigured: false,
|
|
179
|
+
enabled: true,
|
|
180
|
+
},
|
|
181
|
+
]));
|
|
182
|
+
for (const [origin, layer] of [
|
|
183
|
+
['user', effective.user.workflow?.gates?.execTargets],
|
|
184
|
+
['shared', effective.shared.workflow?.gates?.execTargets],
|
|
185
|
+
['local', effective.local.workflow?.gates?.execTargets],
|
|
186
|
+
]) {
|
|
187
|
+
if (!layer) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
for (const [id, override] of Object.entries(layer)) {
|
|
191
|
+
if (override === null) {
|
|
192
|
+
const target = targets[id] ?? views[id]?.target;
|
|
193
|
+
delete targets[id];
|
|
194
|
+
if (target) {
|
|
195
|
+
views[id] = {
|
|
196
|
+
target: cloneExecTarget(target),
|
|
197
|
+
origin,
|
|
198
|
+
explicitlyConfigured: true,
|
|
199
|
+
enabled: false,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
mergeExecTargetLayer(targets, { [id]: override });
|
|
205
|
+
const target = targets[id];
|
|
206
|
+
if (target) {
|
|
207
|
+
views[id] = {
|
|
208
|
+
target: cloneExecTarget(target),
|
|
209
|
+
origin,
|
|
210
|
+
explicitlyConfigured: true,
|
|
211
|
+
enabled: true,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return views;
|
|
217
|
+
}
|
|
170
218
|
function mergeExecTargetLayer(targets, layer) {
|
|
171
219
|
if (!layer) {
|
|
172
220
|
return;
|
|
@@ -181,6 +229,7 @@ function mergeExecTargetLayer(targets, layer) {
|
|
|
181
229
|
targets[id] = cloneExecTarget({
|
|
182
230
|
runtime: override.runtime ?? existing.runtime,
|
|
183
231
|
baseCommand: override.baseCommand ?? existing.baseCommand,
|
|
232
|
+
invocation: mergeExecTargetInvocation(existing.invocation, override.invocation),
|
|
184
233
|
models: override.models ?? existing.models,
|
|
185
234
|
hostDetectionCommand: override.hostDetectionCommand ?? existing.hostDetectionCommand,
|
|
186
235
|
availabilityCommand: override.availabilityCommand ?? existing.availabilityCommand,
|
|
@@ -209,6 +258,9 @@ function cloneExecTarget(target) {
|
|
|
209
258
|
if (target.hostDetectionCommand) {
|
|
210
259
|
next.hostDetectionCommand = [...target.hostDetectionCommand];
|
|
211
260
|
}
|
|
261
|
+
if (target.invocation) {
|
|
262
|
+
next.invocation = { ...target.invocation };
|
|
263
|
+
}
|
|
212
264
|
if (target.availabilityCommand) {
|
|
213
265
|
next.availabilityCommand = [...target.availabilityCommand];
|
|
214
266
|
}
|
|
@@ -229,6 +281,9 @@ function toCompleteExecTarget(target) {
|
|
|
229
281
|
? target.priority
|
|
230
282
|
: 0,
|
|
231
283
|
};
|
|
284
|
+
if (target.invocation) {
|
|
285
|
+
completeTarget.invocation = { ...target.invocation };
|
|
286
|
+
}
|
|
232
287
|
if (isValidArgv(target.hostDetectionCommand)) {
|
|
233
288
|
completeTarget.hostDetectionCommand = [...target.hostDetectionCommand];
|
|
234
289
|
}
|
|
@@ -240,6 +295,15 @@ function toCompleteExecTarget(target) {
|
|
|
240
295
|
}
|
|
241
296
|
return completeTarget;
|
|
242
297
|
}
|
|
298
|
+
function mergeExecTargetInvocation(existing, override) {
|
|
299
|
+
if (!existing && !override) {
|
|
300
|
+
return undefined;
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
...existing,
|
|
304
|
+
...override,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
243
307
|
function isValidStringList(value) {
|
|
244
308
|
return (Array.isArray(value) &&
|
|
245
309
|
value.length > 0 &&
|
|
@@ -264,7 +328,8 @@ function flattenConfig(value, prefix = '') {
|
|
|
264
328
|
continue;
|
|
265
329
|
}
|
|
266
330
|
const nextKey = prefix ? `${prefix}.${key}` : key;
|
|
267
|
-
if (isRecord(nestedValue)
|
|
331
|
+
if (isRecord(nestedValue) &&
|
|
332
|
+
!isWorkflowDispatchCandidateLadder(nestedValue)) {
|
|
268
333
|
Object.assign(flattened, flattenConfig(nestedValue, nextKey));
|
|
269
334
|
continue;
|
|
270
335
|
}
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ export { configureLocalHooksPath, getHookInstallInfo, HOOK_DRIFT_WARNING, HOOK_M
|
|
|
5
5
|
export type { HookInstallInfo, HookStatus } from './hook.js';
|
|
6
6
|
export { hasMarker, insertMarker, OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX, writeDirectorySentinel, } from './markers.js';
|
|
7
7
|
export type { CanonicalEntry } from './scanner.js';
|
|
8
|
-
export { scanCanonical } from './scanner.js';
|
|
8
|
+
export { scanBundledManagedCodexAgents, scanCanonical } from './scanner.js';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,6BAA6B,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/engine/index.js
CHANGED
|
@@ -3,4 +3,4 @@ export { SYNC_OPERATION_TYPES, } from './engine.types.js';
|
|
|
3
3
|
export { executeSyncPlan } from './execute-plan.js';
|
|
4
4
|
export { configureLocalHooksPath, getHookInstallInfo, HOOK_DRIFT_WARNING, HOOK_MARKER_END, HOOK_MARKER_START, HOOK_STRAY_INFO, installHook, isHookInstalled, REPO_GITHOOKS_PATH, runHookCheck, uninstallHook, } from './hook.js';
|
|
5
5
|
export { hasMarker, insertMarker, OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX, writeDirectorySentinel, } from './markers.js';
|
|
6
|
-
export { scanCanonical } from './scanner.js';
|
|
6
|
+
export { scanBundledManagedCodexAgents, scanCanonical } from './scanner.js';
|
package/dist/engine/scanner.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface CanonicalEntry {
|
|
|
6
6
|
canonicalPath: string;
|
|
7
7
|
isFile: boolean;
|
|
8
8
|
}
|
|
9
|
+
export declare function scanBundledManagedCodexAgents(): Promise<CanonicalEntry[]>;
|
|
9
10
|
export declare function scanCanonical(basePath: string, scope: ConcreteScope): Promise<CanonicalEntry[]>;
|
|
10
11
|
export {};
|
|
11
12
|
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/engine/scanner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/engine/scanner.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,KAAK,EACX,MAAM,eAAe,CAAC;AAEvB,KAAK,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;CACjB;AA0DD,wBAAsB,6BAA6B,IAAI,OAAO,CAC5D,cAAc,EAAE,CACjB,CAsBA;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CA2B3B"}
|
package/dist/engine/scanner.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readdir } from 'node:fs/promises';
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { CliError } from '../errors/index.js';
|
|
4
|
-
import {
|
|
4
|
+
import { resolveAssetsRoot } from '../fs/assets.js';
|
|
5
|
+
import { SCOPE_CONTENT_TYPES, USER_SCOPE_MANAGED_AGENT_FILES, } from '../shared/types.js';
|
|
5
6
|
function canonicalDirectoryName(contentType) {
|
|
6
7
|
if (contentType === 'skill') {
|
|
7
8
|
return 'skills';
|
|
@@ -42,6 +43,21 @@ async function readEntries(dirPath) {
|
|
|
42
43
|
throw error;
|
|
43
44
|
}
|
|
44
45
|
}
|
|
46
|
+
export async function scanBundledManagedCodexAgents() {
|
|
47
|
+
const agentsDir = join(await resolveAssetsRoot(), 'agents');
|
|
48
|
+
const entries = await readEntries(agentsDir);
|
|
49
|
+
const available = new Set(entries.filter((entry) => entry.isFile).map((entry) => entry.name));
|
|
50
|
+
const missing = USER_SCOPE_MANAGED_AGENT_FILES.filter((name) => !available.has(name));
|
|
51
|
+
if (missing.length > 0) {
|
|
52
|
+
throw new CliError(`Bundled managed Codex role definitions are unavailable: ${missing.join(', ')}. Reinstall or rebuild OAT before running user sync.`);
|
|
53
|
+
}
|
|
54
|
+
return USER_SCOPE_MANAGED_AGENT_FILES.map((name) => ({
|
|
55
|
+
name,
|
|
56
|
+
type: 'agent',
|
|
57
|
+
canonicalPath: join(agentsDir, name),
|
|
58
|
+
isFile: true,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
45
61
|
export async function scanCanonical(basePath, scope) {
|
|
46
62
|
const scopeRoot = resolve(basePath);
|
|
47
63
|
const entries = [];
|
package/dist/fs/paths.d.ts
CHANGED
|
@@ -5,5 +5,9 @@ export declare function resolveScopeRoot(scope: ConcreteScope, cwd: string, home
|
|
|
5
5
|
export declare function toPosixPath(pathValue: string): string;
|
|
6
6
|
export declare function normalizeToPosixPath(pathValue: string): string;
|
|
7
7
|
export declare function validatePathWithinScope(candidatePath: string, scopeRoot: string): string;
|
|
8
|
+
export declare function validateRealPathWithinScope(candidatePath: string, scopeRoot: string): Promise<{
|
|
9
|
+
realScopeRoot: string;
|
|
10
|
+
realPath: string;
|
|
11
|
+
}>;
|
|
8
12
|
export {};
|
|
9
13
|
//# sourceMappingURL=paths.d.ts.map
|
package/dist/fs/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/fs/paths.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,KAAK,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE3C,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBrE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,MAAM,CAMR;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAcR"}
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/fs/paths.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,KAAK,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE3C,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBrE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,MAAM,CAMR;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAcR;AAED,wBAAsB,2BAA2B,CAC/C,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAsBtD"}
|
package/dist/fs/paths.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { access } from 'node:fs/promises';
|
|
1
|
+
import { access, realpath } from 'node:fs/promises';
|
|
2
2
|
import { dirname, posix, resolve, sep } from 'node:path';
|
|
3
3
|
import { CliError } from '../errors/index.js';
|
|
4
4
|
export async function resolveProjectRoot(cwd) {
|
|
@@ -40,3 +40,20 @@ export function validatePathWithinScope(candidatePath, scopeRoot) {
|
|
|
40
40
|
}
|
|
41
41
|
return resolvedCandidatePath;
|
|
42
42
|
}
|
|
43
|
+
export async function validateRealPathWithinScope(candidatePath, scopeRoot) {
|
|
44
|
+
const resolvedCandidatePath = validatePathWithinScope(candidatePath, scopeRoot);
|
|
45
|
+
let realScopeRoot;
|
|
46
|
+
let realCandidatePath;
|
|
47
|
+
try {
|
|
48
|
+
[realScopeRoot, realCandidatePath] = await Promise.all([
|
|
49
|
+
realpath(resolve(scopeRoot)),
|
|
50
|
+
realpath(resolvedCandidatePath),
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const detail = error instanceof Error ? `: ${error.message}` : '';
|
|
55
|
+
throw new CliError(`Unable to resolve real path for ${candidatePath} within scope root ${scopeRoot}${detail}`);
|
|
56
|
+
}
|
|
57
|
+
validatePathWithinScope(realCandidatePath, realScopeRoot);
|
|
58
|
+
return { realScopeRoot, realPath: realCandidatePath };
|
|
59
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/providers/ceiling/registry.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/providers/ceiling/registry.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB,IAAI,CAAC;AAKT,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,oBAAoB,CAAC;IAChC;;;OAGG;IACH,qBAAqB,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,qBAAqB,GACzB,mBAAmB,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC;CACtE;AAMD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAK9C,CAAC;AA4GF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAE1E"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { VALID_CLAUDE_DISPATCH_CEILINGS, VALID_CODEX_DISPATCH_CEILINGS, } from '../../config/oat-config.js';
|
|
2
|
-
import {
|
|
2
|
+
import { buildCodexMaterializedTargetRoleName } from '../codex/codec/shared.js';
|
|
3
|
+
const DIRECT_DISPATCH_ROLE_PATTERN = /^oat-(?:phase-implementer|reviewer)(?:-|$)/;
|
|
4
|
+
export function isDirectDispatchRoleName(value) {
|
|
5
|
+
return DIRECT_DISPATCH_ROLE_PATTERN.test(value.trim());
|
|
6
|
+
}
|
|
3
7
|
/** Codex materialized-role base names (must match sync-extension output). */
|
|
4
8
|
const CODEX_IMPLEMENTER_ROLE = 'oat-phase-implementer';
|
|
5
9
|
const CODEX_REVIEWER_ROLE = 'oat-reviewer';
|
|
@@ -20,12 +24,14 @@ const codexAdapter = {
|
|
|
20
24
|
return null;
|
|
21
25
|
}
|
|
22
26
|
const target = ctx.target;
|
|
23
|
-
if (!target?.model ||
|
|
27
|
+
if (!target?.model ||
|
|
28
|
+
!target.effort ||
|
|
29
|
+
isDirectDispatchRoleName(target.model)) {
|
|
24
30
|
return null;
|
|
25
31
|
}
|
|
26
32
|
const baseRole = role === 'reviewer' ? CODEX_REVIEWER_ROLE : CODEX_IMPLEMENTER_ROLE;
|
|
27
33
|
return {
|
|
28
|
-
variant:
|
|
34
|
+
variant: buildCodexMaterializedTargetRoleName({
|
|
29
35
|
agentName: baseRole,
|
|
30
36
|
model: target.model,
|
|
31
37
|
effort: target.effort,
|
|
@@ -55,7 +61,8 @@ const claudeAdapter = {
|
|
|
55
61
|
validValues: [...VALID_CLAUDE_DISPATCH_CEILINGS],
|
|
56
62
|
mechanism: 'model-arg',
|
|
57
63
|
compileToDispatchArgs(value) {
|
|
58
|
-
if (
|
|
64
|
+
if (isDirectDispatchRoleName(value) ||
|
|
65
|
+
!VALID_CLAUDE_DISPATCH_CEILINGS.includes(value)) {
|
|
59
66
|
return null;
|
|
60
67
|
}
|
|
61
68
|
return { model: value };
|
|
@@ -72,7 +79,7 @@ const cursorAdapter = {
|
|
|
72
79
|
mechanism: 'model-arg',
|
|
73
80
|
compileToDispatchArgs(value) {
|
|
74
81
|
const model = value.trim();
|
|
75
|
-
return model ? { model } : null;
|
|
82
|
+
return model && !isDirectDispatchRoleName(model) ? { model } : null;
|
|
76
83
|
},
|
|
77
84
|
// Cursor model slugs do not share a total order, so upgrade verification is
|
|
78
85
|
// not meaningful here; availability is checked by the identity oracle layer.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { SUPPORTED_CODEX_ROLE_TARGETS } from './shared.js';
|
|
2
|
+
export declare const SUPPORTED_CODEX_BASE_ROLES: readonly ["oat-phase-implementer", "oat-reviewer"];
|
|
3
|
+
export interface SupportedCodexRoleCatalogueEntry {
|
|
4
|
+
baseRole: (typeof SUPPORTED_CODEX_BASE_ROLES)[number];
|
|
5
|
+
model: string;
|
|
6
|
+
effort: string;
|
|
7
|
+
roleName: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function isSupportedCodexRoleTarget(target: {
|
|
10
|
+
model: string;
|
|
11
|
+
effort: string;
|
|
12
|
+
}): boolean;
|
|
13
|
+
export declare function expandSupportedCodexRoleCatalogue(): SupportedCodexRoleCatalogueEntry[];
|
|
14
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../../src/providers/codex/codec/catalog.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAExD,eAAO,MAAM,0BAA0B,oDAG7B,CAAC;AAEX,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,EAAE,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAKV;AAED,wBAAgB,iCAAiC,IAAI,gCAAgC,EAAE,CAYtF"}
|