@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,10 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname } from "node:path";
|
|
2
|
+
import { dirname, relative } from "node:path";
|
|
3
|
+
import { resolveEvalPath } from "../../layout/resolve.js";
|
|
4
|
+
/** POSIX-style display path for `absPath` relative to `projectRoot` (#2109). */
|
|
5
|
+
function evalRelDisplay(projectRoot, absPath) {
|
|
6
|
+
return relative(projectRoot, absPath).split(/[\\/]/).join("/");
|
|
7
|
+
}
|
|
3
8
|
export const GITIGNORE_LINE = ".deft-cache/";
|
|
4
9
|
export const GITIGNORE_DEFT_RUNTIME_SENTINELS = [
|
|
5
10
|
".deft/ritual-state.json",
|
|
@@ -126,7 +131,6 @@ operators should know:
|
|
|
126
131
|
- \`.gitattributes\` -- the \`merge=union\` rule.
|
|
127
132
|
- \`scripts/candidates_log.py\` -- the writer for \`candidates.jsonl\`.
|
|
128
133
|
`;
|
|
129
|
-
const CANDIDATES_RELPATH = "vbrief/.eval/candidates.jsonl";
|
|
130
134
|
function stepOutcome(name, ok, message, details = {}, error = null) {
|
|
131
135
|
return { name, ok, message, error, details };
|
|
132
136
|
}
|
|
@@ -307,10 +311,10 @@ function ensureGitattributesMergeUnion(gitattributesPath, stepName) {
|
|
|
307
311
|
}
|
|
308
312
|
return stepOutcome(stepName, true, "created .gitattributes with vbrief/.eval/*.jsonl merge=union", { gitattributes_appended: true, gitattributes_created: true });
|
|
309
313
|
}
|
|
310
|
-
function ensureEvalReadme(readmePath, stepName) {
|
|
314
|
+
function ensureEvalReadme(readmePath, readmeRel, stepName) {
|
|
311
315
|
try {
|
|
312
316
|
readFileSync(readmePath, { encoding: "utf8" });
|
|
313
|
-
return stepOutcome(stepName, true,
|
|
317
|
+
return stepOutcome(stepName, true, `${readmeRel} already present (no-op)`, {
|
|
314
318
|
readme_created: false,
|
|
315
319
|
readme_already_present: true,
|
|
316
320
|
});
|
|
@@ -325,7 +329,7 @@ function ensureEvalReadme(readmePath, stepName) {
|
|
|
325
329
|
catch (exc) {
|
|
326
330
|
return stepOutcome(stepName, false, `could not create ${readmePath}`, { readme_created: false }, String(exc));
|
|
327
331
|
}
|
|
328
|
-
return stepOutcome(stepName, true,
|
|
332
|
+
return stepOutcome(stepName, true, `created ${readmeRel} (#1144 hybrid policy)`, {
|
|
329
333
|
readme_created: true,
|
|
330
334
|
});
|
|
331
335
|
}
|
|
@@ -333,7 +337,10 @@ function ensureEvalReadme(readmePath, stepName) {
|
|
|
333
337
|
export function stepEnsureGitignoreEvalEntries(projectRoot) {
|
|
334
338
|
const gitignorePath = `${projectRoot}/.gitignore`;
|
|
335
339
|
const gitattributesPath = `${projectRoot}/.gitattributes`;
|
|
336
|
-
|
|
340
|
+
// Layout-aware (#2109): resolve the README under the active lifecycle `.eval`
|
|
341
|
+
// dir (xbrief/ when migrated, else vbrief/) instead of a hardcoded vbrief/ path.
|
|
342
|
+
const readmePath = resolveEvalPath(projectRoot, "README.md");
|
|
343
|
+
const readmeRel = evalRelDisplay(projectRoot, readmePath);
|
|
337
344
|
const stepName = "ensure_gitignore_eval_entries";
|
|
338
345
|
const details = {};
|
|
339
346
|
const giResult = ensureGitignoreSelectiveEntries(gitignorePath, stepName);
|
|
@@ -348,7 +355,7 @@ export function stepEnsureGitignoreEvalEntries(projectRoot) {
|
|
|
348
355
|
return stepOutcome(stepName, false, gaResult.message, details, gaResult.error ?? null);
|
|
349
356
|
}
|
|
350
357
|
Object.assign(details, gaResult.details);
|
|
351
|
-
const rdResult = ensureEvalReadme(readmePath, stepName);
|
|
358
|
+
const rdResult = ensureEvalReadme(readmePath, readmeRel, stepName);
|
|
352
359
|
if (!rdResult.ok) {
|
|
353
360
|
Object.assign(details, rdResult.details);
|
|
354
361
|
return stepOutcome(stepName, false, rdResult.message, details, rdResult.error ?? null);
|
|
@@ -361,7 +368,7 @@ export function stepEnsureGitignoreEvalEntries(projectRoot) {
|
|
|
361
368
|
if (appendedLines === 0 && !appendedAttr && !createdReadme) {
|
|
362
369
|
message =
|
|
363
370
|
".gitignore selective entries, .gitattributes merge=union, " +
|
|
364
|
-
|
|
371
|
+
`and ${readmeRel} already present (#1144 hybrid ` +
|
|
365
372
|
"policy satisfied; no-op)";
|
|
366
373
|
}
|
|
367
374
|
else {
|
|
@@ -373,7 +380,7 @@ export function stepEnsureGitignoreEvalEntries(projectRoot) {
|
|
|
373
380
|
if (appendedAttr)
|
|
374
381
|
parts.push(".gitattributes merge=union rule");
|
|
375
382
|
if (createdReadme)
|
|
376
|
-
parts.push(
|
|
383
|
+
parts.push(readmeRel);
|
|
377
384
|
message = `wrote ${parts.join(" + ")} per #1144 hybrid policy`;
|
|
378
385
|
}
|
|
379
386
|
message += formatBlanketWarning(Boolean(details.blanket_present));
|
|
@@ -381,7 +388,10 @@ export function stepEnsureGitignoreEvalEntries(projectRoot) {
|
|
|
381
388
|
}
|
|
382
389
|
/** Ensure `vbrief/.eval/candidates.jsonl` exists (#1240 option A). */
|
|
383
390
|
export function stepSeedCandidatesLog(projectRoot) {
|
|
384
|
-
|
|
391
|
+
// Layout-aware (#2109): seed under the active lifecycle `.eval` dir (xbrief/
|
|
392
|
+
// when migrated, else vbrief/) instead of a hardcoded vbrief/ path.
|
|
393
|
+
const auditPath = resolveEvalPath(projectRoot, "candidates.jsonl");
|
|
394
|
+
const auditRel = evalRelDisplay(projectRoot, auditPath);
|
|
385
395
|
const auditDir = dirname(auditPath);
|
|
386
396
|
try {
|
|
387
397
|
mkdirSync(auditDir, { recursive: true });
|
|
@@ -391,8 +401,7 @@ export function stepSeedCandidatesLog(projectRoot) {
|
|
|
391
401
|
}
|
|
392
402
|
try {
|
|
393
403
|
readFileSync(auditPath, { encoding: "utf8" });
|
|
394
|
-
|
|
395
|
-
return stepOutcome("seed_candidates_log", true, `${relative} already present (no-op)`, {
|
|
404
|
+
return stepOutcome("seed_candidates_log", true, `${auditRel} already present (no-op)`, {
|
|
396
405
|
created: false,
|
|
397
406
|
already_present: true,
|
|
398
407
|
});
|
|
@@ -406,7 +415,7 @@ export function stepSeedCandidatesLog(projectRoot) {
|
|
|
406
415
|
catch (exc) {
|
|
407
416
|
return stepOutcome("seed_candidates_log", false, `could not seed ${auditPath}`, {}, String(exc));
|
|
408
417
|
}
|
|
409
|
-
return stepOutcome("seed_candidates_log", true, `created empty ${
|
|
418
|
+
return stepOutcome("seed_candidates_log", true, `created empty ${auditRel}`, {
|
|
410
419
|
created: true,
|
|
411
420
|
already_present: false,
|
|
412
421
|
});
|
|
@@ -3,6 +3,7 @@ import { randomUUID } from "node:crypto";
|
|
|
3
3
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
|
+
import { hasArtifactSuffix, resolveEvalPath, resolveLifecycleRoot } from "../../layout/resolve.js";
|
|
6
7
|
import { SUBPROCESS_MAX_BUFFER } from "../../subprocess/max-buffer.js";
|
|
7
8
|
import { stepEnsureGitignoreEntry, stepEnsureGitignoreEvalEntries, stepSeedCandidatesLog, } from "./gitignore.js";
|
|
8
9
|
import { PROGRESS_DEFAULT } from "./types.js";
|
|
@@ -296,7 +297,9 @@ function extractIssueNumber(vbriefData) {
|
|
|
296
297
|
if (typeof ref !== "object" || ref === null)
|
|
297
298
|
continue;
|
|
298
299
|
const typed = ref;
|
|
299
|
-
|
|
300
|
+
// Dual-namespace (#2109): accept the migrated `x-xbrief/` corpus token and
|
|
301
|
+
// the legacy `x-vbrief/` token (still read-accepted for back-compat).
|
|
302
|
+
if (typed.type !== "x-xbrief/github-issue" && typed.type !== "x-vbrief/github-issue")
|
|
300
303
|
continue;
|
|
301
304
|
const uri = typed.uri;
|
|
302
305
|
if (typeof uri !== "string")
|
|
@@ -312,7 +315,7 @@ function scanLifecycleFolder(folder) {
|
|
|
312
315
|
if (!existsSync(folder))
|
|
313
316
|
return results;
|
|
314
317
|
const entries = readdirSync(folder)
|
|
315
|
-
.filter((name) => name
|
|
318
|
+
.filter((name) => hasArtifactSuffix(name))
|
|
316
319
|
.sort();
|
|
317
320
|
for (const name of entries) {
|
|
318
321
|
const path = join(folder, name);
|
|
@@ -370,11 +373,11 @@ export function stepBackfillAuditLog(projectRoot, repo, options = {}) {
|
|
|
370
373
|
if (repo === null) {
|
|
371
374
|
return stepOutcome("backfill_audit_log", true, "skipped (no --repo provided; pass --repo OWNER/NAME to backfill)", { skipped: "no-repo" });
|
|
372
375
|
}
|
|
373
|
-
const vbriefRoot =
|
|
376
|
+
const vbriefRoot = resolveLifecycleRoot(projectRoot);
|
|
374
377
|
if (!existsSync(vbriefRoot)) {
|
|
375
378
|
return stepOutcome("backfill_audit_log", true, `skipped (no vbrief/ directory under ${projectRoot})`, { skipped: "no-vbrief" });
|
|
376
379
|
}
|
|
377
|
-
const auditPath =
|
|
380
|
+
const auditPath = resolveEvalPath(projectRoot, "candidates.jsonl");
|
|
378
381
|
const alreadyLogged = existingAuditIssueNumbers(auditPath);
|
|
379
382
|
const nowIso = options.nowIso ?? nowIsoDefault;
|
|
380
383
|
const appendEntry = options.appendAuditEntry ?? appendAuditEntryDefault;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { resolveEvalPath } from "../../layout/resolve.js";
|
|
4
5
|
export const ACTION_FN_NAMES = {
|
|
5
6
|
accept: "accept",
|
|
6
7
|
reject: "reject",
|
|
@@ -375,7 +376,7 @@ export function createFilesystemCacheModule() {
|
|
|
375
376
|
CacheError,
|
|
376
377
|
};
|
|
377
378
|
}
|
|
378
|
-
export function createFilesystemCandidatesLogModule(logPath = "
|
|
379
|
+
export function createFilesystemCandidatesLogModule(logPath = resolveEvalPath(process.cwd(), "candidates.jsonl")) {
|
|
379
380
|
return {
|
|
380
381
|
readAll(options) {
|
|
381
382
|
if (!existsSync(logPath)) {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
4
|
+
import { hasArtifactSuffix, resolveLifecycleRoot, resolveProjectDefinitionPath, } from "../../layout/resolve.js";
|
|
5
|
+
import { readPlanPolicy } from "../../policy/plan-extensions.js";
|
|
3
6
|
import { pyRepr } from "../../scm/py-format.js";
|
|
4
7
|
function pythonTypeName(value) {
|
|
5
8
|
if (value === null) {
|
|
@@ -252,8 +255,7 @@ export function validateHoldMarkers(markers) {
|
|
|
252
255
|
return { errors, warnings };
|
|
253
256
|
}
|
|
254
257
|
export function projectDefinitionPath(projectRoot) {
|
|
255
|
-
|
|
256
|
-
return join(root, PROJECT_DEFINITION_REL_PATH);
|
|
258
|
+
return resolveProjectDefinitionPath(projectRoot ?? process.cwd());
|
|
257
259
|
}
|
|
258
260
|
function loadProjectDefinition(projectRoot) {
|
|
259
261
|
const path = projectDefinitionPath(projectRoot);
|
|
@@ -276,7 +278,7 @@ function consumerRulesFromProject(data) {
|
|
|
276
278
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
277
279
|
return [];
|
|
278
280
|
}
|
|
279
|
-
const policy = plan
|
|
281
|
+
const policy = readPlanPolicy(plan);
|
|
280
282
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
281
283
|
return [];
|
|
282
284
|
}
|
|
@@ -294,7 +296,7 @@ function holdMarkersFromProject(data) {
|
|
|
294
296
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
295
297
|
return null;
|
|
296
298
|
}
|
|
297
|
-
const policy = plan
|
|
299
|
+
const policy = readPlanPolicy(plan);
|
|
298
300
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
299
301
|
return null;
|
|
300
302
|
}
|
|
@@ -518,13 +520,13 @@ export function classifyIssue(issue, options = {}) {
|
|
|
518
520
|
}
|
|
519
521
|
/** Return issue numbers referenced by pending/ or active/ scope vBRIEFs. */
|
|
520
522
|
export function extractReferencedIssues(projectRoot, lifecycleFolders = ["pending", "active"]) {
|
|
521
|
-
const root =
|
|
523
|
+
const root = resolveLifecycleRoot(projectRoot ?? process.cwd());
|
|
522
524
|
const referenced = new Set();
|
|
523
525
|
for (const folder of lifecycleFolders) {
|
|
524
526
|
const folderPath = join(root, folder);
|
|
525
527
|
let entries;
|
|
526
528
|
try {
|
|
527
|
-
entries = readdirSync(folderPath).filter((f) => f
|
|
529
|
+
entries = readdirSync(folderPath).filter((f) => hasArtifactSuffix(f));
|
|
528
530
|
}
|
|
529
531
|
catch {
|
|
530
532
|
continue;
|
|
@@ -549,7 +551,7 @@ export function extractReferencedIssues(projectRoot, lifecycleFolders = ["pendin
|
|
|
549
551
|
continue;
|
|
550
552
|
}
|
|
551
553
|
const r = ref;
|
|
552
|
-
if (r.type
|
|
554
|
+
if (!referenceTypeMatches(String(r.type ?? ""), "github-issue")) {
|
|
553
555
|
continue;
|
|
554
556
|
}
|
|
555
557
|
const uri = r.uri;
|
|
@@ -652,7 +654,7 @@ export function validateTriageAutoClassifyOnPlan(plan, filepath) {
|
|
|
652
654
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
653
655
|
return out;
|
|
654
656
|
}
|
|
655
|
-
const policy = plan
|
|
657
|
+
const policy = readPlanPolicy(plan);
|
|
656
658
|
const raw = typeof policy === "object" && policy !== null && !Array.isArray(policy)
|
|
657
659
|
? policy.triageAutoClassify
|
|
658
660
|
: undefined;
|
|
@@ -671,7 +673,7 @@ export function validateTriageHoldMarkersOnPlan(plan, filepath) {
|
|
|
671
673
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
672
674
|
return out;
|
|
673
675
|
}
|
|
674
|
-
const policy = plan
|
|
676
|
+
const policy = readPlanPolicy(plan);
|
|
675
677
|
const raw = typeof policy === "object" && policy !== null && !Array.isArray(policy)
|
|
676
678
|
? policy.triageHoldMarkers
|
|
677
679
|
: undefined;
|
|
@@ -696,7 +698,7 @@ export function validateProject(projectRoot) {
|
|
|
696
698
|
return {
|
|
697
699
|
code: 0,
|
|
698
700
|
stdout: "OK: no PROJECT-DEFINITION at " +
|
|
699
|
-
`${
|
|
701
|
+
`${resolveProjectDefinitionPath(root)} -- ` +
|
|
700
702
|
"framework defaults apply with no consumer overrides.\n",
|
|
701
703
|
stderr: "",
|
|
702
704
|
};
|
|
@@ -709,7 +711,7 @@ export function validateProject(projectRoot) {
|
|
|
709
711
|
stderr: "FAIL: PROJECT-DEFINITION.plan is not an object\n",
|
|
710
712
|
};
|
|
711
713
|
}
|
|
712
|
-
const rel =
|
|
714
|
+
const rel = resolveProjectDefinitionPath(root);
|
|
713
715
|
const classifyErrs = validateTriageAutoClassifyOnPlan(plan, rel);
|
|
714
716
|
const holderErrs = validateTriageHoldMarkersOnPlan(plan, rel);
|
|
715
717
|
const errors = [...classifyErrs, ...holderErrs];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { resolveEvalPath } from "../../layout/resolve.js";
|
|
4
4
|
/** Resolve audit log path; mirrors candidates_log._resolve_path (framework root). */
|
|
5
5
|
export function resolveAuditLogPath(options = {}) {
|
|
6
6
|
if (options.auditLogPath !== null && options.auditLogPath !== undefined) {
|
|
@@ -12,7 +12,7 @@ export function resolveAuditLogPath(options = {}) {
|
|
|
12
12
|
: envRoot.length > 0
|
|
13
13
|
? resolve(envRoot)
|
|
14
14
|
: process.cwd();
|
|
15
|
-
return
|
|
15
|
+
return resolveEvalPath(root, "candidates.jsonl");
|
|
16
16
|
}
|
|
17
17
|
/** Read audit log entries, optionally filtered by repo. */
|
|
18
18
|
export function readAuditEntries(repo, options = {}) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import { resolveEvalPath } from "../../layout/resolve.js";
|
|
3
4
|
import { extractAuthor, extractMilestone } from "../scope-drift/cache-walker.js";
|
|
4
|
-
import { CACHE_DIR_NAME, CACHE_SOURCE_GITHUB_ISSUE
|
|
5
|
+
import { CACHE_DIR_NAME, CACHE_SOURCE_GITHUB_ISSUE } from "./constants.js";
|
|
5
6
|
import { hasActiveScopeIgnores, isRawIssueScopeIgnored, resolveScopeIgnores, } from "./scope-ignores-filter.js";
|
|
6
7
|
import { blockedByIssueNumber, rankByIssueNumber } from "./scope-walk.js";
|
|
7
8
|
function cachedState(issue) {
|
|
@@ -22,7 +23,7 @@ export function resolveSlicesLogPath(options = {}) {
|
|
|
22
23
|
: envRoot.length > 0
|
|
23
24
|
? resolve(envRoot)
|
|
24
25
|
: process.cwd();
|
|
25
|
-
return
|
|
26
|
+
return resolveEvalPath(root, "slices.jsonl");
|
|
26
27
|
}
|
|
27
28
|
/** Read slices.jsonl records. */
|
|
28
29
|
export function loadSliceRecords(options = {}) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readPlanPolicy } from "../../policy/plan-extensions.js";
|
|
1
2
|
import { DEFAULT_TRIAGE_RANKING_LABELS, PROJECT_DEFINITION_REL_PATH } from "./constants.js";
|
|
2
3
|
import { loadProjectDefinition } from "./project.js";
|
|
3
4
|
/** Resolve effective plan.policy.triageRankingLabels list. */
|
|
@@ -10,7 +11,7 @@ export function resolveRankingLabels(projectRoot) {
|
|
|
10
11
|
if (typeof plan !== "object" || plan === null) {
|
|
11
12
|
return [...DEFAULT_TRIAGE_RANKING_LABELS];
|
|
12
13
|
}
|
|
13
|
-
const policy = plan
|
|
14
|
+
const policy = readPlanPolicy(plan);
|
|
14
15
|
if (typeof policy !== "object" || policy === null) {
|
|
15
16
|
return [...DEFAULT_TRIAGE_RANKING_LABELS];
|
|
16
17
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
-
import { join
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
4
|
+
import { hasArtifactSuffix, resolveLifecycleFolder, resolveLifecycleRoot, } from "../../layout/resolve.js";
|
|
3
5
|
function loadPlan(path) {
|
|
4
6
|
try {
|
|
5
7
|
const data = JSON.parse(readFileSync(path, { encoding: "utf8" }));
|
|
@@ -25,7 +27,7 @@ export function issueNumbersFromPlan(plan) {
|
|
|
25
27
|
continue;
|
|
26
28
|
}
|
|
27
29
|
const typed = ref;
|
|
28
|
-
if (typed.type
|
|
30
|
+
if (!referenceTypeMatches(String(typed.type ?? ""), "github-issue")) {
|
|
29
31
|
continue;
|
|
30
32
|
}
|
|
31
33
|
const uri = typed.uri;
|
|
@@ -82,11 +84,11 @@ function dependsOnIds(plan) {
|
|
|
82
84
|
}
|
|
83
85
|
function completedPlanIds(projectRoot) {
|
|
84
86
|
const out = new Set();
|
|
85
|
-
const base =
|
|
87
|
+
const base = resolveLifecycleFolder(projectRoot, "completed");
|
|
86
88
|
if (!existsSync(base)) {
|
|
87
89
|
return out;
|
|
88
90
|
}
|
|
89
|
-
for (const name of readdirSync(base).filter((entry) => entry
|
|
91
|
+
for (const name of readdirSync(base).filter((entry) => hasArtifactSuffix(entry))) {
|
|
90
92
|
const plan = loadPlan(join(base, name));
|
|
91
93
|
if (plan === null) {
|
|
92
94
|
continue;
|
|
@@ -111,14 +113,14 @@ export function scopeIsBlocked(plan, completedIds) {
|
|
|
111
113
|
return deps.length > 0 && deps.some((dep) => !completedIds.has(dep));
|
|
112
114
|
}
|
|
113
115
|
function walkScopeFolders(projectRoot, folders, visitor) {
|
|
114
|
-
const base =
|
|
116
|
+
const base = resolveLifecycleRoot(projectRoot);
|
|
115
117
|
for (const folder of folders) {
|
|
116
118
|
const folderDir = join(base, folder);
|
|
117
119
|
if (!existsSync(folderDir)) {
|
|
118
120
|
continue;
|
|
119
121
|
}
|
|
120
122
|
for (const name of readdirSync(folderDir)
|
|
121
|
-
.filter((entry) => entry
|
|
123
|
+
.filter((entry) => hasArtifactSuffix(entry))
|
|
122
124
|
.sort()) {
|
|
123
125
|
const plan = loadPlan(join(folderDir, name));
|
|
124
126
|
if (plan !== null) {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { hasArtifactSuffix } from "../../layout/resolve.js";
|
|
3
4
|
import { extractIssueRef } from "./parse-uri.js";
|
|
4
5
|
export function scanLifecycleRefs(folder) {
|
|
5
6
|
const results = [];
|
|
6
7
|
if (!existsSync(folder))
|
|
7
8
|
return results;
|
|
8
9
|
const files = readdirSync(folder)
|
|
9
|
-
.filter((name) => name
|
|
10
|
+
.filter((name) => hasArtifactSuffix(name))
|
|
10
11
|
.sort();
|
|
11
12
|
for (const name of files) {
|
|
12
13
|
const path = join(folder, name);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
1
2
|
/** Parse (repo, issue_number) from a github-issue reference URI. */
|
|
2
3
|
export function parseGithubIssueUri(uri) {
|
|
3
4
|
if (typeof uri !== "string")
|
|
@@ -32,7 +33,7 @@ export function extractIssueRef(data) {
|
|
|
32
33
|
if (typeof ref !== "object" || ref === null || Array.isArray(ref))
|
|
33
34
|
continue;
|
|
34
35
|
const rec = ref;
|
|
35
|
-
if (rec.type
|
|
36
|
+
if (!referenceTypeMatches(String(rec.type ?? ""), "github-issue"))
|
|
36
37
|
continue;
|
|
37
38
|
const [repo, number] = parseGithubIssueUri(rec.uri);
|
|
38
39
|
if (number !== null)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
4
|
-
import { dirname,
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { resolveEvalPath, resolveLifecycleFolder } from "../../layout/resolve.js";
|
|
5
6
|
import { auditKey, existingAuditRefs, scanLifecycleRefs } from "./audit.js";
|
|
6
|
-
import {
|
|
7
|
+
import { BACKFILL_FOLDERS, RECONCILE_ACTOR, } from "./types.js";
|
|
7
8
|
const GIT_ORIGIN_RE = /^(?:https?:\/\/(?:[^@/]+@)?github\.com\/|git@github\.com:|ssh:\/\/git@github\.com[:/])([A-Za-z0-9][A-Za-z0-9._-]*)\/([A-Za-z0-9][A-Za-z0-9._-]*?)(?:\.git)?\/?\s*$/;
|
|
8
9
|
export function inferRepoFromGit(cwd) {
|
|
9
10
|
try {
|
|
@@ -32,13 +33,13 @@ function newDecisionId() {
|
|
|
32
33
|
}
|
|
33
34
|
export function findReconcilable(projectRoot, options = {}) {
|
|
34
35
|
const root = resolve(projectRoot);
|
|
35
|
-
const auditPath = options.auditLogPath ??
|
|
36
|
+
const auditPath = options.auditLogPath ?? resolveEvalPath(root, "candidates.jsonl");
|
|
36
37
|
const existing = existingAuditRefs(auditPath);
|
|
37
38
|
const defaultRepo = options.defaultRepo ?? null;
|
|
38
39
|
const items = [];
|
|
39
40
|
const seen = new Set();
|
|
40
41
|
for (const folderName of BACKFILL_FOLDERS) {
|
|
41
|
-
const folderPath =
|
|
42
|
+
const folderPath = resolveLifecycleFolder(root, folderName);
|
|
42
43
|
for (const [refRepo, number, path] of scanLifecycleRefs(folderPath)) {
|
|
43
44
|
const effectiveRepo = refRepo ?? defaultRepo;
|
|
44
45
|
if (effectiveRepo === null)
|
|
@@ -63,7 +64,7 @@ function countSkippedExisting(projectRoot, defaultRepo, auditPath) {
|
|
|
63
64
|
let count = 0;
|
|
64
65
|
const root = resolve(projectRoot);
|
|
65
66
|
for (const folderName of BACKFILL_FOLDERS) {
|
|
66
|
-
for (const [refRepo, number] of scanLifecycleRefs(
|
|
67
|
+
for (const [refRepo, number] of scanLifecycleRefs(resolveLifecycleFolder(root, folderName))) {
|
|
67
68
|
const effectiveRepo = refRepo ?? defaultRepo;
|
|
68
69
|
if (effectiveRepo === null)
|
|
69
70
|
continue;
|
|
@@ -86,7 +87,7 @@ function countNoRepo(projectRoot, defaultRepo, auditPath) {
|
|
|
86
87
|
let count = 0;
|
|
87
88
|
const root = resolve(projectRoot);
|
|
88
89
|
for (const folderName of BACKFILL_FOLDERS) {
|
|
89
|
-
for (const [refRepo, number] of scanLifecycleRefs(
|
|
90
|
+
for (const [refRepo, number] of scanLifecycleRefs(resolveLifecycleFolder(root, folderName))) {
|
|
90
91
|
if ((refRepo ?? defaultRepo) === null && !existingNumbers.has(number))
|
|
91
92
|
count += 1;
|
|
92
93
|
}
|
|
@@ -115,7 +116,7 @@ export function reconcile(projectRoot, options = {}) {
|
|
|
115
116
|
if (defaultRepo === null) {
|
|
116
117
|
defaultRepo = inferRepoFromGit(root);
|
|
117
118
|
}
|
|
118
|
-
const auditPath = options.auditLogPath ??
|
|
119
|
+
const auditPath = options.auditLogPath ?? resolveEvalPath(root, "candidates.jsonl");
|
|
119
120
|
const dryRun = options.dryRun ?? false;
|
|
120
121
|
const result = {
|
|
121
122
|
projectRoot: root,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
4
|
+
import { hasArtifactSuffix } from "../../layout/resolve.js";
|
|
3
5
|
const ISSUE_URL_RE = /github\.com\/([^/]+\/[^/]+)\/issues\/(\d+)/i;
|
|
4
6
|
export function iterActiveVbriefs(activeDir) {
|
|
5
7
|
if (!existsSync(activeDir))
|
|
6
8
|
return [];
|
|
7
9
|
return readdirSync(activeDir)
|
|
8
|
-
.filter((name) => name
|
|
10
|
+
.filter((name) => hasArtifactSuffix(name))
|
|
9
11
|
.sort()
|
|
10
12
|
.map((name) => join(activeDir, name));
|
|
11
13
|
}
|
|
@@ -30,7 +32,7 @@ export function extractIssueRefs(vbriefPath) {
|
|
|
30
32
|
if (typeof ref !== "object" || ref === null || Array.isArray(ref))
|
|
31
33
|
continue;
|
|
32
34
|
const rec = ref;
|
|
33
|
-
if (rec.type
|
|
35
|
+
if (!referenceTypeMatches(String(rec.type ?? ""), "github-issue"))
|
|
34
36
|
continue;
|
|
35
37
|
const uri = String(rec.uri ?? "");
|
|
36
38
|
const match = ISSUE_URL_RE.exec(uri);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { resolveLifecycleFolder } from "../../layout/resolve.js";
|
|
2
3
|
import { detectDrift } from "./drift.js";
|
|
3
4
|
import { iterActiveVbriefs } from "./extract.js";
|
|
4
5
|
import { PROMPT_OPTIONS } from "./types.js";
|
|
@@ -20,7 +21,7 @@ function defaultAuditWriter(repo, issueNumber, annotation, log) {
|
|
|
20
21
|
}
|
|
21
22
|
export function refreshActive(projectRoot, options = {}) {
|
|
22
23
|
const root = resolve(projectRoot);
|
|
23
|
-
const activeDir = options.activeDir ??
|
|
24
|
+
const activeDir = options.activeDir ?? resolveLifecycleFolder(root, "active");
|
|
24
25
|
const log = options.log ?? ((line) => process.stdout.write(`${line}\n`));
|
|
25
26
|
const inputFn = options.inputFn ?? (() => "");
|
|
26
27
|
const refreshLocal = options.refreshLocal ?? (() => { });
|
|
@@ -2,14 +2,16 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { resolveEvalPath, resolveProjectDefinitionPath } from "../../layout/resolve.js";
|
|
6
|
+
import { migrateLegacyPolicyKey, PLAN_POLICY_KEY } from "../../policy/plan-extensions.js";
|
|
7
|
+
import { SUBSCRIPTION_HISTORY_SCHEMA } from "./constants.js";
|
|
6
8
|
import { pyStrRepr } from "./python-repr.js";
|
|
7
9
|
import { utcIso } from "./time.js";
|
|
8
10
|
export class ProjectDefinitionIOError extends Error {
|
|
9
11
|
name = "ProjectDefinitionIOError";
|
|
10
12
|
}
|
|
11
13
|
export function projectDefinitionPath(projectRoot) {
|
|
12
|
-
return
|
|
14
|
+
return resolveProjectDefinitionPath(projectRoot);
|
|
13
15
|
}
|
|
14
16
|
export function loadProjectDefinitionForMutation(projectRoot) {
|
|
15
17
|
const path = projectDefinitionPath(projectRoot);
|
|
@@ -58,7 +60,7 @@ function resolveActor(actor) {
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
export function recordSubscriptionChange(projectRoot, options) {
|
|
61
|
-
const historyPath =
|
|
63
|
+
const historyPath = resolveEvalPath(projectRoot, "subscription-history.jsonl");
|
|
62
64
|
const record = {
|
|
63
65
|
schema: SUBSCRIPTION_HISTORY_SCHEMA,
|
|
64
66
|
change_id: randomUUID(),
|
|
@@ -132,9 +134,10 @@ export function subscribe(projectRoot, options) {
|
|
|
132
134
|
throw new Error(`PROJECT-DEFINITION at ${path} has a non-object 'plan' key`);
|
|
133
135
|
}
|
|
134
136
|
const planRec = plan;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
137
|
+
migrateLegacyPolicyKey(planRec);
|
|
138
|
+
if (planRec[PLAN_POLICY_KEY] === undefined)
|
|
139
|
+
planRec[PLAN_POLICY_KEY] = {};
|
|
140
|
+
const policy = planRec[PLAN_POLICY_KEY];
|
|
138
141
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
139
142
|
throw new Error(`PROJECT-DEFINITION at ${path} has a non-object 'plan.policy' key`);
|
|
140
143
|
}
|
|
@@ -179,9 +182,10 @@ export function addIgnore(projectRoot, label) {
|
|
|
179
182
|
throw new Error(`PROJECT-DEFINITION at ${path} has a non-object 'plan' key`);
|
|
180
183
|
}
|
|
181
184
|
const planRec = plan;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
+
migrateLegacyPolicyKey(planRec);
|
|
186
|
+
if (planRec[PLAN_POLICY_KEY] === undefined)
|
|
187
|
+
planRec[PLAN_POLICY_KEY] = {};
|
|
188
|
+
const policy = planRec[PLAN_POLICY_KEY];
|
|
185
189
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
186
190
|
throw new Error(`PROJECT-DEFINITION at ${path} has a non-object 'plan.policy' key`);
|
|
187
191
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { referenceTypeMatches } from "@deftai/directive-types";
|
|
4
|
+
import { hasArtifactSuffix, resolveLifecycleRoot } from "../../layout/resolve.js";
|
|
3
5
|
import { subscriptionHash } from "./normalize.js";
|
|
4
6
|
import { pyListRepr } from "./python-repr.js";
|
|
5
7
|
const LIFECYCLE_FOLDERS = ["proposed", "pending", "active", "completed", "cancelled"];
|
|
6
8
|
export function extractReferencedIssues(projectRoot, lifecycleFolders = LIFECYCLE_FOLDERS) {
|
|
7
|
-
const root =
|
|
9
|
+
const root = resolveLifecycleRoot(projectRoot);
|
|
8
10
|
const anySet = new Set();
|
|
9
11
|
const activeSet = new Set();
|
|
10
12
|
if (!existsSync(root))
|
|
@@ -14,7 +16,7 @@ export function extractReferencedIssues(projectRoot, lifecycleFolders = LIFECYCL
|
|
|
14
16
|
if (!existsSync(folderPath))
|
|
15
17
|
continue;
|
|
16
18
|
for (const name of readdirSync(folderPath)) {
|
|
17
|
-
if (!name
|
|
19
|
+
if (!hasArtifactSuffix(name))
|
|
18
20
|
continue;
|
|
19
21
|
const vbriefPath = join(folderPath, name);
|
|
20
22
|
let data;
|
|
@@ -36,7 +38,7 @@ export function extractReferencedIssues(projectRoot, lifecycleFolders = LIFECYCL
|
|
|
36
38
|
if (typeof ref !== "object" || ref === null || Array.isArray(ref))
|
|
37
39
|
continue;
|
|
38
40
|
const rec = ref;
|
|
39
|
-
if (rec.type
|
|
41
|
+
if (!referenceTypeMatches(String(rec.type ?? ""), "github-issue"))
|
|
40
42
|
continue;
|
|
41
43
|
const uri = rec.uri;
|
|
42
44
|
if (typeof uri !== "string")
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import { readPlanPolicy } from "../../policy/plan-extensions.js";
|
|
3
4
|
import { DEFAULT_TRIAGE_SCOPE, PROJECT_DEFINITION_REL_PATH } from "./constants.js";
|
|
4
5
|
export function projectDefinitionPath(projectRoot) {
|
|
5
6
|
return join(resolve(projectRoot), PROJECT_DEFINITION_REL_PATH);
|
|
@@ -24,7 +25,7 @@ export function isDefaultApplied(data) {
|
|
|
24
25
|
const plan = data.plan;
|
|
25
26
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan))
|
|
26
27
|
return true;
|
|
27
|
-
const policy = plan
|
|
28
|
+
const policy = readPlanPolicy(plan);
|
|
28
29
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy))
|
|
29
30
|
return true;
|
|
30
31
|
const scope = policy.triageScope;
|
|
@@ -36,7 +37,7 @@ export function getRawScope(data) {
|
|
|
36
37
|
const plan = data.plan;
|
|
37
38
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan))
|
|
38
39
|
return undefined;
|
|
39
|
-
const policy = plan
|
|
40
|
+
const policy = readPlanPolicy(plan);
|
|
40
41
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy))
|
|
41
42
|
return undefined;
|
|
42
43
|
return policy.triageScope;
|
|
@@ -47,7 +48,7 @@ export function getRawIgnores(data) {
|
|
|
47
48
|
const plan = data.plan;
|
|
48
49
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan))
|
|
49
50
|
return [];
|
|
50
|
-
const policy = plan
|
|
51
|
+
const policy = readPlanPolicy(plan);
|
|
51
52
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy))
|
|
52
53
|
return [];
|
|
53
54
|
const raw = policy.triageScopeIgnores;
|
|
@@ -65,7 +66,7 @@ export function resolveScopeRules(projectRoot, projectDefinition) {
|
|
|
65
66
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
|
|
66
67
|
return DEFAULT_TRIAGE_SCOPE.map((r) => ({ ...r }));
|
|
67
68
|
}
|
|
68
|
-
const policy = plan
|
|
69
|
+
const policy = readPlanPolicy(plan);
|
|
69
70
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
|
70
71
|
return DEFAULT_TRIAGE_SCOPE.map((r) => ({ ...r }));
|
|
71
72
|
}
|
|
@@ -91,7 +92,7 @@ export function resolveScopeIgnores(projectRoot, projectDefinition) {
|
|
|
91
92
|
const plan = data.plan;
|
|
92
93
|
if (typeof plan !== "object" || plan === null || Array.isArray(plan))
|
|
93
94
|
return out;
|
|
94
|
-
const policy = plan
|
|
95
|
+
const policy = readPlanPolicy(plan);
|
|
95
96
|
if (typeof policy !== "object" || policy === null || Array.isArray(policy))
|
|
96
97
|
return out;
|
|
97
98
|
const raw = policy.triageScopeIgnores;
|