@deftai/directive-core 0.65.0 → 0.66.1
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/dist/architecture/sor-preflight.js +6 -4
- package/dist/capacity/backfill.js +5 -3
- package/dist/capacity/show.js +5 -3
- package/dist/category-b-namespace/index.d.ts +39 -0
- package/dist/category-b-namespace/index.js +120 -0
- package/dist/codebase/default-extractor.js +2 -1
- package/dist/codebase/map.js +2 -1
- package/dist/codebase/provider.js +4 -2
- package/dist/content-contracts/standards/_helpers.js +1 -1
- package/dist/doctor/checks.js +2 -1
- package/dist/doctor/doctor-state.js +2 -2
- package/dist/encoding/patterns.js +19 -0
- package/dist/encoding/scan.js +3 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/init-deposit/refresh.js +2 -1
- package/dist/init-deposit/scaffold.js +2 -1
- package/dist/install-upgrade/index.d.ts +2 -0
- package/dist/install-upgrade/index.js +31 -2
- package/dist/intake/issue-emit.d.ts +1 -1
- package/dist/intake/issue-emit.js +3 -2
- package/dist/intake/issue-ingest.d.ts +24 -0
- package/dist/intake/issue-ingest.js +113 -16
- package/dist/intake/reconcile-issues.js +11 -4
- package/dist/layout/index.d.ts +2 -0
- package/dist/layout/index.js +2 -0
- package/dist/layout/resolve.d.ts +87 -0
- package/dist/layout/resolve.js +159 -0
- package/dist/lifecycle/lifecycle-hygiene.d.ts +1 -1
- package/dist/lifecycle/lifecycle-hygiene.js +8 -5
- package/dist/orchestration/judgment-policy.js +4 -6
- package/dist/orchestration/verify-judgment-gates.d.ts +1 -0
- package/dist/orchestration/verify-judgment-gates.js +4 -2
- package/dist/policy/autonomy.js +4 -6
- package/dist/policy/capacity.js +4 -6
- package/dist/policy/decisions.d.ts +1 -0
- package/dist/policy/decisions.js +4 -2
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.js +3 -1
- package/dist/policy/plan-extensions.d.ts +35 -0
- package/dist/policy/plan-extensions.js +57 -0
- package/dist/policy/resolve.d.ts +6 -2
- package/dist/policy/resolve.js +18 -8
- package/dist/policy/wip.js +6 -4
- package/dist/preflight-cache/evaluate.js +8 -5
- package/dist/release/native-steps.js +4 -3
- package/dist/render/framework-commands.js +2 -1
- package/dist/render/prd-render.js +2 -2
- package/dist/render/project-render.js +23 -5
- package/dist/render/roadmap-render.js +36 -8
- package/dist/render/scope-outlook.js +3 -2
- package/dist/scope/audit-log.js +3 -2
- package/dist/scope/capacity-stamp.js +2 -1
- package/dist/scope/decompose.js +6 -4
- package/dist/scope/decomposed-refs.js +2 -1
- package/dist/scope/demote.js +5 -4
- package/dist/scope/project-context.js +2 -1
- package/dist/scope/project-definition-sync.js +4 -3
- package/dist/scope/transition.js +6 -2
- package/dist/scope/undo.js +2 -1
- package/dist/scope/vbrief-ref.js +5 -3
- package/dist/session/resume-conditions.js +2 -1
- package/dist/session/ritual-sentinel.js +2 -1
- package/dist/session/staleness.js +2 -1
- package/dist/slice/record.js +4 -4
- package/dist/spec-authority/resolver.js +5 -5
- package/dist/swarm/complete-cohort.js +5 -4
- package/dist/swarm/launch.js +6 -7
- package/dist/swarm/readiness.js +22 -20
- package/dist/swarm/subagent-backend.js +2 -5
- package/dist/swarm/verify-review-clean.js +2 -1
- package/dist/triage/actions/candidates-log.d.ts +3 -0
- package/dist/triage/actions/candidates-log.js +8 -2
- package/dist/triage/bootstrap/gitignore.js +22 -13
- package/dist/triage/bootstrap/index.js +7 -4
- package/dist/triage/bulk/index.js +2 -1
- package/dist/triage/classify/index.js +13 -11
- package/dist/triage/queue/audit.js +3 -3
- package/dist/triage/queue/cache.js +3 -2
- package/dist/triage/queue/ranking-labels.js +2 -1
- package/dist/triage/queue/scope-walk.js +8 -6
- package/dist/triage/reconcile/audit.js +2 -1
- package/dist/triage/reconcile/parse-uri.js +2 -1
- package/dist/triage/reconcile/reconcile.js +8 -7
- package/dist/triage/refresh/extract.js +4 -2
- package/dist/triage/refresh/refresh.js +3 -2
- package/dist/triage/scope/mutations-core.js +13 -9
- package/dist/triage/scope/renderers.js +5 -3
- package/dist/triage/scope/resolve.js +6 -5
- package/dist/triage/scope/validate.js +3 -6
- package/dist/triage/scope-drift/add-ignore.js +4 -2
- package/dist/triage/scope-drift/scope-rules.js +3 -2
- package/dist/triage/subscribe/index.js +13 -7
- package/dist/triage/summary/index.js +7 -5
- package/dist/triage/summary/reconcilable.js +6 -4
- package/dist/triage/summary/scope-drift.js +2 -1
- package/dist/triage/welcome/prior-state.js +9 -9
- package/dist/triage/welcome/summary.js +9 -8
- package/dist/triage/welcome/writers.js +12 -10
- package/dist/validate-content/capacity-policy.js +5 -4
- package/dist/validate-content/capacity-show.js +5 -3
- package/dist/validate-content/filename.d.ts +1 -1
- package/dist/validate-content/filename.js +5 -4
- package/dist/validate-content/validate-strategy-output.js +14 -5
- package/dist/vbrief-build/build.js +1 -1
- package/dist/vbrief-build/constants.js +7 -0
- package/dist/vbrief-build/speckit.js +3 -2
- package/dist/vbrief-reconcile/graph.js +3 -2
- package/dist/vbrief-reconcile/labels.js +4 -3
- package/dist/vbrief-reconcile/reconciliation.js +5 -1
- package/dist/vbrief-reconcile/swarm-deps.js +6 -5
- package/dist/vbrief-reconcile/umbrellas.d.ts +1 -1
- package/dist/vbrief-reconcile/umbrellas.js +9 -7
- package/dist/vbrief-validate/conformance.d.ts +1 -2
- package/dist/vbrief-validate/conformance.js +29 -14
- package/dist/vbrief-validate/constants.d.ts +18 -1
- package/dist/vbrief-validate/constants.js +32 -3
- package/dist/vbrief-validate/epic-links.js +3 -2
- package/dist/vbrief-validate/filename.js +5 -3
- package/dist/vbrief-validate/index.d.ts +3 -1
- package/dist/vbrief-validate/index.js +2 -1
- package/dist/vbrief-validate/main.js +17 -6
- package/dist/vbrief-validate/origin.js +1 -1
- package/dist/vbrief-validate/paths.js +2 -1
- package/dist/vbrief-validate/plan-hooks.js +4 -3
- package/dist/vbrief-validate/registry-status.d.ts +1 -0
- package/dist/vbrief-validate/registry-status.js +3 -1
- package/dist/vbrief-validate/roundtrip.d.ts +36 -0
- package/dist/vbrief-validate/roundtrip.js +168 -0
- package/dist/vbrief-validate/schema.d.ts +1 -1
- package/dist/vbrief-validate/schema.js +62 -19
- package/dist/vbrief-validate/validate-all.js +12 -4
- package/dist/verify-source/code-structure-validate.js +8 -4
- package/dist/verify-source/contract-drift.d.ts +7 -3
- package/dist/verify-source/contract-drift.js +40 -22
- package/dist/xbrief-migrate/constants.d.ts +13 -0
- package/dist/xbrief-migrate/constants.js +14 -0
- package/dist/xbrief-migrate/detect.d.ts +11 -0
- package/dist/xbrief-migrate/detect.js +81 -0
- package/dist/xbrief-migrate/drift-gate.d.ts +56 -0
- package/dist/xbrief-migrate/drift-gate.js +205 -0
- package/dist/xbrief-migrate/index.d.ts +7 -0
- package/dist/xbrief-migrate/index.js +7 -0
- package/dist/xbrief-migrate/migrate-project.d.ts +33 -0
- package/dist/xbrief-migrate/migrate-project.js +189 -0
- package/dist/xbrief-migrate/signpost.d.ts +5 -0
- package/dist/xbrief-migrate/signpost.js +19 -0
- package/dist/xbrief-migrate/transforms.d.ts +46 -0
- package/dist/xbrief-migrate/transforms.js +182 -0
- package/dist/xbrief-migrate/version.d.ts +8 -0
- package/dist/xbrief-migrate/version.js +25 -0
- package/package.json +11 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import { readPlanPolicy } from "../policy/plan-extensions.js";
|
|
3
4
|
import { PROJECT_DEFINITION_REL_PATH } from "../policy/resolve.js";
|
|
4
5
|
function resolveDefaultCapacityBucket(projectRoot) {
|
|
5
6
|
try {
|
|
@@ -10,7 +11,7 @@ function resolveDefaultCapacityBucket(projectRoot) {
|
|
|
10
11
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
11
12
|
return "";
|
|
12
13
|
}
|
|
13
|
-
const policy = plan
|
|
14
|
+
const policy = readPlanPolicy(plan);
|
|
14
15
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
15
16
|
return "";
|
|
16
17
|
}
|
package/dist/scope/decompose.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { accessSync, constants, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
11
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
12
|
+
import { hasArtifactSuffix, resolveLifecycleRoot } from "../layout/resolve.js";
|
|
11
13
|
import { referenceWithDefaultTrust, slugify } from "../vbrief-build/build.js";
|
|
12
14
|
import { EMITTED_VBRIEF_VERSION } from "../vbrief-build/constants.js";
|
|
13
15
|
import { formatVbriefJson } from "./vbrief-json.js";
|
|
@@ -398,7 +400,7 @@ export function storyQualityIssues(opts) {
|
|
|
398
400
|
// Path helpers
|
|
399
401
|
// ---------------------------------------------------------------------------
|
|
400
402
|
function vbriefDir(projectRoot) {
|
|
401
|
-
return
|
|
403
|
+
return resolveLifecycleRoot(projectRoot);
|
|
402
404
|
}
|
|
403
405
|
function relToVbrief(vbriefDirPath, path) {
|
|
404
406
|
const resolvedPath = resolve(path);
|
|
@@ -507,7 +509,7 @@ function storyHasTraces(story, items, sw) {
|
|
|
507
509
|
if (Array.isArray(refs)) {
|
|
508
510
|
for (const ref of refs) {
|
|
509
511
|
if (typeof ref === "object" && ref !== null && !Array.isArray(ref)) {
|
|
510
|
-
if (ref.type
|
|
512
|
+
if (referenceTypeMatches(String(ref.type ?? ""), "spec-section"))
|
|
511
513
|
return true;
|
|
512
514
|
}
|
|
513
515
|
}
|
|
@@ -752,7 +754,7 @@ function storyNarratives(story) {
|
|
|
752
754
|
}
|
|
753
755
|
function childFilename(story, stId, title, date) {
|
|
754
756
|
const fn = story.filename;
|
|
755
|
-
if (typeof fn === "string" && fn
|
|
757
|
+
if (typeof fn === "string" && hasArtifactSuffix(fn))
|
|
756
758
|
return fn;
|
|
757
759
|
const sl = slugify(title) || slugify(stId) || "story";
|
|
758
760
|
return `${date}-${sl}.vbrief.json`;
|
|
@@ -891,7 +893,7 @@ export function applyDecomposition(opts) {
|
|
|
891
893
|
for (const { target, title } of childPaths) {
|
|
892
894
|
references.push(referenceWithDefaultTrust({
|
|
893
895
|
uri: relToVbrief(vbriefDirPath, target),
|
|
894
|
-
type: "x-
|
|
896
|
+
type: "x-xbrief/plan",
|
|
895
897
|
title,
|
|
896
898
|
}));
|
|
897
899
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, relative, resolve } from "node:path";
|
|
3
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
3
4
|
import { formatVbriefJson } from "./vbrief-json.js";
|
|
4
5
|
import { collectChildUris, collectPlanRefs, resolveVbriefRef } from "./vbrief-ref.js";
|
|
5
6
|
function rewriteOnePlanRef(value, oldParentResolved, newParentRel, vbriefDir) {
|
|
@@ -36,7 +37,7 @@ function rewriteParentChildReference(parentPath, oldChildResolved, newChildRel,
|
|
|
36
37
|
continue;
|
|
37
38
|
}
|
|
38
39
|
const r = ref;
|
|
39
|
-
if (r.type
|
|
40
|
+
if (!referenceTypeMatches(String(r.type ?? ""), "plan")) {
|
|
40
41
|
continue;
|
|
41
42
|
}
|
|
42
43
|
const resolved = resolveVbriefRef(r.uri, vbriefDir);
|
package/dist/scope/demote.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
3
|
+
import { hasArtifactSuffix, resolveLifecycleFolder } from "../layout/resolve.js";
|
|
3
4
|
import { stripTrailingPathSeparators } from "../text/redos-safe.js";
|
|
4
5
|
import { append, canonicalLogPath, latestForPath, newDecisionId } from "./audit-log.js";
|
|
5
6
|
import { resolveProjectRoot } from "./project-context.js";
|
|
@@ -35,10 +36,10 @@ export function demoteOne(filePath, projectRoot, reason, options = {}) {
|
|
|
35
36
|
return { ok: false, message: `File not found: ${resolved}`, auditEntry: null };
|
|
36
37
|
}
|
|
37
38
|
const basename = resolved.split(/[/\\]/).pop() ?? "";
|
|
38
|
-
if (!basename
|
|
39
|
+
if (!hasArtifactSuffix(basename)) {
|
|
39
40
|
return {
|
|
40
41
|
ok: false,
|
|
41
|
-
message: `Not a vBRIEF file (expected .vbrief.json): ${basename}`,
|
|
42
|
+
message: `Not a vBRIEF file (expected .vbrief.json or .xbrief.json): ${basename}`,
|
|
42
43
|
auditEntry: null,
|
|
43
44
|
};
|
|
44
45
|
}
|
|
@@ -114,7 +115,7 @@ export function batchDemote(projectRoot, olderThanDays, options = {}) {
|
|
|
114
115
|
throw new Error(`--older-than-days must be >= 0, got ${olderThanDays}`);
|
|
115
116
|
}
|
|
116
117
|
const now = options.now ?? new Date();
|
|
117
|
-
const pendingDir =
|
|
118
|
+
const pendingDir = resolveLifecycleFolder(projectRoot, SOURCE_FOLDER);
|
|
118
119
|
if (!existsSync(pendingDir)) {
|
|
119
120
|
return [0, [], []];
|
|
120
121
|
}
|
|
@@ -124,7 +125,7 @@ export function batchDemote(projectRoot, olderThanDays, options = {}) {
|
|
|
124
125
|
const skipped = [];
|
|
125
126
|
let demoted = 0;
|
|
126
127
|
const files = readdirSync(pendingDir)
|
|
127
|
-
.filter((name) => name
|
|
128
|
+
.filter((name) => hasArtifactSuffix(name))
|
|
128
129
|
.sort();
|
|
129
130
|
for (const name of files) {
|
|
130
131
|
const candidate = join(pendingDir, name);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, statSync } from "node:fs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
|
-
|
|
3
|
+
// Layout-aware (#2109 part 1): an xbrief-only tree is also a valid project root.
|
|
4
|
+
const PROJECT_ROOT_SENTINELS = ["xbrief", "vbrief", ".git"];
|
|
4
5
|
function isProjectRoot(candidate) {
|
|
5
6
|
return PROJECT_ROOT_SENTINELS.some((sentinel) => existsSync(join(candidate, sentinel)));
|
|
6
7
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
3
4
|
import { PROJECT_DEFINITION_REL_PATH } from "../policy/resolve.js";
|
|
4
5
|
import { formatVbriefJson } from "./vbrief-json.js";
|
|
5
6
|
import { relativeToVbrief, resolveVbriefRef, scopeIdsForFilename } from "./vbrief-ref.js";
|
|
@@ -8,7 +9,7 @@ function rewriteProjectDefinitionPlanReference(ref, oldResolved, newRel, vbriefR
|
|
|
8
9
|
return false;
|
|
9
10
|
}
|
|
10
11
|
const r = ref;
|
|
11
|
-
if (r.type
|
|
12
|
+
if (!referenceTypeMatches(String(r.type ?? ""), "plan")) {
|
|
12
13
|
return false;
|
|
13
14
|
}
|
|
14
15
|
const resolved = resolveVbriefRef(r.uri, vbriefRoot);
|
|
@@ -41,7 +42,7 @@ function projectItemReferencesScope(item, oldResolved, newResolved, vbriefRoot)
|
|
|
41
42
|
continue;
|
|
42
43
|
}
|
|
43
44
|
const r = ref;
|
|
44
|
-
if (r.type
|
|
45
|
+
if (!referenceTypeMatches(String(r.type ?? ""), "plan")) {
|
|
45
46
|
continue;
|
|
46
47
|
}
|
|
47
48
|
const resolved = resolveVbriefRef(r.uri, vbriefRoot);
|
|
@@ -58,7 +59,7 @@ function projectItemReferencesScope(item, oldResolved, newResolved, vbriefRoot)
|
|
|
58
59
|
continue;
|
|
59
60
|
}
|
|
60
61
|
const r = ref;
|
|
61
|
-
if (r.type
|
|
62
|
+
if (!referenceTypeMatches(String(r.type ?? ""), "plan")) {
|
|
62
63
|
continue;
|
|
63
64
|
}
|
|
64
65
|
const resolved = resolveVbriefRef(r.uri, vbriefRoot);
|
package/dist/scope/transition.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { hasArtifactSuffix } from "../layout/resolve.js";
|
|
3
4
|
import { append, canonicalLogPath, newDecisionId } from "./audit-log.js";
|
|
4
5
|
import { stampCompletionMetadata } from "./capacity-stamp.js";
|
|
5
6
|
import { LIFECYCLE_FOLDERS, MOVE_LABELS, STATUS_PRECONDITIONS, STAY_LABELS, TRANSITIONS, } from "./constants.js";
|
|
@@ -17,8 +18,11 @@ export function runTransition(action, filePath, now = new Date()) {
|
|
|
17
18
|
return { ok: false, message: `File not found: ${resolvedPath}` };
|
|
18
19
|
}
|
|
19
20
|
const basename = resolvedPath.split(/[/\\]/).pop() ?? "";
|
|
20
|
-
if (!basename
|
|
21
|
-
return {
|
|
21
|
+
if (!hasArtifactSuffix(basename)) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
message: `Not a vBRIEF file (expected .vbrief.json or .xbrief.json): ${basename}`,
|
|
25
|
+
};
|
|
22
26
|
}
|
|
23
27
|
const currentFolder = detectLifecycleFolder(resolvedPath);
|
|
24
28
|
if (currentFolder === null) {
|
package/dist/scope/undo.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, join, relative, resolve } from "node:path";
|
|
3
|
+
import { resolveLifecycleRoot } from "../layout/resolve.js";
|
|
3
4
|
import { append, canonicalLogPath, newDecisionId, readAll } from "./audit-log.js";
|
|
4
5
|
import { REVERSIBLE_ACTIONS, TERMINAL_ACTIONS } from "./constants.js";
|
|
5
6
|
import { formatVbriefJson, utcNowIso } from "./vbrief-json.js";
|
|
6
7
|
function vbriefRoot(projectRoot) {
|
|
7
|
-
return
|
|
8
|
+
return resolveLifecycleRoot(projectRoot);
|
|
8
9
|
}
|
|
9
10
|
function absForEntryPath(projectRoot, vbriefPath) {
|
|
10
11
|
return resolve(projectRoot, vbriefPath);
|
package/dist/scope/vbrief-ref.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
3
|
+
import { hasArtifactSuffix, stripArtifactSuffix } from "../layout/resolve.js";
|
|
2
4
|
/** Resolve a vBRIEF reference URI to an absolute path, or null. */
|
|
3
5
|
export function resolveVbriefRef(uri, vbriefDir) {
|
|
4
6
|
if (typeof uri !== "string" || uri.length === 0) {
|
|
@@ -48,7 +50,7 @@ export function collectChildUris(plan) {
|
|
|
48
50
|
continue;
|
|
49
51
|
}
|
|
50
52
|
const r = ref;
|
|
51
|
-
if (r.type
|
|
53
|
+
if (!referenceTypeMatches(String(r.type ?? ""), "plan")) {
|
|
52
54
|
continue;
|
|
53
55
|
}
|
|
54
56
|
const uri = r.uri;
|
|
@@ -61,8 +63,8 @@ export function collectChildUris(plan) {
|
|
|
61
63
|
/** Return registry IDs that may name a vBRIEF filename. */
|
|
62
64
|
export function scopeIdsForFilename(filename) {
|
|
63
65
|
let fullId;
|
|
64
|
-
if (filename
|
|
65
|
-
fullId = filename
|
|
66
|
+
if (hasArtifactSuffix(filename)) {
|
|
67
|
+
fullId = stripArtifactSuffix(filename);
|
|
66
68
|
}
|
|
67
69
|
else {
|
|
68
70
|
fullId = filename.replace(/\.[^.]+$/, "");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
|
+
import { hasArtifactSuffix } from "../layout/resolve.js";
|
|
4
5
|
export const RESUME_ELIGIBLE_DECISION = "resume-eligible";
|
|
5
6
|
export const EVALUATOR_ACTOR = "agent:resume-evaluator";
|
|
6
7
|
export const CACHE_DIR_NAME = ".deft-cache";
|
|
@@ -270,7 +271,7 @@ function countPending(projectRoot) {
|
|
|
270
271
|
for (const name of readdirSync(folder)) {
|
|
271
272
|
const full = join(folder, name);
|
|
272
273
|
try {
|
|
273
|
-
if (statSync(full).isFile() && name
|
|
274
|
+
if (statSync(full).isFile() && hasArtifactSuffix(name)) {
|
|
274
275
|
count += 1;
|
|
275
276
|
}
|
|
276
277
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { closeSync, existsSync, fdatasyncSync, mkdirSync, openSync, readdirSync, readFileSync, renameSync, statSync, writeSync, } from "node:fs";
|
|
2
2
|
import { join, relative, resolve } from "node:path";
|
|
3
|
+
import { hasArtifactSuffix } from "../layout/resolve.js";
|
|
3
4
|
import { stableJson } from "./json.js";
|
|
4
5
|
import { parseTimestamp, timestampIso } from "./time.js";
|
|
5
6
|
export const SCHEMA_VERSION = 1;
|
|
@@ -307,7 +308,7 @@ export function detectLatestActiveVbrief(projectRoot) {
|
|
|
307
308
|
}
|
|
308
309
|
const candidates = [];
|
|
309
310
|
for (const name of children) {
|
|
310
|
-
if (!name
|
|
311
|
+
if (!hasArtifactSuffix(name)) {
|
|
311
312
|
continue;
|
|
312
313
|
}
|
|
313
314
|
const full = join(activeDir, name);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readPlanPolicy } from "../policy/plan-extensions.js";
|
|
1
2
|
import { loadProjectDefinition } from "../policy/resolve.js";
|
|
2
3
|
const DEFAULT_SESSION_RITUAL_STALENESS_HOURS = 4;
|
|
3
4
|
function pythonTypeName(value) {
|
|
@@ -59,7 +60,7 @@ export function resolveSessionRitualStalenessHours(projectRoot) {
|
|
|
59
60
|
error: "PROJECT-DEFINITION 'plan' is not an object",
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
|
-
const policyBlock = plan
|
|
63
|
+
const policyBlock = readPlanPolicy(plan);
|
|
63
64
|
if (typeof policyBlock !== "object" ||
|
|
64
65
|
policyBlock === null ||
|
|
65
66
|
Array.isArray(policyBlock) ||
|
package/dist/slice/record.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { appendFileSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, } from "node:fs";
|
|
3
|
-
import { dirname,
|
|
4
|
-
import {
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { resolveEvalPath } from "../layout/resolve.js";
|
|
5
5
|
import { pythonJsonStringify } from "./json.js";
|
|
6
6
|
import { withAppendLock } from "./lock.js";
|
|
7
7
|
import { validateRecord } from "./validate.js";
|
|
@@ -16,7 +16,7 @@ const defaultDeps = {
|
|
|
16
16
|
withLock: withAppendLock,
|
|
17
17
|
};
|
|
18
18
|
function resolvePath(path) {
|
|
19
|
-
return path !== undefined ? resolve(path) :
|
|
19
|
+
return path !== undefined ? resolve(path) : resolveEvalPath(process.cwd(), "slices.jsonl");
|
|
20
20
|
}
|
|
21
21
|
export function newSliceId() {
|
|
22
22
|
return randomUUID();
|
|
@@ -134,6 +134,6 @@ export function findByUmbrella(umbrella, options = {}) {
|
|
|
134
134
|
return readAll(options).filter((record) => record.umbrella === umbrella);
|
|
135
135
|
}
|
|
136
136
|
export function slicesPath(projectRoot) {
|
|
137
|
-
return
|
|
137
|
+
return resolveEvalPath(projectRoot, "slices.jsonl");
|
|
138
138
|
}
|
|
139
139
|
//# sourceMappingURL=record.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { resolveLifecycleLayout, resolveLifecycleRoot, resolveProjectDefinitionPath, } from "../layout/resolve.js";
|
|
3
4
|
import { SPEC_RENDER_BANNER } from "../render/constants.js";
|
|
4
5
|
import { EXPORT_SPEC_PD_BANNER, GENERATED_SPEC_PURPOSE, GENERATED_SPEC_SOURCE_PD, GENERATED_SPEC_SOURCE_SPEC, } from "./constants.js";
|
|
5
|
-
const SPEC_REL = join("vbrief", "specification.vbrief.json");
|
|
6
|
-
const PD_REL = join("vbrief", "PROJECT-DEFINITION.vbrief.json");
|
|
7
6
|
export function resolveSpecAuthority(projectRoot) {
|
|
8
7
|
const root = projectRoot;
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const layout = resolveLifecycleLayout(root);
|
|
9
|
+
const vbriefDir = resolveLifecycleRoot(root);
|
|
10
|
+
const projectDefPath = resolveProjectDefinitionPath(root);
|
|
11
11
|
if (!existsSync(projectDefPath))
|
|
12
12
|
return null;
|
|
13
|
-
const specPath = join(
|
|
13
|
+
const specPath = join(vbriefDir, `specification${layout.artifactSuffix}`);
|
|
14
14
|
const hasSpec = existsSync(specPath);
|
|
15
15
|
const kind = hasSpec ? "full-spec" : "greenfield";
|
|
16
16
|
const banner = kind === "full-spec" ? SPEC_RENDER_BANNER : EXPORT_SPEC_PD_BANNER;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import { hasArtifactSuffix, resolveLifecycleRoot } from "../layout/resolve.js";
|
|
3
4
|
import { detectLifecycleFolder } from "../scope/decomposed-refs.js";
|
|
4
5
|
import { runTransition } from "../scope/transition.js";
|
|
5
6
|
import { collectChildUris, collectPlanRefs, resolveVbriefRef } from "../scope/vbrief-ref.js";
|
|
@@ -41,7 +42,7 @@ function globResolve(pattern, projectRoot) {
|
|
|
41
42
|
return [];
|
|
42
43
|
}
|
|
43
44
|
return readdirSync(dir)
|
|
44
|
-
.filter((name) => name
|
|
45
|
+
.filter((name) => hasArtifactSuffix(name) || glob === name)
|
|
45
46
|
.map((name) => resolve(dir, name))
|
|
46
47
|
.filter((p) => existsSync(p));
|
|
47
48
|
}
|
|
@@ -229,7 +230,7 @@ function completeParent(parentPath, vbriefDir, projectRoot, settled, dryRun) {
|
|
|
229
230
|
};
|
|
230
231
|
}
|
|
231
232
|
export function sweepCohort(storyPaths, projectRoot, dryRun) {
|
|
232
|
-
const vbriefDir =
|
|
233
|
+
const vbriefDir = resolveLifecycleRoot(projectRoot);
|
|
233
234
|
const result = {
|
|
234
235
|
project_root: resolve(projectRoot),
|
|
235
236
|
dry_run: dryRun,
|
|
@@ -243,7 +244,7 @@ export function sweepCohort(storyPaths, projectRoot, dryRun) {
|
|
|
243
244
|
const termDir = join(vbriefDir, term);
|
|
244
245
|
if (existsSync(termDir)) {
|
|
245
246
|
for (const name of readdirSync(termDir)) {
|
|
246
|
-
if (name
|
|
247
|
+
if (hasArtifactSuffix(name)) {
|
|
247
248
|
settled.add(resolve(join(termDir, name)));
|
|
248
249
|
}
|
|
249
250
|
}
|
|
@@ -358,7 +359,7 @@ export function completeCohort(args) {
|
|
|
358
359
|
stderr: `Error: project root does not exist: ${projectRoot}\n`,
|
|
359
360
|
};
|
|
360
361
|
}
|
|
361
|
-
if (!existsSync(
|
|
362
|
+
if (!existsSync(resolveLifecycleRoot(projectRoot))) {
|
|
362
363
|
return {
|
|
363
364
|
exitCode: 2,
|
|
364
365
|
stdout: "",
|
package/dist/swarm/launch.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { basename, join, resolve } from "node:path";
|
|
3
3
|
import { inferGithubAuthMode } from "../intake/github-auth-modes.js";
|
|
4
4
|
import { getPlatformCapabilities } from "../intake/platform-capabilities.js";
|
|
5
|
+
import { hasArtifactSuffix, resolveLifecycleFolder, stripArtifactSuffix, } from "../layout/resolve.js";
|
|
5
6
|
import { evaluate as preflightEvaluate } from "../preflight/evaluate.js";
|
|
6
7
|
import { issueNumbersFromPlan, scopeMetadataRank } from "../triage/queue/scope-walk.js";
|
|
7
8
|
import { selectionOrderingKey } from "../triage/queue/selection.js";
|
|
@@ -45,9 +46,7 @@ function storyId(path, plan) {
|
|
|
45
46
|
return value.trim();
|
|
46
47
|
}
|
|
47
48
|
const name = basename(path);
|
|
48
|
-
return name.
|
|
49
|
-
? name.slice(0, -".vbrief.json".length)
|
|
50
|
-
: name.replace(/\.[^.]+$/, "");
|
|
49
|
+
return hasArtifactSuffix(name) ? stripArtifactSuffix(name) : name.replace(/\.[^.]+$/, "");
|
|
51
50
|
}
|
|
52
51
|
function extractHashNumbers(text) {
|
|
53
52
|
const out = [];
|
|
@@ -128,13 +127,13 @@ function projectRel(projectRoot, path) {
|
|
|
128
127
|
}
|
|
129
128
|
}
|
|
130
129
|
function indexActiveStories(projectRoot) {
|
|
131
|
-
const activeDir =
|
|
130
|
+
const activeDir = resolveLifecycleFolder(projectRoot, "active");
|
|
132
131
|
const index = [];
|
|
133
132
|
if (!existsSync(activeDir)) {
|
|
134
133
|
return index;
|
|
135
134
|
}
|
|
136
135
|
for (const name of readdirSync(activeDir).sort()) {
|
|
137
|
-
if (!name
|
|
136
|
+
if (!hasArtifactSuffix(name)) {
|
|
138
137
|
continue;
|
|
139
138
|
}
|
|
140
139
|
const path = join(activeDir, name);
|
|
@@ -151,7 +150,7 @@ export function looksLikePath(token) {
|
|
|
151
150
|
return (token.endsWith(".json") ||
|
|
152
151
|
token.includes("/") ||
|
|
153
152
|
token.includes("\\") ||
|
|
154
|
-
(existsSync(token) && basename(token)
|
|
153
|
+
(existsSync(token) && hasArtifactSuffix(basename(token))));
|
|
155
154
|
}
|
|
156
155
|
function resolveOne(token, projectRoot, idMap, issueMap) {
|
|
157
156
|
if (looksLikePath(token)) {
|
|
@@ -411,7 +410,7 @@ export function swarmLaunch(args) {
|
|
|
411
410
|
stderr: "Error: no stories supplied. Pass --stories <ids|paths> and/or --paths <paths>.\n",
|
|
412
411
|
};
|
|
413
412
|
}
|
|
414
|
-
if (!existsSync(
|
|
413
|
+
if (!existsSync(resolveLifecycleFolder(projectRoot, "active"))) {
|
|
415
414
|
return {
|
|
416
415
|
exitCode: EXIT_CONFIG_ERROR,
|
|
417
416
|
stdout: "",
|
package/dist/swarm/readiness.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { basename, join, resolve } from "node:path";
|
|
3
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
4
|
+
import { ARTIFACT_SUFFIXES, hasArtifactSuffix, LIFECYCLE_DIR_NAMES, resolveLifecycleLayout, resolveLifecycleRoot, stripArtifactSuffix, } from "../layout/resolve.js";
|
|
3
5
|
import { acceptanceTextsFromItems, asStrList, deprecatedSubitemsIssues, itemHasTraces, itemsHaveAcceptance, missingRequiredSwarmFields, storyQualityIssues, } from "../vbrief-validation/story-quality.js";
|
|
4
6
|
import { LIFECYCLE_FOLDERS, READY } from "./constants.js";
|
|
5
7
|
function loadJson(path) {
|
|
@@ -24,7 +26,8 @@ function projectRel(projectRoot, path) {
|
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
function expandPaths(projectRoot, patterns) {
|
|
27
|
-
const
|
|
29
|
+
const layout = resolveLifecycleLayout(projectRoot);
|
|
30
|
+
const usePatterns = patterns.length > 0 ? patterns : [`${layout.artifactDir}/active/*${layout.artifactSuffix}`];
|
|
28
31
|
const out = [];
|
|
29
32
|
const seen = new Set();
|
|
30
33
|
for (const pattern of usePatterns) {
|
|
@@ -33,13 +36,14 @@ function expandPaths(projectRoot, patterns) {
|
|
|
33
36
|
const globPart = pattern.includes("/")
|
|
34
37
|
? pattern.slice(pattern.lastIndexOf("/") + 1)
|
|
35
38
|
: pattern;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const firstSeg = pattern.split("/")[0] ?? "";
|
|
40
|
+
const secondSeg = pattern.split("/")[1] ?? "";
|
|
41
|
+
const lifecyclePattern = LIFECYCLE_DIR_NAMES.includes(firstSeg);
|
|
42
|
+
if (lifecyclePattern && existsSync(join(projectRoot, firstSeg, secondSeg))) {
|
|
43
|
+
const activeDir = join(projectRoot, firstSeg, secondSeg);
|
|
44
|
+
for (const name of readdirSync(activeDir)) {
|
|
45
|
+
if (matchGlob(name, globPart)) {
|
|
46
|
+
addPath(join(activeDir, name), seen, out);
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
49
|
}
|
|
@@ -69,8 +73,10 @@ function dirnamePattern(projectRoot, pattern) {
|
|
|
69
73
|
return idx >= 0 ? join(projectRoot, pattern.slice(0, idx)) : projectRoot;
|
|
70
74
|
}
|
|
71
75
|
function matchGlob(name, glob) {
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
// Layout-aware (#2109 part 1): an artifact-suffix glob matches either suffix,
|
|
77
|
+
// so a mixed/either lifecycle tree resolves the same way.
|
|
78
|
+
if (ARTIFACT_SUFFIXES.some((suffix) => glob === `*${suffix}`)) {
|
|
79
|
+
return hasArtifactSuffix(name);
|
|
74
80
|
}
|
|
75
81
|
if (glob.startsWith("*.")) {
|
|
76
82
|
return name.endsWith(glob.slice(1));
|
|
@@ -115,7 +121,7 @@ function hasChildPlanRefs(plan) {
|
|
|
115
121
|
return refs.some((ref) => typeof ref === "object" &&
|
|
116
122
|
ref !== null &&
|
|
117
123
|
!Array.isArray(ref) &&
|
|
118
|
-
ref.type
|
|
124
|
+
referenceTypeMatches(String(ref.type ?? ""), "plan"));
|
|
119
125
|
}
|
|
120
126
|
function looksLikePhase(path, plan) {
|
|
121
127
|
const title = String(plan.title ?? "");
|
|
@@ -153,9 +159,7 @@ function storyId(path, plan) {
|
|
|
153
159
|
return value.trim();
|
|
154
160
|
}
|
|
155
161
|
const name = basename(path);
|
|
156
|
-
return name.
|
|
157
|
-
? name.slice(0, -".vbrief.json".length)
|
|
158
|
-
: name.replace(/\.[^.]+$/, "");
|
|
162
|
+
return hasArtifactSuffix(name) ? stripArtifactSuffix(name) : name.replace(/\.[^.]+$/, "");
|
|
159
163
|
}
|
|
160
164
|
function hasTraces(plan, swarm) {
|
|
161
165
|
const narratives = plan.narratives;
|
|
@@ -182,7 +186,7 @@ function hasTraces(plan, swarm) {
|
|
|
182
186
|
if (typeof ref === "object" &&
|
|
183
187
|
ref !== null &&
|
|
184
188
|
!Array.isArray(ref) &&
|
|
185
|
-
ref.type
|
|
189
|
+
referenceTypeMatches(String(ref.type ?? ""), "spec-section")) {
|
|
186
190
|
return true;
|
|
187
191
|
}
|
|
188
192
|
}
|
|
@@ -206,14 +210,14 @@ function acceptanceCountJustification(plan, swarm) {
|
|
|
206
210
|
}
|
|
207
211
|
function allScopeIds(projectRoot) {
|
|
208
212
|
const ids = new Map();
|
|
209
|
-
const vbriefDir =
|
|
213
|
+
const vbriefDir = resolveLifecycleRoot(projectRoot);
|
|
210
214
|
for (const folder of LIFECYCLE_FOLDERS) {
|
|
211
215
|
const dir = join(vbriefDir, folder);
|
|
212
216
|
if (!existsSync(dir)) {
|
|
213
217
|
continue;
|
|
214
218
|
}
|
|
215
219
|
for (const name of readdirSync(dir).sort()) {
|
|
216
|
-
if (!name
|
|
220
|
+
if (!hasArtifactSuffix(name)) {
|
|
217
221
|
continue;
|
|
218
222
|
}
|
|
219
223
|
const path = join(dir, name);
|
|
@@ -224,9 +228,7 @@ function allScopeIds(projectRoot) {
|
|
|
224
228
|
const plan = planOf(data);
|
|
225
229
|
const sid = storyId(path, plan);
|
|
226
230
|
ids.set(sid, [path, String(plan.status ?? "")]);
|
|
227
|
-
const stem = name
|
|
228
|
-
? name.slice(0, -".vbrief.json".length)
|
|
229
|
-
: name.replace(/\.[^.]+$/, "");
|
|
231
|
+
const stem = stripArtifactSuffix(name);
|
|
230
232
|
if (!ids.has(stem)) {
|
|
231
233
|
ids.set(stem, [path, String(plan.status ?? "")]);
|
|
232
234
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* @see {@link https://github.com/deftai/directive/issues/1739} Superseding PR
|
|
12
12
|
* @see {@link https://github.com/deftai/directive/issues/1860} Hard deletion tracking
|
|
13
13
|
*/
|
|
14
|
+
import { readPlanPolicy } from "../policy/plan-extensions.js";
|
|
14
15
|
import { loadProjectDefinition } from "../policy/resolve.js";
|
|
15
16
|
import { LEAF_CODING_WORKER_ROLE, SUBAGENT_BACKEND_SET_CMD } from "./constants.js";
|
|
16
17
|
const TRUTHY = new Set(["1", "true", "yes", "on"]);
|
|
@@ -63,11 +64,7 @@ export function probeSubagentBackends(environ = process.env) {
|
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
function getPolicyBlock(data) {
|
|
66
|
-
const
|
|
67
|
-
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
68
|
-
return {};
|
|
69
|
-
}
|
|
70
|
-
const policy = plan.policy;
|
|
67
|
+
const policy = readPlanPolicy(data.plan);
|
|
71
68
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
72
69
|
return {};
|
|
73
70
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
+
import { hasArtifactSuffix } from "../layout/resolve.js";
|
|
3
4
|
import { defaultRunGh, fetchGreptileCommentBody, fetchPrHeadSha, } from "../pr-merge-readiness/gh.js";
|
|
4
5
|
import { evaluateGates, parseGreptileBody } from "../pr-merge-readiness/index.js";
|
|
5
6
|
import { EXIT_EXTERNAL_ERROR, EXIT_OK, EXIT_UNCLEAN } from "./constants.js";
|
|
@@ -34,7 +35,7 @@ function globPaths(pattern) {
|
|
|
34
35
|
return [];
|
|
35
36
|
}
|
|
36
37
|
return readdirSync(dir)
|
|
37
|
-
.filter((name) => (glob === "*.vbrief.json" ? name
|
|
38
|
+
.filter((name) => (glob === "*.vbrief.json" ? hasArtifactSuffix(name) : name === glob))
|
|
38
39
|
.map((name) => resolve(dir, name));
|
|
39
40
|
}
|
|
40
41
|
return [resolve(pattern)];
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { AuditEntry, CandidatesLog } from "./types.js";
|
|
2
|
+
/** Display/back-compat constant; resolution flows through resolveEvalPath (#2109). */
|
|
2
3
|
export declare const AUDIT_LOG_REL_PATH = "vbrief/.eval/candidates.jsonl";
|
|
4
|
+
/** Layout-aware candidates audit-log path (xbrief when migrated, else vbrief). */
|
|
5
|
+
export declare function resolveCandidatesLogPath(projectRoot: string): string;
|
|
3
6
|
/** Read every well-formed audit-log row in insertion order (#1698 shared reader). */
|
|
4
7
|
export declare function readAuditLog(logPath: string, repo?: string | null): AuditEntry[];
|
|
5
8
|
/** Return every entry for ``(repo, issue_number)`` in insertion order. */
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
import { resolveEvalPath } from "../../layout/resolve.js";
|
|
4
5
|
import { CandidatesLogError } from "./errors.js";
|
|
6
|
+
/** Display/back-compat constant; resolution flows through resolveEvalPath (#2109). */
|
|
5
7
|
export const AUDIT_LOG_REL_PATH = "vbrief/.eval/candidates.jsonl";
|
|
8
|
+
/** Layout-aware candidates audit-log path (xbrief when migrated, else vbrief). */
|
|
9
|
+
export function resolveCandidatesLogPath(projectRoot) {
|
|
10
|
+
return resolveEvalPath(projectRoot, "candidates.jsonl");
|
|
11
|
+
}
|
|
6
12
|
const VALID_DECISIONS = new Set([
|
|
7
13
|
"accept",
|
|
8
14
|
"reject",
|
|
@@ -103,7 +109,7 @@ function resolveLogPath(projectRoot, override) {
|
|
|
103
109
|
if (override !== undefined) {
|
|
104
110
|
return override;
|
|
105
111
|
}
|
|
106
|
-
return
|
|
112
|
+
return resolveCandidatesLogPath(projectRoot);
|
|
107
113
|
}
|
|
108
114
|
function stableStringify(entry) {
|
|
109
115
|
const sortedKeys = Object.keys(entry).sort();
|
|
@@ -227,6 +233,6 @@ export function rollbackAuditEntry(decisionId, projectRoot, logPathOverride) {
|
|
|
227
233
|
return removed;
|
|
228
234
|
}
|
|
229
235
|
export function resolveAuditLogPath(projectRoot) {
|
|
230
|
-
return
|
|
236
|
+
return resolveCandidatesLogPath(projectRoot);
|
|
231
237
|
}
|
|
232
238
|
//# sourceMappingURL=candidates-log.js.map
|