@open-agent-toolkit/cli 0.2.57 → 0.2.59
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 +44 -2
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/configuration.md +16 -0
- package/assets/docs/cli-utilities/workflow-gates.md +88 -3
- package/assets/docs/contributing/skills.md +27 -5
- package/assets/docs/contributing/smoke-testing.md +44 -0
- package/assets/docs/provider-sync/commands.md +23 -0
- package/assets/docs/workflows/projects/autonomy.md +5 -2
- package/assets/docs/workflows/projects/dispatch-ceiling.md +43 -7
- package/assets/docs/workflows/projects/implementation-execution.md +6 -3
- package/assets/docs/workflows/projects/lifecycle.md +4 -3
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-autonomous/SKILL.md +1 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +45 -38
- package/assets/skills/oat-project-design/SKILL.md +24 -5
- package/assets/skills/oat-project-discover/SKILL.md +10 -5
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +45 -38
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +43 -9
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +14 -8
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +45 -38
- package/assets/skills/oat-project-implement/references/phase-execution.md +7 -3
- package/assets/skills/oat-project-import-plan/SKILL.md +29 -4
- package/assets/skills/oat-project-next/SKILL.md +29 -2
- package/assets/skills/oat-project-plan/SKILL.md +29 -4
- package/assets/skills/oat-project-plan-writing/SKILL.md +95 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +45 -38
- package/assets/skills/oat-project-progress/SKILL.md +12 -1
- package/assets/skills/oat-project-quick-start/SKILL.md +29 -4
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +45 -38
- package/assets/skills/oat-project-review-provide/SKILL.md +13 -6
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +12 -5
- package/assets/templates/state.md +4 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +102 -8
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +16 -1
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +10 -1
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +10 -1
- package/dist/commands/shared/frontmatter.d.ts +32 -1
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +92 -0
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +8 -1
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +40 -6
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +11 -17
- package/dist/commands/sync/sync.types.d.ts +6 -6
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/config/resolve.d.ts +16 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +16 -8
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +6 -0
- package/dist/manifest/index.d.ts +2 -1
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +1 -1
- package/dist/manifest/manager.d.ts +40 -0
- package/dist/manifest/manager.d.ts.map +1 -1
- package/dist/manifest/manager.js +35 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-review-provide
|
|
3
|
-
version: 1.5.
|
|
3
|
+
version: 1.5.4
|
|
4
4
|
description: Use when the user explicitly asks to review an OAT project — e.g. "review project", "review the project", "run project review", or confirms a previously offered review. Do NOT auto-invoke on completed work alone. Resolves a project review scope and offers before running.
|
|
5
5
|
disable-model-invocation: false
|
|
6
6
|
user-invocable: true
|
|
@@ -654,11 +654,18 @@ oat project dispatch-ceiling resolve --provider "$ACTIVE_PROVIDER" --role review
|
|
|
654
654
|
```
|
|
655
655
|
|
|
656
656
|
Require `dispatchReport.schemaVersion: 1`. Render/consume the resolver's
|
|
657
|
-
versioned report using `formatDispatchReport(dispatchReport)` semantics
|
|
658
|
-
|
|
659
|
-
`
|
|
660
|
-
|
|
661
|
-
|
|
657
|
+
versioned report using `formatDispatchReport(dispatchReport)` semantics. Take
|
|
658
|
+
the formal compatibility line directly from the same response's additive
|
|
659
|
+
`dispatchStamp` field: it must be a non-empty string beginning with the
|
|
660
|
+
canonical `Dispatch:` prefix. Copy that returned value byte-for-byte into the
|
|
661
|
+
review dispatch audit metadata. Reformatting the report through
|
|
662
|
+
`formatDispatchStamp(dispatchReport)` / `toDispatchStampRecord(dispatchReport)`
|
|
663
|
+
is an optional corroboration where that library is already loaded; it is never
|
|
664
|
+
the normal path and never a substitute for the returned field, and no
|
|
665
|
+
out-of-tree shim is required. Do not hand-assemble `Dispatch:` fields from a
|
|
666
|
+
role name or model string. If `dispatchStamp` is absent or lacks the canonical
|
|
667
|
+
prefix on a report-bearing response, stop and report instead of reconstructing
|
|
668
|
+
it.
|
|
662
669
|
|
|
663
670
|
The exact managed provider target still comes from
|
|
664
671
|
`providers.<provider>.dispatchArgs` plus
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-review-provide-remote
|
|
3
|
-
version: 1.1.
|
|
3
|
+
version: 1.1.3
|
|
4
4
|
description: Use when reviewing a GitHub PR opened on another machine for an active OAT project and posting findings back as a single PR review. Resolves the project from the PR diff, reads project artifacts for mode-aware review, and posts via gh api.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: true
|
|
@@ -286,10 +286,17 @@ oat project dispatch-ceiling resolve --provider "$ACTIVE_PROVIDER" --role review
|
|
|
286
286
|
```
|
|
287
287
|
|
|
288
288
|
Require `dispatchReport.schemaVersion: 1`. Render/consume its versioned human
|
|
289
|
-
block with `formatDispatchReport(dispatchReport)` semantics and
|
|
290
|
-
|
|
291
|
-
`
|
|
292
|
-
|
|
289
|
+
block with `formatDispatchReport(dispatchReport)` semantics and take the formal
|
|
290
|
+
audit `Dispatch:` line directly from the same response's additive
|
|
291
|
+
`dispatchStamp` field: it must be a non-empty string beginning with the
|
|
292
|
+
canonical `Dispatch:` prefix. Copy that returned value byte-for-byte into the
|
|
293
|
+
review dispatch audit metadata. Reformatting the report through
|
|
294
|
+
`formatDispatchStamp(dispatchReport)` / `toDispatchStampRecord(dispatchReport)`
|
|
295
|
+
is an optional corroboration where that library is already loaded; it is never
|
|
296
|
+
the normal path and never a substitute for the returned field, and no
|
|
297
|
+
out-of-tree shim is required. Never hand-build a parallel stamp schema. If
|
|
298
|
+
`dispatchStamp` is absent or lacks the canonical prefix on a report-bearing
|
|
299
|
+
response, stop and report instead of reconstructing it.
|
|
293
300
|
|
|
294
301
|
Retain the exact managed provider payload from
|
|
295
302
|
`providers.<provider>.dispatchArgs` and
|
|
@@ -36,13 +36,16 @@ oat_phase_status: in_progress # Status: in_progress | complete | pr_open
|
|
|
36
36
|
# oat_dispatch_ceiling: # legacy compatibility alias for capped managed provider targets
|
|
37
37
|
oat_workflow_mode: { OAT_WORKFLOW_MODE } # spec-driven | quick | import
|
|
38
38
|
oat_workflow_origin: native # native | imported
|
|
39
|
+
# oat_skill_gate_overrides: # optional; per-project posture for configured lifecycle gates
|
|
40
|
+
# oat-project-implement: disabled # only the literal value `disabled`; absence means follow configuration
|
|
39
41
|
# oat_implement_exit_gate: # optional; durable configured implementation exit-gate state
|
|
40
42
|
# status: pending # pending | allowed | blocked | stale
|
|
41
43
|
# resolution: configured # configured | no_gate
|
|
42
|
-
# disposition: null # null | passed | warned | prompt_approved | no_gate
|
|
44
|
+
# disposition: null # null | passed | warned | prompt_approved | project_disabled | no_gate
|
|
43
45
|
# config_fingerprint: '<stable hash of resolved gate declaration>'
|
|
44
46
|
# resolved_command: null
|
|
45
47
|
# resolved_description: null
|
|
48
|
+
# project_override: null # null or {value: disabled, source: state.md:oat_skill_gate_overrides}
|
|
46
49
|
# on_failure: block # block | prompt | warn | null
|
|
47
50
|
# max_attempts: 2
|
|
48
51
|
# attempts_completed: 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,11 +5,11 @@ import { tmpdir } from 'node:os';
|
|
|
5
5
|
import { basename, isAbsolute, join, relative } from 'node:path';
|
|
6
6
|
import { buildCommandContext, } from '../../app/command-context.js';
|
|
7
7
|
import { appendProjectLog } from '../project/log/append.js';
|
|
8
|
-
import { getFrontmatterBlock, parseFrontmatterScalarFields, parseGeneratedTime, } from '../shared/frontmatter.js';
|
|
8
|
+
import { getFrontmatterBlock, parseFrontmatterScalarFields, parseGeneratedTime, parseSkillGateOverrides, SKILL_GATE_OVERRIDE_DISABLED, SKILL_GATE_OVERRIDE_SOURCE, } from '../shared/frontmatter.js';
|
|
9
9
|
import { readGlobalOptions } from '../shared/shared.utils.js';
|
|
10
10
|
import { parseJsonConfig } from '../../config/json.js';
|
|
11
11
|
import { BUILTIN_EXEC_TARGETS, MAX_GATE_TIMEOUT_MS, MIN_GATE_TIMEOUT_MS, isValidGateTimeoutMs, readOatConfig, readOatLocalConfig, readUserConfig, writeOatConfig, writeOatLocalConfig, writeUserConfig, } from '../../config/oat-config.js';
|
|
12
|
-
import { resolveEffectiveConfig, resolveExecTargetViews, resolveExecTargets, resolveGate, } from '../../config/resolve.js';
|
|
12
|
+
import { resolveEffectiveConfig, resolveExecTargetViews, resolveExecTargets, resolveGate, resolveGateWithSource, } from '../../config/resolve.js';
|
|
13
13
|
import { dirExists, fileExists } from '../../fs/io.js';
|
|
14
14
|
import { normalizeToPosixPath, resolveProjectRoot, validateRealPathWithinScope, } from '../../fs/paths.js';
|
|
15
15
|
import { buildDispatchReport, } from '../../providers/identity/dispatch-report.js';
|
|
@@ -1173,6 +1173,7 @@ function resolvedProjectsRoot(effective) {
|
|
|
1173
1173
|
}
|
|
1174
1174
|
async function resolveReviewProject(options) {
|
|
1175
1175
|
const projectsRoot = resolvedProjectsRoot(options.effective);
|
|
1176
|
+
const commandLabel = options.commandLabel ?? 'gate review';
|
|
1176
1177
|
if (options.project !== undefined) {
|
|
1177
1178
|
return {
|
|
1178
1179
|
path: await resolveExplicitReviewProject(options.repoRoot, projectsRoot, options.project),
|
|
@@ -1188,10 +1189,10 @@ async function resolveReviewProject(options) {
|
|
|
1188
1189
|
}
|
|
1189
1190
|
const candidates = await listProjectCandidates(options.repoRoot, projectsRoot);
|
|
1190
1191
|
if (candidates.length === 0) {
|
|
1191
|
-
throw new Error(
|
|
1192
|
+
throw new Error(`No OAT project could be resolved for ${commandLabel}. Set an active project or pass --project <path-or-name>.`);
|
|
1192
1193
|
}
|
|
1193
1194
|
if (candidates.length > 1) {
|
|
1194
|
-
throw new Error(`Multiple OAT projects could be resolved for
|
|
1195
|
+
throw new Error(`Multiple OAT projects could be resolved for ${commandLabel}: ${candidates.join(', ')}. Pass --project <path-or-name>.`);
|
|
1195
1196
|
}
|
|
1196
1197
|
return {
|
|
1197
1198
|
path: candidates[0],
|
|
@@ -1725,10 +1726,102 @@ async function updateConfigLayer(context, layer, dependencies, mutate) {
|
|
|
1725
1726
|
const config = await dependencies.readUserConfig(userConfigDir);
|
|
1726
1727
|
await dependencies.writeUserConfig(userConfigDir, mutate(config));
|
|
1727
1728
|
}
|
|
1728
|
-
|
|
1729
|
+
/**
|
|
1730
|
+
* Read the project's declared gate overrides.
|
|
1731
|
+
*
|
|
1732
|
+
* Fails closed rather than defaulting to "no overrides": unreadable project
|
|
1733
|
+
* state would otherwise silently launch a gate the operator disabled. CRLF
|
|
1734
|
+
* checkouts are normalized first so a line-ending difference is not mistaken
|
|
1735
|
+
* for missing frontmatter.
|
|
1736
|
+
*/
|
|
1737
|
+
async function readProjectGateOverrides(repoRoot, projectPath) {
|
|
1738
|
+
const statePath = normalizeToPosixPath(join(projectPath, 'state.md'));
|
|
1739
|
+
const content = await readFile(join(repoRoot, statePath), 'utf8');
|
|
1740
|
+
const frontmatter = getFrontmatterBlock(content.replace(/\r\n/g, '\n'));
|
|
1741
|
+
if (frontmatter === null) {
|
|
1742
|
+
throw new Error(`${statePath}: project state has no readable YAML frontmatter block, so gate overrides cannot be resolved. Repair the state file before resolving a project-aware gate.`);
|
|
1743
|
+
}
|
|
1744
|
+
return parseSkillGateOverrides(frontmatter, statePath).overrides;
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Project-aware resolution. `configuredGate` is retained even when an override
|
|
1748
|
+
* makes the effective gate null, so project-disabled evidence can never be
|
|
1749
|
+
* mistaken for absent configuration.
|
|
1750
|
+
*/
|
|
1751
|
+
async function resolveProjectAwareGate(options) {
|
|
1752
|
+
const project = await resolveReviewProject({
|
|
1753
|
+
repoRoot: options.repoRoot,
|
|
1754
|
+
effective: options.effective,
|
|
1755
|
+
// Same active/name/path contract as `oat gate review`; only the guidance
|
|
1756
|
+
// wording follows the caller, so a `gate resolve` failure does not tell the
|
|
1757
|
+
// operator to fix a review command they never ran.
|
|
1758
|
+
commandLabel: 'gate resolve',
|
|
1759
|
+
// A bare `--project` defers to the same active/single-candidate rules
|
|
1760
|
+
// `oat gate review` uses when it is given no explicit project.
|
|
1761
|
+
...(typeof options.projectValue === 'string'
|
|
1762
|
+
? { project: options.projectValue }
|
|
1763
|
+
: {}),
|
|
1764
|
+
});
|
|
1765
|
+
const overrides = await readProjectGateOverrides(options.repoRoot, project.path);
|
|
1766
|
+
const projectOverride = overrides[options.skillName] === SKILL_GATE_OVERRIDE_DISABLED
|
|
1767
|
+
? {
|
|
1768
|
+
value: SKILL_GATE_OVERRIDE_DISABLED,
|
|
1769
|
+
source: SKILL_GATE_OVERRIDE_SOURCE,
|
|
1770
|
+
}
|
|
1771
|
+
: null;
|
|
1772
|
+
const { gate, source } = resolveGateWithSource(options.effective, options.skillName);
|
|
1773
|
+
// An override never fabricates configuration: with no configured gate the
|
|
1774
|
+
// resolution stays `not_configured` while the override remains visible.
|
|
1775
|
+
// `configSource` still reports the layer that owned the decision when one
|
|
1776
|
+
// explicitly declared the skill `null`, so an operator can tell a deliberate
|
|
1777
|
+
// layer-level disable from a skill no layer mentions at all. It stays null in
|
|
1778
|
+
// the latter case, and `configuredGate` is null either way.
|
|
1779
|
+
if (!gate) {
|
|
1780
|
+
return {
|
|
1781
|
+
skill: options.skillName,
|
|
1782
|
+
resolution: 'not_configured',
|
|
1783
|
+
configuredGate: null,
|
|
1784
|
+
effectiveGate: null,
|
|
1785
|
+
configSource: source,
|
|
1786
|
+
projectOverride,
|
|
1787
|
+
};
|
|
1788
|
+
}
|
|
1789
|
+
if (projectOverride) {
|
|
1790
|
+
return {
|
|
1791
|
+
skill: options.skillName,
|
|
1792
|
+
resolution: 'configured_disabled_by_project',
|
|
1793
|
+
configuredGate: gate,
|
|
1794
|
+
effectiveGate: null,
|
|
1795
|
+
configSource: source,
|
|
1796
|
+
projectOverride,
|
|
1797
|
+
};
|
|
1798
|
+
}
|
|
1799
|
+
return {
|
|
1800
|
+
skill: options.skillName,
|
|
1801
|
+
resolution: 'configured',
|
|
1802
|
+
configuredGate: gate,
|
|
1803
|
+
effectiveGate: gate,
|
|
1804
|
+
configSource: source,
|
|
1805
|
+
projectOverride: null,
|
|
1806
|
+
};
|
|
1807
|
+
}
|
|
1808
|
+
async function runResolve(skillName, options, context, dependencies) {
|
|
1729
1809
|
try {
|
|
1730
1810
|
const effective = await readEffectiveConfig(context, dependencies);
|
|
1731
|
-
|
|
1811
|
+
// Without project context this stays byte-identical to the legacy raw
|
|
1812
|
+
// `GateConfig | null` output that external consumers already parse.
|
|
1813
|
+
if (options.project === undefined) {
|
|
1814
|
+
writeJsonValue(context, resolveGate(effective, skillName));
|
|
1815
|
+
process.exitCode = 0;
|
|
1816
|
+
return;
|
|
1817
|
+
}
|
|
1818
|
+
const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
|
|
1819
|
+
writeJsonValue(context, await resolveProjectAwareGate({
|
|
1820
|
+
skillName,
|
|
1821
|
+
projectValue: options.project,
|
|
1822
|
+
repoRoot,
|
|
1823
|
+
effective,
|
|
1824
|
+
}));
|
|
1732
1825
|
process.exitCode = 0;
|
|
1733
1826
|
}
|
|
1734
1827
|
catch (error) {
|
|
@@ -2370,9 +2463,10 @@ export function createGateCommand(overrides = {}) {
|
|
|
2370
2463
|
.command('resolve')
|
|
2371
2464
|
.description('Print the resolved gate configuration for a skill')
|
|
2372
2465
|
.argument('<skill>', 'Gate-aware skill name')
|
|
2373
|
-
.
|
|
2466
|
+
.option('--project [path-or-name]', 'Resolve with project gate overrides applied; defaults to the active project')
|
|
2467
|
+
.action(async (skillName, options, command) => {
|
|
2374
2468
|
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
2375
|
-
await runResolve(skillName, context, dependencies);
|
|
2469
|
+
await runResolve(skillName, options, context, dependencies);
|
|
2376
2470
|
});
|
|
2377
2471
|
cmd
|
|
2378
2472
|
.command('set')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,0BAA0B,CAAC;AAclC,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAKzC,OAAO,EAGL,KAAK,UAAU,EAEhB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,eAAe,EAOrB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ import { configureLocalHooksPath, getHookInstallInfo, installHook, isHookInstall
|
|
|
21
21
|
import { dirExists, fileExists } from '../../fs/io.js';
|
|
22
22
|
import { resolveProjectRoot, resolveScopeRoot } from '../../fs/paths.js';
|
|
23
23
|
import { normalizeToPosixPath } from '../../fs/paths.js';
|
|
24
|
-
import { createEmptyManifest, loadManifest, saveManifest, } from '../../manifest/manager.js';
|
|
24
|
+
import { createEmptyManifest, detectManifestVersionRestamp, formatManifestVersionRestampWarning, loadManifest, saveManifest, } from '../../manifest/manager.js';
|
|
25
25
|
import { applyCodexProjectExtensionPlan, computeCodexProjectExtensionPlan, } from '../../providers/codex/codec/sync-extension.js';
|
|
26
26
|
import { applyCursorProjectExtensionPlan, computeCursorProjectExtensionPlan, } from '../../providers/cursor/codec/sync-extension.js';
|
|
27
27
|
import { getActiveAdapters, getConfigAwareAdapters, getProviderRegistrations, recomputeProviderScopeContext, resolveProviderScopeContext, } from '../../providers/shared/index.js';
|
|
@@ -465,6 +465,7 @@ async function runInitCommand(context, dependencies, hookFlag, setupFlag, explic
|
|
|
465
465
|
let projectRoot = null;
|
|
466
466
|
let oatDirExistedBefore = true;
|
|
467
467
|
const scopeSummaries = [];
|
|
468
|
+
const manifestVersionRestamps = [];
|
|
468
469
|
let migrationAborted = false;
|
|
469
470
|
for (const scope of scopes) {
|
|
470
471
|
const scopeRoot = await dependencies.resolveScopeRoot(scope, context);
|
|
@@ -539,6 +540,16 @@ async function runInitCommand(context, dependencies, hookFlag, setupFlag, explic
|
|
|
539
540
|
}
|
|
540
541
|
const manifestPath = join(scopeRoot, '.oat', 'sync', 'manifest.json');
|
|
541
542
|
let manifest = await dependencies.loadManifest(manifestPath);
|
|
543
|
+
// Captured from the manifest exactly as loaded, before any replacement:
|
|
544
|
+
// adoption rewrites `manifest` and the save then replaces `oatVersion`
|
|
545
|
+
// outright, so this is the last point at which the producing version is
|
|
546
|
+
// still observable. Taken ahead of the `entries` fallback below so the
|
|
547
|
+
// ordering is correct by construction rather than by the schema's current
|
|
548
|
+
// insistence that `entries` be present.
|
|
549
|
+
const versionRestamp = detectManifestVersionRestamp(scope, manifest);
|
|
550
|
+
if (versionRestamp) {
|
|
551
|
+
manifestVersionRestamps.push(versionRestamp);
|
|
552
|
+
}
|
|
542
553
|
if (!manifest.entries) {
|
|
543
554
|
manifest = createEmptyManifest();
|
|
544
555
|
}
|
|
@@ -673,6 +684,9 @@ async function runInitCommand(context, dependencies, hookFlag, setupFlag, explic
|
|
|
673
684
|
context.logger.info(`No stray entries adopted [${scope}].`);
|
|
674
685
|
}
|
|
675
686
|
}
|
|
687
|
+
if (versionRestamp && !context.json) {
|
|
688
|
+
context.logger.warn(formatManifestVersionRestampWarning('init', versionRestamp));
|
|
689
|
+
}
|
|
676
690
|
await dependencies.saveManifest(manifestPath, manifest);
|
|
677
691
|
scopeSummaries.push({
|
|
678
692
|
scope,
|
|
@@ -689,6 +703,7 @@ async function runInitCommand(context, dependencies, hookFlag, setupFlag, explic
|
|
|
689
703
|
straysAdopted: scopeSummaries.reduce((total, summary) => total + summary.straysAdopted, 0),
|
|
690
704
|
hookInstalled,
|
|
691
705
|
scopes: scopeSummaries,
|
|
706
|
+
manifestVersionRestamps,
|
|
692
707
|
};
|
|
693
708
|
context.logger.json(payload);
|
|
694
709
|
}
|
|
@@ -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;AAkB9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;
|
|
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;AAkB9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AA6BzB,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;AA0wFD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CA0GT"}
|
|
@@ -14,6 +14,7 @@ import TOML from '@iarna/toml';
|
|
|
14
14
|
import { getCeilingAdapter, isDirectDispatchRoleName, CLAUDE_TIER_ORDER, } from '../../../providers/ceiling/registry.js';
|
|
15
15
|
import { buildDispatchReport, formatDispatchReport, } from '../../../providers/identity/dispatch-report.js';
|
|
16
16
|
import { classifyModelFamily, } from '../../../providers/identity/family.js';
|
|
17
|
+
import { formatDispatchStamp, } from '../../../providers/identity/stamp.js';
|
|
17
18
|
import { Command, Option } from 'commander';
|
|
18
19
|
import YAML from 'yaml';
|
|
19
20
|
const CODEX_VALUES = [
|
|
@@ -1824,7 +1825,15 @@ async function runDispatchCeilingResolve(context, dependencies, options) {
|
|
|
1824
1825
|
const resolution = await resolveDispatchCeiling(context, dependencies, options);
|
|
1825
1826
|
const dispatchReport = buildResolutionReport(resolution, options);
|
|
1826
1827
|
if (context.json) {
|
|
1827
|
-
|
|
1828
|
+
// The stamp is emitted exactly when report context produced a report, and
|
|
1829
|
+
// always through the canonical formatter: never hand-assembled here.
|
|
1830
|
+
context.logger.json(dispatchReport
|
|
1831
|
+
? {
|
|
1832
|
+
...resolution,
|
|
1833
|
+
dispatchReport,
|
|
1834
|
+
dispatchStamp: formatDispatchStamp(dispatchReport),
|
|
1835
|
+
}
|
|
1836
|
+
: resolution);
|
|
1828
1837
|
}
|
|
1829
1838
|
else {
|
|
1830
1839
|
writeHumanResolution(context, resolution);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove-skill.d.ts","sourceRoot":"","sources":["../../../../src/commands/remove/skill/remove-skill.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EACL,iBAAiB,EAElB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,eAAe,CAAC;AAGvB,OAAO,
|
|
1
|
+
{"version":3,"file":"remove-skill.d.ts","sourceRoot":"","sources":["../../../../src/commands/remove/skill/remove-skill.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EACL,iBAAiB,EAElB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,eAAe,CAAC;AAGvB,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,aAAa,EAKnB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACL,KAAK,yBAAyB,EAG9B,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqCpC,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAC1C,cAAc,CAAC;IACpB,gBAAgB,EAAE,CAChB,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,cAAc,KACpB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,WAAW,EAAE,MAAM,eAAe,EAAE,CAAC;IACrC,sBAAsB,EAAE,CACtB,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,KACf,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACxC,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;IAC3E,kBAAkB,EAAE,CAClB,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,KAAK,KACT,cAAc,EAAE,CAAC;IACtB,iCAAiC,EAAE,CACjC,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,wBAAgB,oCAAoC,IAAI,uBAAuB,CA0C9E;AAiPD,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,uBAAuB,GACpC,OAAO,CAAC,OAAO,CAAC,CA2DlB;AAED,wBAAgB,wBAAwB,CACtC,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CAwCT"}
|
|
@@ -7,7 +7,7 @@ import { DEFAULT_SYNC_CONFIG, loadSyncConfig, } from '../../../config/sync-confi
|
|
|
7
7
|
import { classifyObsoleteMappingRetirement, } from '../../../engine/index.js';
|
|
8
8
|
import { dirExists, fileExists } from '../../../fs/io.js';
|
|
9
9
|
import { resolveProjectRoot, resolveScopeRoot, toPosixPath } from '../../../fs/paths.js';
|
|
10
|
-
import { loadManifest, removeEntry, saveManifest, } from '../../../manifest/index.js';
|
|
10
|
+
import { detectManifestVersionRestamp, formatManifestVersionRestampWarning, loadManifest, removeEntry, saveManifest, } from '../../../manifest/index.js';
|
|
11
11
|
import { claudeAdapter } from '../../../providers/claude/index.js';
|
|
12
12
|
import { codexAdapter } from '../../../providers/codex/index.js';
|
|
13
13
|
import { copilotAdapter } from '../../../providers/copilot/index.js';
|
|
@@ -179,6 +179,7 @@ async function buildScopePlan(scope, scopeRoot, skillName, dependencies) {
|
|
|
179
179
|
managedProviderViews: dedupeViews(managedProviderViews),
|
|
180
180
|
unmanagedProviderViews: dedupeViews(unmanagedProviderViews),
|
|
181
181
|
manifestProvidersToRemove: [...manifestProvidersToRemove],
|
|
182
|
+
versionRestamp: detectManifestVersionRestamp(scope, manifest),
|
|
182
183
|
};
|
|
183
184
|
}
|
|
184
185
|
function logDryRun(context, plan) {
|
|
@@ -217,6 +218,9 @@ async function applyPlan(context, plan, dependencies) {
|
|
|
217
218
|
for (const provider of plan.manifestProvidersToRemove) {
|
|
218
219
|
nextManifest = removeEntry(nextManifest, plan.canonicalRelativePath, provider);
|
|
219
220
|
}
|
|
221
|
+
if (plan.versionRestamp && !context.json) {
|
|
222
|
+
context.logger.warn(formatManifestVersionRestampWarning('remove skill', plan.versionRestamp));
|
|
223
|
+
}
|
|
220
224
|
await dependencies.saveManifest(plan.manifestPath, nextManifest);
|
|
221
225
|
context.logger.info(`[apply][${plan.scope}] removed ${plan.canonicalRelativePath}`);
|
|
222
226
|
if (plan.unmanagedProviderViews.length > 0) {
|
|
@@ -267,6 +271,11 @@ export async function runRemoveSkill(context, skillName, dryRun, dependencies) {
|
|
|
267
271
|
status: 'removed',
|
|
268
272
|
skill: skillName,
|
|
269
273
|
scopes: toJsonScopeResults(plans),
|
|
274
|
+
// Applied restamps only. The dry-run payload deliberately omits this
|
|
275
|
+
// field rather than naming a restamp that no save will perform.
|
|
276
|
+
manifestVersionRestamps: plans
|
|
277
|
+
.map((plan) => plan.versionRestamp)
|
|
278
|
+
.filter((restamp) => restamp !== undefined),
|
|
270
279
|
});
|
|
271
280
|
}
|
|
272
281
|
return true;
|
|
@@ -1,12 +1,43 @@
|
|
|
1
1
|
export declare const PROJECT_STATE_KINDS: readonly ['implementation', 'coordination'];
|
|
2
2
|
export declare const PROJECT_STATE_PHASES: readonly ['discovery', 'spec', 'design', 'plan', 'implement', 'decomposition'];
|
|
3
|
-
export declare const PROJECT_STATE_FRONTMATTER_FIELDS: readonly ['oat_kind', 'oat_parent', 'oat_siblings', 'oat_depends_on', 'oat_children', 'oat_inherited_context_revalidated', 'oat_phase', 'oat_phase_status', 'oat_status', 'oat_workflow_mode', 'oat_lifecycle', 'oat_current_task', 'oat_last_commit', 'oat_blockers', 'oat_hill_checkpoints', 'oat_hill_completed', 'oat_parallel_execution', 'oat_implement_exit_gate', 'oat_pr_status', 'oat_pr_url', 'oat_project_created', 'oat_project_completed', 'oat_project_state_updated', 'oat_docs_updated', 'oat_generated', 'oat_template', 'oat_template_name'];
|
|
3
|
+
export declare const PROJECT_STATE_FRONTMATTER_FIELDS: readonly ['oat_kind', 'oat_parent', 'oat_siblings', 'oat_depends_on', 'oat_children', 'oat_inherited_context_revalidated', 'oat_phase', 'oat_phase_status', 'oat_status', 'oat_workflow_mode', 'oat_lifecycle', 'oat_current_task', 'oat_last_commit', 'oat_blockers', 'oat_hill_checkpoints', 'oat_hill_completed', 'oat_parallel_execution', 'oat_implement_exit_gate', 'oat_skill_gate_overrides', 'oat_pr_status', 'oat_pr_url', 'oat_project_created', 'oat_project_completed', 'oat_project_state_updated', 'oat_docs_updated', 'oat_generated', 'oat_template', 'oat_template_name'];
|
|
4
4
|
export type ProjectStateKind = (typeof PROJECT_STATE_KINDS)[number];
|
|
5
5
|
export type ProjectStatePhase = (typeof PROJECT_STATE_PHASES)[number];
|
|
6
6
|
export type ProjectStateFrontmatterField = (typeof PROJECT_STATE_FRONTMATTER_FIELDS)[number];
|
|
7
7
|
export declare function isProjectStateKind(value: string): value is ProjectStateKind;
|
|
8
8
|
export declare function isProjectStatePhase(value: string): value is ProjectStatePhase;
|
|
9
9
|
export declare function isProjectStateFrontmatterField(value: string): value is ProjectStateFrontmatterField;
|
|
10
|
+
export declare const SKILL_GATE_OVERRIDE_FIELD = "oat_skill_gate_overrides";
|
|
11
|
+
export declare const SKILL_GATE_OVERRIDE_DISABLED = "disabled";
|
|
12
|
+
export declare const SKILL_GATE_OVERRIDE_SOURCE = "state.md:oat_skill_gate_overrides";
|
|
13
|
+
/**
|
|
14
|
+
* Canonical gate-aware lifecycle skills: exactly the skills declaring
|
|
15
|
+
* `oat_gateable: true` in their frontmatter, which is the only set a project
|
|
16
|
+
* override may target. An override key outside this set can never disable
|
|
17
|
+
* anything, so accepting one would silently record an inert instruction.
|
|
18
|
+
*
|
|
19
|
+
* This set does not bound which skills a configured gate may target. Gate
|
|
20
|
+
* resolution performs the same config lookup for any skill name, so a
|
|
21
|
+
* configured gate on a non-gate-aware skill still resolves and executes; it
|
|
22
|
+
* simply applies to every project because no override key for it is accepted.
|
|
23
|
+
*
|
|
24
|
+
* `skills.test.ts` pins this constant against the live `oat_gateable: true`
|
|
25
|
+
* declarations so the two cannot drift apart.
|
|
26
|
+
*/
|
|
27
|
+
export declare const GATE_AWARE_SKILLS: readonly ['oat-project-implement', 'oat-project-import-plan', 'oat-project-plan', 'oat-project-quick-start'];
|
|
28
|
+
export type SkillGateOverrideValue = typeof SKILL_GATE_OVERRIDE_DISABLED;
|
|
29
|
+
export interface ProjectSkillGateOverrides {
|
|
30
|
+
/** False when the key is absent entirely: absence means follow configuration. */
|
|
31
|
+
present: boolean;
|
|
32
|
+
overrides: Record<string, SkillGateOverrideValue>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Strict parser for the per-project gate override map.
|
|
36
|
+
*
|
|
37
|
+
* Absence is not an error and never fabricates configuration. Every rejection
|
|
38
|
+
* names the offending project state path so the operator can repair it.
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseSkillGateOverrides(frontmatter: string, statePath: string): ProjectSkillGateOverrides;
|
|
10
41
|
export declare function getFrontmatterBlock(content: string): string | null;
|
|
11
42
|
export declare function getFrontmatterField(frontmatter: string, field: string): string | null;
|
|
12
43
|
export declare function parseFrontmatterScalarFields(frontmatter: string, fields: readonly string[]): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/frontmatter.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,mBAAmB,YAAI,gBAAgB,EAAE,cAAc,CAAU,CAAC;AAE/E,eAAO,MAAM,oBAAoB,YAC/B,WAAW,EACX,MAAM,EACN,QAAQ,EACR,MAAM,EACN,WAAW,EACX,eAAe,CACP,CAAC;AAEX,eAAO,MAAM,gCAAgC,YAC3C,UAAU,EACV,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,mCAAmC,EACnC,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,mBAAmB,CACX,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AACtE,MAAM,MAAM,4BAA4B,GACtC,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAE3E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,iBAAiB,CAE7E;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,MAAM,GACZ,KAAK,IAAI,4BAA4B,CAIvC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGlE;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CA4BpD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB"}
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/frontmatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,7 @@ export const PROJECT_STATE_FRONTMATTER_FIELDS = [
|
|
|
29
29
|
'oat_hill_completed',
|
|
30
30
|
'oat_parallel_execution',
|
|
31
31
|
'oat_implement_exit_gate',
|
|
32
|
+
'oat_skill_gate_overrides',
|
|
32
33
|
'oat_pr_status',
|
|
33
34
|
'oat_pr_url',
|
|
34
35
|
'oat_project_created',
|
|
@@ -48,6 +49,97 @@ export function isProjectStatePhase(value) {
|
|
|
48
49
|
export function isProjectStateFrontmatterField(value) {
|
|
49
50
|
return PROJECT_STATE_FRONTMATTER_FIELDS.includes(value);
|
|
50
51
|
}
|
|
52
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
53
|
+
export const SKILL_GATE_OVERRIDE_FIELD = 'oat_skill_gate_overrides';
|
|
54
|
+
export const SKILL_GATE_OVERRIDE_DISABLED = 'disabled';
|
|
55
|
+
export const SKILL_GATE_OVERRIDE_SOURCE = `state.md:${SKILL_GATE_OVERRIDE_FIELD}`;
|
|
56
|
+
/**
|
|
57
|
+
* Canonical gate-aware lifecycle skills: exactly the skills declaring
|
|
58
|
+
* `oat_gateable: true` in their frontmatter, which is the only set a project
|
|
59
|
+
* override may target. An override key outside this set can never disable
|
|
60
|
+
* anything, so accepting one would silently record an inert instruction.
|
|
61
|
+
*
|
|
62
|
+
* This set does not bound which skills a configured gate may target. Gate
|
|
63
|
+
* resolution performs the same config lookup for any skill name, so a
|
|
64
|
+
* configured gate on a non-gate-aware skill still resolves and executes; it
|
|
65
|
+
* simply applies to every project because no override key for it is accepted.
|
|
66
|
+
*
|
|
67
|
+
* `skills.test.ts` pins this constant against the live `oat_gateable: true`
|
|
68
|
+
* declarations so the two cannot drift apart.
|
|
69
|
+
*/
|
|
70
|
+
export const GATE_AWARE_SKILLS = [
|
|
71
|
+
'oat-project-implement',
|
|
72
|
+
'oat-project-import-plan',
|
|
73
|
+
'oat-project-plan',
|
|
74
|
+
'oat-project-quick-start',
|
|
75
|
+
];
|
|
76
|
+
function skillGateOverrideError(statePath, detail) {
|
|
77
|
+
return new Error(`${statePath}: \`${SKILL_GATE_OVERRIDE_FIELD}\` ${detail}. Use a map of gate-aware skill names to the literal value \`${SKILL_GATE_OVERRIDE_DISABLED}\`, or remove the key to follow configured gates.`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Strict parser for the per-project gate override map.
|
|
81
|
+
*
|
|
82
|
+
* Absence is not an error and never fabricates configuration. Every rejection
|
|
83
|
+
* names the offending project state path so the operator can repair it.
|
|
84
|
+
*/
|
|
85
|
+
export function parseSkillGateOverrides(frontmatter, statePath) {
|
|
86
|
+
const document = YAML.parseDocument(frontmatter, { uniqueKeys: true });
|
|
87
|
+
if (document.errors.length > 0) {
|
|
88
|
+
throw skillGateOverrideError(statePath, `cannot be read because the frontmatter is malformed (${document.errors[0]?.message ?? 'YAML parse error'})`);
|
|
89
|
+
}
|
|
90
|
+
// A scalar or sequence root is malformed project state, not "no overrides":
|
|
91
|
+
// returning an empty map here would silently launch a disabled gate.
|
|
92
|
+
if (!isMap(document.contents)) {
|
|
93
|
+
throw skillGateOverrideError(statePath, 'cannot be read because the frontmatter root is not a YAML map');
|
|
94
|
+
}
|
|
95
|
+
const matches = document.contents.items.filter((pair) => isScalar(pair.key) && pair.key.value === SKILL_GATE_OVERRIDE_FIELD);
|
|
96
|
+
if (matches.length === 0) {
|
|
97
|
+
return { present: false, overrides: {} };
|
|
98
|
+
}
|
|
99
|
+
// `uniqueKeys` already rejects a duplicate top-level key above; this stays as
|
|
100
|
+
// a fail-closed guard rather than silently reading the first of several.
|
|
101
|
+
if (matches.length > 1) {
|
|
102
|
+
throw skillGateOverrideError(statePath, 'is declared more than once');
|
|
103
|
+
}
|
|
104
|
+
const value = matches[0]?.value;
|
|
105
|
+
// An explicitly null or empty map is a deliberate "no overrides" statement.
|
|
106
|
+
if (value === null || (isScalar(value) && value.value === null)) {
|
|
107
|
+
return { present: true, overrides: {} };
|
|
108
|
+
}
|
|
109
|
+
if (!isMap(value)) {
|
|
110
|
+
throw skillGateOverrideError(statePath, 'must be a map of skill names to `disabled`');
|
|
111
|
+
}
|
|
112
|
+
const overrides = {};
|
|
113
|
+
for (const pair of value.items) {
|
|
114
|
+
if (!isScalar(pair.key) || typeof pair.key.value !== 'string') {
|
|
115
|
+
throw skillGateOverrideError(statePath, 'has a non-string skill key');
|
|
116
|
+
}
|
|
117
|
+
// Exact spelling only: a padded or decorated key is not the skill name.
|
|
118
|
+
const skill = pair.key.value;
|
|
119
|
+
if (!skill) {
|
|
120
|
+
throw skillGateOverrideError(statePath, 'has an empty skill key');
|
|
121
|
+
}
|
|
122
|
+
if (pair.key.anchor !== undefined || pair.key.tag !== undefined) {
|
|
123
|
+
throw skillGateOverrideError(statePath, `decorates the key \`${skill}\` with a YAML anchor or tag`);
|
|
124
|
+
}
|
|
125
|
+
if (!GATE_AWARE_SKILLS.includes(skill)) {
|
|
126
|
+
throw skillGateOverrideError(statePath, `names \`${skill}\`, which is not a gate-aware skill`);
|
|
127
|
+
}
|
|
128
|
+
if (hasOwnProperty.call(overrides, skill)) {
|
|
129
|
+
throw skillGateOverrideError(statePath, `declares \`${skill}\` more than once`);
|
|
130
|
+
}
|
|
131
|
+
const entry = pair.value;
|
|
132
|
+
if (!isScalar(entry) ||
|
|
133
|
+
entry.anchor !== undefined ||
|
|
134
|
+
entry.tag !== undefined ||
|
|
135
|
+
typeof entry.value !== 'string' ||
|
|
136
|
+
entry.value !== SKILL_GATE_OVERRIDE_DISABLED) {
|
|
137
|
+
throw skillGateOverrideError(statePath, `sets \`${skill}\` to an unsupported value`);
|
|
138
|
+
}
|
|
139
|
+
overrides[skill] = SKILL_GATE_OVERRIDE_DISABLED;
|
|
140
|
+
}
|
|
141
|
+
return { present: true, overrides };
|
|
142
|
+
}
|
|
51
143
|
export function getFrontmatterBlock(content) {
|
|
52
144
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
53
145
|
return match?.[1] ?? null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC/B,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,KAAK,cAAc,EAIpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAWzC,OAAO,EAIL,KAAK,kBAAkB,EAEvB,KAAK,aAAa,EAEnB,MAAM,uCAAuC,CAAC;AAU/C,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAIjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,+BAA+B,EAIrC,MAAM,eAAe,CAAC;AAOvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"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"}
|