@webpieces/rules-config 0.4.786 → 0.4.787
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/package.json +1 -1
- package/src/aged-tree-sweep.d.ts +4 -1
- package/src/aged-tree-sweep.js +4 -1
- package/src/aged-tree-sweep.js.map +1 -1
- package/src/index.d.ts +3 -0
- package/src/index.js +11 -1
- package/src/index.js.map +1 -1
- package/src/repo-scratch-dirs.d.ts +20 -0
- package/src/repo-scratch-dirs.js +54 -0
- package/src/repo-scratch-dirs.js.map +1 -0
- package/src/spec-temp-dirs.d.ts +37 -0
- package/src/spec-temp-dirs.js +112 -0
- package/src/spec-temp-dirs.js.map +1 -0
- package/src/tmp-scratch-sweep.d.ts +32 -0
- package/src/tmp-scratch-sweep.js +99 -0
- package/src/tmp-scratch-sweep.js.map +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/rules-config",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.787",
|
|
4
4
|
"description": "Shared webpieces.config.json loader. Single source of truth for validation rule configuration consumed by @webpieces/ai-hook-rules, @webpieces/code-rules, and @webpieces/nx-webpieces-rules.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/aged-tree-sweep.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* How long a file survives an AGED-TREE SWEEP without being rewritten — the policy `cleanTmp` applies
|
|
3
|
-
* to `{repo}/.webpieces
|
|
3
|
+
* to `{repo}/.webpieces`.
|
|
4
|
+
*
|
|
5
|
+
* It is NOT the only root webpieces writes under, though this comment used to say so: scratch trees go
|
|
6
|
+
* to `os.tmpdir()` as well, on a much shorter cutoff and through `TmpScratchSweeper`. See that file.
|
|
4
7
|
*
|
|
5
8
|
* NOT the same knob as `DEFAULT_RETENTION_DAYS` in review-provenance.ts, which happens to be 30 as well.
|
|
6
9
|
* That one is a CONFIGURABLE ceiling on reviewer transcripts, overridable per repo in settings; this one
|
package/src/aged-tree-sweep.js
CHANGED
|
@@ -7,7 +7,10 @@ const path = tslib_1.__importStar(require("path"));
|
|
|
7
7
|
const inversify_1 = require("inversify");
|
|
8
8
|
/**
|
|
9
9
|
* How long a file survives an AGED-TREE SWEEP without being rewritten — the policy `cleanTmp` applies
|
|
10
|
-
* to `{repo}/.webpieces
|
|
10
|
+
* to `{repo}/.webpieces`.
|
|
11
|
+
*
|
|
12
|
+
* It is NOT the only root webpieces writes under, though this comment used to say so: scratch trees go
|
|
13
|
+
* to `os.tmpdir()` as well, on a much shorter cutoff and through `TmpScratchSweeper`. See that file.
|
|
11
14
|
*
|
|
12
15
|
* NOT the same knob as `DEFAULT_RETENTION_DAYS` in review-provenance.ts, which happens to be 30 as well.
|
|
13
16
|
* That one is a CONFIGURABLE ceiling on reviewer transcripts, overridable per repo in settings; this one
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aged-tree-sweep.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/aged-tree-sweep.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,mDAA6B;AAC7B,yCAA2D;AAE3D
|
|
1
|
+
{"version":3,"file":"aged-tree-sweep.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/aged-tree-sweep.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,mDAA6B;AAC7B,yCAA2D;AAE3D;;;;;;;;;;;GAWG;AACU,QAAA,cAAc,GAAG,EAAE,CAAC;AAEjC,wGAAwG;AACxG,MAAa,UAAU;IACnB,KAAK,CAAS;IACd,IAAI,CAAS;IAEb,YAAY,KAAK,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,KAAiB;QACjB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;IAC/C,CAAC;CACJ;AAjBD,gCAiBC;AAED;;;;;;;;;;;GAWG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAe;IACxB;;;;;;OAMG;IACH,KAAK,CAAC,IAAY,EAAE,QAAgB,EAAE,WAAsD,GAAS,EAAE,GAAE,CAAC;QACtG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,UAAU,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjE,CAAC;IAED,mGAAmG;IACnG,wDAAwD;IACxD,yDAAyD;IACjD,IAAI,CAAC,GAAW,EAAE,GAAW,EAAE,QAAgB,EAAE,MAAe,EAAE,QAAmD;QACzH,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,6FAA6F;YAC7F,wFAAwF;YACxF,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC/D,CAAC;iBAAM,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,CAAC;gBACxC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACjC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACtB,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;YACrB,CAAC;QACL,CAAC;QACD,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAClB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpB,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ,CAAA;AAtCY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,sBAAU,EAAC,8BAAkB,CAAC,SAAS,CAAC;GAC5B,eAAe,CAsC3B","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { injectable, bindingScopeValues } from 'inversify';\n\n/**\n * How long a file survives an AGED-TREE SWEEP without being rewritten — the policy `cleanTmp` applies\n * to `{repo}/.webpieces`.\n *\n * It is NOT the only root webpieces writes under, though this comment used to say so: scratch trees go\n * to `os.tmpdir()` as well, on a much shorter cutoff and through `TmpScratchSweeper`. See that file.\n *\n * NOT the same knob as `DEFAULT_RETENTION_DAYS` in review-provenance.ts, which happens to be 30 as well.\n * That one is a CONFIGURABLE ceiling on reviewer transcripts, overridable per repo in settings; this one\n * is the fixed sweep cutoff and nothing reads it from config. Same number today, different decisions,\n * so folding them would couple a repo's transcript-retention preference to when scratch dirs are reaped.\n */\nexport const RETENTION_DAYS = 30;\n\n/** What one sweep reaped: files deleted for age, and directories pruned because they ended up empty. */\nexport class SweepCount {\n files: number;\n dirs: number;\n\n constructor(files = 0, dirs = 0) {\n this.files = files;\n this.dirs = dirs;\n }\n\n add(other: SweepCount): void {\n this.files += other.files;\n this.dirs += other.dirs;\n }\n\n get empty(): boolean {\n return this.files === 0 && this.dirs === 0;\n }\n}\n\n/**\n * The 30-day depth-first reap, as ONE implementation.\n *\n * It was written inside `CleanTmp` for `<primary>/.webpieces`, and extracted here when a second root\n * (the machine-global PR-body store) needed the identical policy. That second root is gone — the gated\n * merge body is the PR's own description now, see `decisions/0005` — so today there is one caller. The\n * loop stays extracted anyway: it is the sweep policy, testable on its own root, and `CleanTmp` reads\n * as the command it is rather than as a deletion algorithm.\n *\n * `onDelete` is a reporter, not a policy hook: it is told what was removed AFTER the decision, so a\n * caller can print a line and cannot change the outcome.\n */\n@injectable(bindingScopeValues.Singleton)\nexport class AgedTreeSweeper {\n /**\n * Delete every file under `root` older than `cutoffMs`, then prune every directory left empty.\n * `root` itself is swept INTO but never removed — every writer `mkdirSync`s its target, so an empty\n * root is harmless, whereas removing it can race a concurrent writer.\n *\n * A missing `root` is a no-op, not an error.\n */\n sweep(root: string, cutoffMs: number, onDelete: (removed: string, isDir: boolean) => void = (): void => {}): SweepCount {\n if (!fs.existsSync(root)) return new SweepCount();\n return this.walk(root, Date.now(), cutoffMs, true, onDelete);\n }\n\n // Depth-first, POST-order: children first, so a directory whose last file just aged out is seen as\n // empty on the way back up and pruned in the same pass.\n // eslint-disable-next-line @typescript-eslint/max-params\n private walk(dir: string, now: number, cutoffMs: number, isRoot: boolean, onDelete: (removed: string, isDir: boolean) => void): SweepCount {\n const count = new SweepCount();\n for (const entry of fs.readdirSync(dir)) {\n const full = path.join(dir, entry);\n // lstat, never stat: a symlink is a leaf that ages out like a file and is NEVER followed, so\n // a sweep can never wander outside `dir` or delete somebody else's file through a link.\n const stat = fs.lstatSync(full);\n if (stat.isDirectory()) {\n count.add(this.walk(full, now, cutoffMs, false, onDelete));\n } else if (now - stat.mtimeMs >= cutoffMs) {\n fs.rmSync(full, { force: true });\n onDelete(full, false);\n count.files += 1;\n }\n }\n if (!isRoot && fs.readdirSync(dir).length === 0) {\n fs.rmdirSync(dir);\n onDelete(dir, true);\n count.dirs += 1;\n }\n return count;\n }\n}\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -83,3 +83,6 @@ export type { MutationVerb, MutationPhase } from './branch-mutation-log';
|
|
|
83
83
|
export { BranchMutationEvent, BranchMutationLog, branchMutationLogPath, logBranchMutation, } from './branch-mutation-log';
|
|
84
84
|
export { CommandsConfig, buildCommandsConfig, DEFAULT_UPSERT_PR_COMMAND, DEFAULT_MERGE_COMPLETE_COMMAND, } from './commands-config';
|
|
85
85
|
export { StaleBinRemoval, StaleBinSweeper, staleBinSweeper } from './stale-bin-sweep';
|
|
86
|
+
export { SpecTempDirs, specTempDirs } from './spec-temp-dirs';
|
|
87
|
+
export { RepoScratchDirs, SCRATCH_DIR_NAME } from './repo-scratch-dirs';
|
|
88
|
+
export { TmpScratchSweeper, TMP_SCRATCH_RETENTION_DAYS, TMP_SCRATCH_PREFIX } from './tmp-scratch-sweep';
|
package/src/index.js
CHANGED
|
@@ -8,7 +8,7 @@ exports.LandPrConfig = exports.DEFAULT_BUILD_COMMAND = exports.PrGateConfig = ex
|
|
|
8
8
|
exports.DEFAULT_RETENTION_DAYS = exports.ProvenanceWriteRequest = exports.OfferedContext = exports.ReviewerPaths = exports.ReviewerTranscript = exports.ReviewProvenance = exports.ReviewProvenanceService = exports.PROVENANCE_SKIPPED = exports.PROVENANCE_MISSING = exports.PROVENANCE_OK = exports.ProvenanceResult = exports.TranscriptScan = exports.ExpectedReviewer = exports.ReviewerContext = exports.ReviewerEvidence = exports.SubagentProvenanceService = exports.verifyGateToken = exports.extractGateToken = exports.gateTokenMarker = exports.computeGateToken = exports.GateTokenService = exports.ALL_DIFF_ONE_READ_LINES = exports.READ_TRUNCATION_LINES = exports.ContextEntry = exports.BriefedFile = exports.ReviewerBriefing = exports.ReviewerInstructionsService = exports.ChecklistInstructionsService = exports.ChecklistValidator = exports.formatFileList = exports.normalizeChecklistDoc = exports.toChecklist = exports.DEFAULT_REVIEWER_AGENT_NAME = exports.REVIEWER_AGENTS_PLACEHOLDER = exports.ReviewerAgentPolicy = exports.ChecklistDefinition = exports.MERGE_MODES = exports.MERGE_MODE_NONE = exports.MERGE_MODE_AUTO = exports.buildDevDeployConfig = exports.buildLandPrConfig = exports.buildPrGateConfig = exports.defaultDevDeployConfig = exports.defaultLandPrConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.ReviewContextEntry = exports.DEFAULT_DEV_BRANCH = exports.DEFAULT_DEV_BRANCH_NAMESPACE = exports.DevDeployConfig = void 0;
|
|
9
9
|
exports.MergedBranch = exports.squashRecoverySteps = exports.stampCleanMainSyncStatus = exports.computeMainSyncStatus = exports.finishedLock = exports.inProcessLock = exports.tryAcquireMainSyncLock = exports.isRefreshInProgress = exports.isLockStale = exports.writeMainSyncLock = exports.readMainSyncLock = exports.computeAllMainSyncStatuses = exports.writeMainSyncStatusFile = exports.writeMainSyncStatus = exports.readMainSyncStatusFile = exports.readMainSyncStatus = exports.mainSyncLockPath = exports.mainSyncStatusPath = exports.DEFAULT_HANG_TIMEOUT_MINUTES = exports.MainSyncStatusService = exports.MainSyncLock = exports.MAIN_SYNC_STATUS_VERSION = exports.PullRequestIndex = exports.MainSyncFileStore = exports.MainSyncStatusFile = exports.MainSyncStatus = exports.reviewJsonSchemaHint = exports.reviewJsonPath = exports.prDirFor = exports.ReviewJsonService = exports.ChecklistReviewContext = exports.RequiredChecklist = exports.SINGLE_ROUND_MAIN_AGENT_INSTRUCTIONS = exports.VERDICT_STATUSES = exports.VERDICT_RED = exports.VERDICT_YELLOW = exports.VERDICT_GREEN = exports.CK_BAD_FORMAT = exports.CK_MISSING = exports.CK_FAIL = exports.CK_OVERRIDDEN = exports.CK_WARN = exports.CK_PASS = exports.checklistOverrideService = exports.ChecklistOverrideService = exports.ChecklistOverride = exports.ChecklistVerdict = exports.ChecklistResult = exports.PrContext = exports.ReviewJson = void 0;
|
|
10
10
|
exports.BranchMutationLog = exports.BranchMutationEvent = exports.WorktreeReaper = exports.WorktreeReapResult = exports.ReapedWorktree = exports.BranchReaper = exports.ReapResult = exports.ReapedBranch = exports.HarnessAgentActivityReader = exports.AgentActivity = exports.AGENT_TRANSCRIPT_QUIET_MS = exports.AGENT_ACTIVITY_UNKNOWN = exports.AGENT_ACTIVITY_RETURNED = exports.AGENT_ACTIVITY_LIVE = exports.WorktreeLockVerdicts = exports.LockEvidence = exports.LockDecision = exports.LOCK_LIVENESS_UNVERIFIABLE = exports.HARNESS_NOT_CONSULTED = exports.AgentWorktreeLockReader = exports.AgentWorktreeLock = exports.WorktreeService = exports.WorktreeWorkInFlight = exports.Worktree = exports.BRANCH_RETENTION_KEEP = exports.BRANCH_RETENTION_ARCHIVE_TAG = exports.BRANCH_RETENTION_DELETE = exports.BRANCH_RETENTIONS = exports.ARCHIVE_TAG_PREFIX = exports.ArchiveResult = exports.BranchArchiver = exports.ADJUDICATED_CLASSIFICATIONS = exports.CLASSIFICATION_DETACHED = exports.CLASSIFICATION_CURRENT = exports.CLASSIFICATION_LOCKED = exports.CLASSIFICATION_PRUNABLE = exports.CLASSIFICATION_IN_USE = exports.CLASSIFICATION_NEVER_PROPOSED = exports.CLASSIFICATION_CONTENT_IN_MAIN = exports.CLASSIFICATION_SUPERSEDED = exports.CLASSIFICATION_NO_COMMITS = exports.CLASSIFICATION_BACKUP_OF_LIVE = exports.CLASSIFICATION_BACKUP_OF_MERGED = exports.CLASSIFICATION_MERGED_PR = exports.CACHE_STALE_AFTER_MS = exports.CacheFreshness = exports.MergedBranchesService = exports.MergedBranchesCache = exports.DeletableWorktree = exports.DeletableBranch = void 0;
|
|
11
|
-
exports.staleBinSweeper = exports.StaleBinSweeper = exports.StaleBinRemoval = exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.logBranchMutation = exports.branchMutationLogPath = void 0;
|
|
11
|
+
exports.TMP_SCRATCH_PREFIX = exports.TMP_SCRATCH_RETENTION_DAYS = exports.TmpScratchSweeper = exports.SCRATCH_DIR_NAME = exports.RepoScratchDirs = exports.specTempDirs = exports.SpecTempDirs = exports.staleBinSweeper = exports.StaleBinSweeper = exports.StaleBinRemoval = exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.logBranchMutation = exports.branchMutationLogPath = void 0;
|
|
12
12
|
var types_1 = require("./types");
|
|
13
13
|
Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
|
|
14
14
|
Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
|
|
@@ -541,4 +541,14 @@ var stale_bin_sweep_1 = require("./stale-bin-sweep");
|
|
|
541
541
|
Object.defineProperty(exports, "StaleBinRemoval", { enumerable: true, get: function () { return stale_bin_sweep_1.StaleBinRemoval; } });
|
|
542
542
|
Object.defineProperty(exports, "StaleBinSweeper", { enumerable: true, get: function () { return stale_bin_sweep_1.StaleBinSweeper; } });
|
|
543
543
|
Object.defineProperty(exports, "staleBinSweeper", { enumerable: true, get: function () { return stale_bin_sweep_1.staleBinSweeper; } });
|
|
544
|
+
var spec_temp_dirs_1 = require("./spec-temp-dirs");
|
|
545
|
+
Object.defineProperty(exports, "SpecTempDirs", { enumerable: true, get: function () { return spec_temp_dirs_1.SpecTempDirs; } });
|
|
546
|
+
Object.defineProperty(exports, "specTempDirs", { enumerable: true, get: function () { return spec_temp_dirs_1.specTempDirs; } });
|
|
547
|
+
var repo_scratch_dirs_1 = require("./repo-scratch-dirs");
|
|
548
|
+
Object.defineProperty(exports, "RepoScratchDirs", { enumerable: true, get: function () { return repo_scratch_dirs_1.RepoScratchDirs; } });
|
|
549
|
+
Object.defineProperty(exports, "SCRATCH_DIR_NAME", { enumerable: true, get: function () { return repo_scratch_dirs_1.SCRATCH_DIR_NAME; } });
|
|
550
|
+
var tmp_scratch_sweep_1 = require("./tmp-scratch-sweep");
|
|
551
|
+
Object.defineProperty(exports, "TmpScratchSweeper", { enumerable: true, get: function () { return tmp_scratch_sweep_1.TmpScratchSweeper; } });
|
|
552
|
+
Object.defineProperty(exports, "TMP_SCRATCH_RETENTION_DAYS", { enumerable: true, get: function () { return tmp_scratch_sweep_1.TMP_SCRATCH_RETENTION_DAYS; } });
|
|
553
|
+
Object.defineProperty(exports, "TMP_SCRATCH_PREFIX", { enumerable: true, get: function () { return tmp_scratch_sweep_1.TMP_SCRATCH_PREFIX; } });
|
|
544
554
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { RuleFailError, renderRuleFailForAi, renderRuleFailForHuman } from './rule-fail-error';\n// THE one representation of a cure, shared by RuleFailError (build-time) and FixHint (edit-time), plus\n// the one renderer that owns the \"Fix Option N:\" numbering and the \"(preferred)\" tag.\nexport { Option, formatFixOptions } from './fix-option';\nexport { CliExitError } from './cli-exit-error';\nexport { CliUsage, CliFlag, CliArgSet, CliArgsCheck, CliArgs } from './cli-args';\nexport { runMain } from './run-main';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig, ConfigLoader } from './load-config';\n// The validation-failure banner: ONE cure (edit the file), plus the marker phrases the validator\n// messages embed rather than re-type.\nexport {\n formatConfigErrorsBanner,\n CONFIG_POLICY_DOC,\n RETIRED_KEY_MARKER,\n RETIRED_TOP_LEVEL_MARKER,\n SECTION_PLACEMENT_MARKER,\n} from './config-error-banner';\nexport {\n findConfigFile,\n CONFIG_FILENAME,\n ConfigFile,\n ConfigParseAttempt,\n CONFIG_PARSE_ATTEMPTS,\n CONFIG_PARSE_RETRY_MILLIS,\n} from './config-file';\n// The PARSED-BUT-UNVALIDATED config shape. Exported for readers that walk the file generically rather\n// than through the typed config (the pr-gate active-hatch dashboard section reads every rule's hatches).\nexport type { RawConfigFile } from './config-file';\nexport { RepoRootFinder, INSTRUCT_AI_DIR, INSTRUCT_AI_LEAF } from './repo-root';\n// The scoped `.webpieces` resolver. EVERY reader/writer of `.webpieces/...` goes through one of its two\n// named methods so the call site declares whether the state is repo-wide or worktree-private.\nexport {\n DotWebpieces,\n dotWebpieces,\n GitDirs,\n WORKTREE_STATE_DIR,\n LOGS_STATE_DIR,\n} from './state-dir';\nexport { StateDirMigrator, StateMigrationReport } from './state-dir-migration';\n// There is NO machine-global state root. `MachineStateHome`/`StateHome`/`WEBPIECES_STATE_HOME` and the\n// `PrBodyStore` that used them are DELETED: the one artifact that needed a scope above the clone was the\n// gated squash body, and GitHub holds it now (it IS the PR description). Every `.webpieces` path a\n// webpieces tool writes is `{repo}/.webpieces`, resolved through `DotWebpieces` above. See\n// `decisions/0005-the-pr-description-is-the-merge-body.md`.\nexport { AgedTreeSweeper, SweepCount, RETENTION_DAYS } from './aged-tree-sweep';\nexport {\n ClaudeEnv,\n claudeEnv,\n CLAUDE_PROJECT_DIR_ENV,\n CLAUDE_PROJECT_DIR_UNSET,\n} from './claude-env';\nexport { AtomicFile } from './atomic-file';\n// The ONE formatter for a remedy that must run in a named directory: `cd '<root>' && <command>`.\n// Single-quoted so a repo path containing a space is still runnable (and still un-smuggleable).\nexport { atRoot } from './at-root';\nexport { RulesConfigDesign } from './rules-config-design';\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './di';\nexport { ExcludePaths, isWebpiecesStateDir } from './exclude-hook-paths';\nexport { isPathExcluded, matchesAnyGlob } from './exclude-paths';\n// The machine-generated trees a line-count rule never fires on. A FLOOR, not a default value:\n// `max-file-lines.allowedPaths` adds to it, so configuring your own tree cannot lose it.\nexport { GENERATED_CODE_PATHS } from './generated-code-paths';\n// THE one `no-custom-css` path exemption. Both engines that enforce the rule (the edit-time hook and the\n// CI validator) consult this class, so `allowGlobs` cannot be honoured by one half and ignored by the other.\nexport { NoCustomCssScope } from './no-custom-css-scope';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport {\n loadTemplate,\n writeTemplateIfMissing,\n writeTemplate,\n TemplateWriter,\n} from './load-template';\n// The instruct-ai docs are delivered as a SET: writing one writes the transitive closure of the docs it\n// links to, so a doc and everything it points at always land together. See instruct-ai-docs.ts.\nexport {\n GIT_WORKFLOW_DOC,\n GitWorkflowDoc,\n InstructAiDoc,\n InstructAiDocSet,\n MergeProcessDoc,\n} from './instruct-ai-docs';\nexport {\n MERGE_PROCESS_DOC,\n MergeProcessText,\n MergeRun,\n ReferenceMergeRun,\n} from './merge-process-doc';\nexport { BUILD_LOG_DOC } from './build-log-doc';\nexport {\n validateWebpiecesConfig,\n validatePrGateSection,\n validateChecklistsSection,\n validateSectionPlacement,\n validateExcludePaths,\n validateMatchRulesSection,\n allRuleNames,\n recommendedSeedMode,\n recommendedSeedModeFor,\n seedEntryForRule,\n} from './validate-config';\nexport { validateCommandsSection } from './commands-section-validators';\nexport {\n unknownKeyErrors,\n isCommentKey,\n validateTopLevelKeys,\n COMMENT_KEY_SUFFIX,\n} from './config-key-rules';\n// The retired-key table + the no-back-compat policy it enforces. Exported so the installer can migrate\n// what the errors instruct, and so consumers can enumerate retirements.\nexport {\n RETIRED_CONFIG_KEYS,\n RETIRED_SCOPE_KEY,\n RETIRED_SCOPE_RULE,\n RetiredConfigKey,\n isRetiredKey,\n retiredEntry,\n retiredKeyError,\n retiredKeyErrorsIn,\n retiredRuleFor,\n} from './retired-config-keys';\n// The MECHANICAL cure the unknown-rule error and the banner both name: strip every key no validator has a\n// schema for, so cleanliness is one command rather than a judgement call made while every Bash call is\n// blocked. `PRUNE_UNKNOWN_COMMAND` (constants.ts) is the single spelling of that command.\nexport { ConfigPruner, PruneResult, PrunedKey } from './config-pruner';\nexport { validateChecklistDocs } from './checklist-docs-validator';\n// The OPTIONAL machine-local `~/.webpieces/config.json`: absent (the normal state for every consumer) means\n// each key's declared default, silently; present means STRICT about what it understands and FORWARD-COMPATIBLE\n// about what it does not. A retired key (its own retirement table), a known key of the wrong TYPE and an\n// unparseable document all REJECT; a key this release simply does not recognise is IGNORED with a warning,\n// because the file is machine-global and the repos reading it pin different releases — rejecting a newer\n// release's key would hard-block every repo on the machine that is not yet on it. See home-config.ts.\n// `isHomeConfigPath` is what grants the file its unconditional Write/Edit PASS in the hook guards, which is\n// what keeps a rejection repairable. Every `experimental.*` key is an OPT-IN that defaults OFF, including\n// `whole-repo-build-guard`: ON requires an explicit `true`, and there is no per-key default to export.\nexport {\n HomeConfig,\n HomeConfigService,\n RetiredHomeConfigKey,\n RETIRED_HOME_CONFIG_KEYS,\n HOME_CONFIG_DIR,\n HOME_CONFIG_FILE,\n HOME_EXPERIMENTAL_SECTION,\n HOME_KEY_ORPHAN_DIR_SWEEP,\n HOME_KEY_WHOLE_REPO_BUILD_GUARD,\n HOME_KEY_MAX_CONCURRENT_BUILDS,\n HOME_KEY_TURN_OFF_ALL_REVIEWERS,\n HOME_KEY_SINGLE_ROUND_REVIEW,\n DEFAULT_MAX_CONCURRENT_BUILDS,\n HOME_KEY_DOC,\n HOME_KEY_AI_DOC,\n DOCUMENTATION_KEYS,\n} from './home-config';\n// The MACHINE-WIDE build ledger, `~/.webpieces/builds.log`. THE one carve-out from\n// `no-machine-global-state.spec.ts`'s rule that webpieces writes only under `{repo}/.webpieces` — the\n// argument is in `decisions/0006-the-build-ledger-is-machine-global.md`, and the short form is that \"how\n// many builds are burning this box's CPU\" is a fact about the MACHINE, is not a cache of anything a\n// remote owns, and cannot be answered from a per-repo file because every linked worktree has its own\n// `.webpieces/` and would be blind to the sibling it is contending with. See builds-log.ts.\nexport {\n BuildsLog,\n BuildTicket,\n BuildTermination,\n RunningBuild,\n BUILDS_LOG_FILE,\n BUILDS_LOCK_FILE,\n BUILD_START,\n BUILD_DONE_SUCCESS,\n BUILD_DONE_FAIL,\n MAX_BUILDS_LOG_BYTES,\n BUILDS_LOG_GENERATIONS,\n MAX_ROW_BYTES,\n} from './builds-log';\n// The orphan-directory sweep: the corpse an `nx g move` leaves on every clone, which git cannot remove\n// because an ignored dist/ or node_modules/ outlives every tracked file under it. See orphan-dir-scan.ts\n// for why the predicate is git's own `clean -Xdn` answer rather than a hand-rolled ignore walk.\nexport { OrphanDirScanner, OrphanCandidate } from './orphan-dir-scan';\nexport {\n OrphanDirArchiver,\n ArchivedOrphan,\n FailedOrphan,\n OrphanSweepResult,\n OrphanSweepManifest,\n TRASH_STATE_DIR,\n TRASH_MANIFEST_FILE,\n TRASH_RETENTION_DAYS,\n} from './orphan-dir-archive';\nexport { OrphanDirSweeper, OrphanSweepReport } from './orphan-dir-sweep';\nexport {\n MatchRuleConfig,\n MatchRuleViolation,\n findMatchRuleViolations,\n isMatchRuleAllowedPath,\n compileMatchRulePatterns,\n renderMatchRuleMessage,\n DEFAULT_MATCH_RULES,\n} from './match-rules-config';\nexport type { ConfigSection } from './sections';\nexport { schemaFieldNames } from './rule-schemas';\nexport {\n HOOK_GUARD_NAMES,\n BRANCH_STATE_GUARD_KEY,\n PR_LIFECYCLE_GUARD_KEY,\n isHookGuard,\n sectionForRule,\n} from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport { SkipRuleResult } from './skip-rule';\nexport {\n detectBase,\n resolveBase,\n getChangedFiles,\n getFileDiff,\n getChangedLineNumbers,\n findNewMethodSignaturesInDiff,\n hasChangesInRange,\n isNewOrModified,\n DiffScope,\n DiffRange,\n ChangedFilesOptions,\n} from './diff-scope';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_INFO_DIR,\n PR_REVIEW_DIR,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n PUSH_DEV_STATE_FILE,\n PRUNE_UNKNOWN_COMMAND,\n UPGRADE_SHIM_COMMAND,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n SyncFlowGuidance,\n WP_START_UPDATE,\n WP_FINISH_UPDATE,\n WP_START_UPSERT_PR,\n WP_FINISH_UPSERT_PR,\n WP_PUSH_DEV,\n WP_FINISH_PUSH_DEV,\n} from './sync-flow-guidance';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n EnsureWeAreSecureConfig,\n BranchCreationGuardConfig,\n PrLifecycleGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n ValidateArchitectureUnchangedConfig,\n ValidateNoArchitectureCyclesConfig,\n ValidatePackageJsonConfig,\n ValidateVersionsLockedConfig,\n ValidateEslintSyncConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PROJECT_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n STRUCTURAL_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport {\n NoClientCreationOutsideServerOrClientConfig,\n CLIENT_CREATION_SEVERITIES,\n} from './no-client-creation-config';\nexport type { ClientCreationSeverity } from './no-client-creation-config';\n// The `no-state-paths-in-templates` config, in its own module for the same reason no-client-creation is:\n// rule-configs.ts is at its file-size cap and a rule that carries real defaults belongs beside them.\nexport {\n NoStatePathsInTemplatesConfig,\n DEFAULT_TEMPLATE_DIRS,\n DEFAULT_BANNED_STATE_PATH_PREFIXES,\n} from './no-state-paths-config';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n ProjectMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n StructuralMode,\n ValidateTsMode,\n} from './rule-configs';\nexport { BranchStateGuardConfig, DEFAULT_MAX_COMMITS_BEHIND } from './main-sync-guard-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n DEFAULT_BUILD_COMMAND,\n LandPrConfig,\n DevDeployConfig,\n DEFAULT_DEV_BRANCH_NAMESPACE,\n DEFAULT_DEV_BRANCH,\n ReviewContextEntry,\n defaultGates,\n defaultPrGateConfig,\n defaultLandPrConfig,\n defaultDevDeployConfig,\n buildPrGateConfig,\n buildLandPrConfig,\n buildDevDeployConfig,\n MERGE_MODE_AUTO,\n MERGE_MODE_NONE,\n MERGE_MODES,\n} from './pr-gate-config';\nexport {\n ChecklistDefinition,\n ReviewerAgentPolicy,\n REVIEWER_AGENTS_PLACEHOLDER,\n DEFAULT_REVIEWER_AGENT_NAME,\n toChecklist,\n normalizeChecklistDoc,\n formatFileList,\n} from './checklist-config';\nexport type { RawChecklistItem } from './checklist-config';\nexport { ChecklistValidator } from './checklist-validator';\nexport { ChecklistInstructionsService } from './checklist-instructions';\nexport {\n ReviewerInstructionsService,\n ReviewerBriefing,\n BriefedFile,\n ContextEntry,\n READ_TRUNCATION_LINES,\n ALL_DIFF_ONE_READ_LINES,\n} from './reviewer-instructions';\nexport {\n GateTokenService,\n computeGateToken,\n gateTokenMarker,\n extractGateToken,\n verifyGateToken,\n} from './gate-token';\nexport {\n SubagentProvenanceService,\n ReviewerEvidence,\n ReviewerContext,\n ExpectedReviewer,\n TranscriptScan,\n ProvenanceResult,\n PROVENANCE_OK,\n PROVENANCE_MISSING,\n PROVENANCE_SKIPPED,\n} from './subagent-provenance';\nexport {\n ReviewProvenanceService,\n ReviewProvenance,\n ReviewerTranscript,\n ReviewerPaths,\n OfferedContext,\n ProvenanceWriteRequest,\n DEFAULT_RETENTION_DAYS,\n} from './review-provenance';\nexport {\n ReviewJson,\n PrContext,\n ChecklistResult,\n ChecklistVerdict,\n ChecklistOverride,\n ChecklistOverrideService,\n checklistOverrideService,\n CK_PASS,\n CK_WARN,\n CK_OVERRIDDEN,\n CK_FAIL,\n CK_MISSING,\n CK_BAD_FORMAT,\n VERDICT_GREEN,\n VERDICT_YELLOW,\n VERDICT_RED,\n VERDICT_STATUSES,\n SINGLE_ROUND_MAIN_AGENT_INSTRUCTIONS,\n RequiredChecklist,\n ChecklistReviewContext,\n ReviewJsonService,\n prDirFor,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncStatusFile,\n MainSyncFileStore,\n PullRequestIndex,\n MAIN_SYNC_STATUS_VERSION,\n} from './main-sync-file';\nexport {\n MainSyncLock,\n MainSyncStatusService,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n readMainSyncStatusFile,\n writeMainSyncStatus,\n writeMainSyncStatusFile,\n computeAllMainSyncStatuses,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n tryAcquireMainSyncLock,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n MergedBranch,\n DeletableBranch,\n DeletableWorktree,\n MergedBranchesCache,\n MergedBranchesService,\n CacheFreshness,\n CACHE_STALE_AFTER_MS,\n CLASSIFICATION_MERGED_PR,\n CLASSIFICATION_BACKUP_OF_MERGED,\n CLASSIFICATION_BACKUP_OF_LIVE,\n CLASSIFICATION_NO_COMMITS,\n CLASSIFICATION_SUPERSEDED,\n CLASSIFICATION_CONTENT_IN_MAIN,\n CLASSIFICATION_NEVER_PROPOSED,\n CLASSIFICATION_IN_USE,\n CLASSIFICATION_PRUNABLE,\n CLASSIFICATION_LOCKED,\n CLASSIFICATION_CURRENT,\n CLASSIFICATION_DETACHED,\n ADJUDICATED_CLASSIFICATIONS,\n} from './merged-branches';\nexport {\n BranchArchiver,\n ArchiveResult,\n ARCHIVE_TAG_PREFIX,\n BRANCH_RETENTIONS,\n BRANCH_RETENTION_DELETE,\n BRANCH_RETENTION_ARCHIVE_TAG,\n BRANCH_RETENTION_KEEP,\n} from './branch-archiver';\nexport { Worktree, WorktreeWorkInFlight, WorktreeService } from './worktrees';\nexport { AgentWorktreeLock, AgentWorktreeLockReader } from './agent-worktree-lock';\nexport {\n HARNESS_NOT_CONSULTED,\n LOCK_LIVENESS_UNVERIFIABLE,\n LockDecision,\n LockEvidence,\n WorktreeLockVerdicts,\n} from './worktree-lock-verdicts';\nexport {\n AGENT_ACTIVITY_LIVE,\n AGENT_ACTIVITY_RETURNED,\n AGENT_ACTIVITY_UNKNOWN,\n AGENT_TRANSCRIPT_QUIET_MS,\n AgentActivity,\n HarnessAgentActivityReader,\n} from './harness-agent-activity';\nexport { ReapedBranch, ReapResult, BranchReaper } from './branch-reaper';\nexport { ReapedWorktree, WorktreeReapResult, WorktreeReaper } from './worktree-reaper';\nexport type { MutationVerb, MutationPhase } from './branch-mutation-log';\nexport {\n BranchMutationEvent,\n BranchMutationLog,\n branchMutationLogPath,\n logBranchMutation,\n} from './branch-mutation-log';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\nexport { StaleBinRemoval, StaleBinSweeper, staleBinSweeper } from './stale-bin-sweep';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,iCAA0E;AAAjE,uGAAA,cAAc,OAAA;AAAE,2GAAA,kBAAkB,OAAA;AAC3C,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,qDAA+F;AAAtF,gHAAA,aAAa,OAAA;AAAE,sHAAA,mBAAmB,OAAA;AAAE,yHAAA,sBAAsB,OAAA;AACnE,uGAAuG;AACvG,sFAAsF;AACtF,2CAAwD;AAA/C,oGAAA,MAAM,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AACjC,mDAAgD;AAAvC,8GAAA,YAAY,OAAA;AACrB,uCAAiF;AAAxE,oGAAA,QAAQ,OAAA;AAAE,mGAAA,OAAO,OAAA;AAAE,qGAAA,SAAS,OAAA;AAAE,wGAAA,YAAY,OAAA;AAAE,mGAAA,OAAO,OAAA;AAC5D,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAChB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAChB,6CAA4E;AAAnE,8GAAA,eAAe,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,2GAAA,YAAY,OAAA;AACpD,iGAAiG;AACjG,sCAAsC;AACtC,6DAM+B;AAL3B,+HAAA,wBAAwB,OAAA;AACxB,wHAAA,iBAAiB,OAAA;AACjB,yHAAA,kBAAkB,OAAA;AAClB,+HAAA,wBAAwB,OAAA;AACxB,+HAAA,wBAAwB,OAAA;AAE5B,6CAOuB;AANnB,6GAAA,cAAc,OAAA;AACd,8GAAA,eAAe,OAAA;AACf,yGAAA,UAAU,OAAA;AACV,iHAAA,kBAAkB,OAAA;AAClB,oHAAA,qBAAqB,OAAA;AACrB,wHAAA,yBAAyB,OAAA;AAK7B,yCAAgF;AAAvE,2GAAA,cAAc,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAC1D,wGAAwG;AACxG,8FAA8F;AAC9F,yCAMqB;AALjB,yGAAA,YAAY,OAAA;AACZ,yGAAA,YAAY,OAAA;AACZ,oGAAA,OAAO,OAAA;AACP,+GAAA,kBAAkB,OAAA;AAClB,2GAAA,cAAc,OAAA;AAElB,6DAA+E;AAAtE,uHAAA,gBAAgB,OAAA;AAAE,2HAAA,oBAAoB,OAAA;AAC/C,uGAAuG;AACvG,yGAAyG;AACzG,mGAAmG;AACnG,2FAA2F;AAC3F,4DAA4D;AAC5D,qDAAgF;AAAvE,kHAAA,eAAe,OAAA;AAAE,6GAAA,UAAU,OAAA;AAAE,iHAAA,cAAc,OAAA;AACpD,2CAKsB;AAJlB,uGAAA,SAAS,OAAA;AACT,uGAAA,SAAS,OAAA;AACT,oHAAA,sBAAsB,OAAA;AACtB,sHAAA,wBAAwB,OAAA;AAE5B,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,iGAAiG;AACjG,gGAAgG;AAChG,qCAAmC;AAA1B,iGAAA,MAAM,OAAA;AACf,6DAA0D;AAAjD,wHAAA,iBAAiB,OAAA;AAC1B,2BAA8E;AAArE,oGAAA,cAAc,OAAA;AAAE,sGAAA,gBAAgB,OAAA;AAAE,0GAAA,oBAAoB,OAAA;AAC/D,2DAAyE;AAAhE,kHAAA,YAAY,OAAA;AAAE,yHAAA,mBAAmB,OAAA;AAC1C,iDAAiE;AAAxD,+GAAA,cAAc,OAAA;AAAE,+GAAA,cAAc,OAAA;AACvC,8FAA8F;AAC9F,yFAAyF;AACzF,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAC7B,yGAAyG;AACzG,6GAA6G;AAC7G,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA;AACzB,iDAAgE;AAAvD,6GAAA,YAAY,OAAA;AAAE,gHAAA,eAAe,OAAA;AACtC,iDAKyB;AAJrB,6GAAA,YAAY,OAAA;AACZ,uHAAA,sBAAsB,OAAA;AACtB,8GAAA,aAAa,OAAA;AACb,+GAAA,cAAc,OAAA;AAElB,wGAAwG;AACxG,gGAAgG;AAChG,uDAM4B;AALxB,oHAAA,gBAAgB,OAAA;AAChB,kHAAA,cAAc,OAAA;AACd,iHAAA,aAAa,OAAA;AACb,oHAAA,gBAAgB,OAAA;AAChB,mHAAA,eAAe,OAAA;AAEnB,yDAK6B;AAJzB,sHAAA,iBAAiB,OAAA;AACjB,qHAAA,gBAAgB,OAAA;AAChB,6GAAA,QAAQ,OAAA;AACR,sHAAA,iBAAiB,OAAA;AAErB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,qDAW2B;AAVvB,0HAAA,uBAAuB,OAAA;AACvB,wHAAA,qBAAqB,OAAA;AACrB,4HAAA,yBAAyB,OAAA;AACzB,2HAAA,wBAAwB,OAAA;AACxB,uHAAA,oBAAoB,OAAA;AACpB,4HAAA,yBAAyB,OAAA;AACzB,+GAAA,YAAY,OAAA;AACZ,sHAAA,mBAAmB,OAAA;AACnB,yHAAA,sBAAsB,OAAA;AACtB,mHAAA,gBAAgB,OAAA;AAEpB,6EAAwE;AAA/D,sIAAA,uBAAuB,OAAA;AAChC,uDAK4B;AAJxB,oHAAA,gBAAgB,OAAA;AAChB,gHAAA,YAAY,OAAA;AACZ,wHAAA,oBAAoB,OAAA;AACpB,sHAAA,kBAAkB,OAAA;AAEtB,uGAAuG;AACvG,wEAAwE;AACxE,6DAU+B;AAT3B,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,yHAAA,kBAAkB,OAAA;AAClB,uHAAA,gBAAgB,OAAA;AAChB,mHAAA,YAAY,OAAA;AACZ,mHAAA,YAAY,OAAA;AACZ,sHAAA,eAAe,OAAA;AACf,yHAAA,kBAAkB,OAAA;AAClB,qHAAA,cAAc,OAAA;AAElB,0GAA0G;AAC1G,uGAAuG;AACvG,0FAA0F;AAC1F,iDAAuE;AAA9D,6GAAA,YAAY,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,0GAAA,SAAS,OAAA;AAC7C,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA;AAC9B,4GAA4G;AAC5G,+GAA+G;AAC/G,yGAAyG;AACzG,2GAA2G;AAC3G,yGAAyG;AACzG,sGAAsG;AACtG,4GAA4G;AAC5G,0GAA0G;AAC1G,uGAAuG;AACvG,6CAiBuB;AAhBnB,yGAAA,UAAU,OAAA;AACV,gHAAA,iBAAiB,OAAA;AACjB,mHAAA,oBAAoB,OAAA;AACpB,uHAAA,wBAAwB,OAAA;AACxB,8GAAA,eAAe,OAAA;AACf,+GAAA,gBAAgB,OAAA;AAChB,wHAAA,yBAAyB,OAAA;AACzB,wHAAA,yBAAyB,OAAA;AACzB,8HAAA,+BAA+B,OAAA;AAC/B,6HAAA,8BAA8B,OAAA;AAC9B,8HAAA,+BAA+B,OAAA;AAC/B,2HAAA,4BAA4B,OAAA;AAC5B,4HAAA,6BAA6B,OAAA;AAC7B,2GAAA,YAAY,OAAA;AACZ,8GAAA,eAAe,OAAA;AACf,iHAAA,kBAAkB,OAAA;AAEtB,mFAAmF;AACnF,sGAAsG;AACtG,yGAAyG;AACzG,oGAAoG;AACpG,qGAAqG;AACrG,4FAA4F;AAC5F,2CAasB;AAZlB,uGAAA,SAAS,OAAA;AACT,yGAAA,WAAW,OAAA;AACX,8GAAA,gBAAgB,OAAA;AAChB,0GAAA,YAAY,OAAA;AACZ,6GAAA,eAAe,OAAA;AACf,8GAAA,gBAAgB,OAAA;AAChB,yGAAA,WAAW,OAAA;AACX,gHAAA,kBAAkB,OAAA;AAClB,6GAAA,eAAe,OAAA;AACf,kHAAA,oBAAoB,OAAA;AACpB,oHAAA,sBAAsB,OAAA;AACtB,2GAAA,aAAa,OAAA;AAEjB,uGAAuG;AACvG,yGAAyG;AACzG,gGAAgG;AAChG,qDAAsE;AAA7D,mHAAA,gBAAgB,OAAA;AAAE,kHAAA,eAAe,OAAA;AAC1C,2DAS8B;AAR1B,uHAAA,iBAAiB,OAAA;AACjB,oHAAA,cAAc,OAAA;AACd,kHAAA,YAAY,OAAA;AACZ,uHAAA,iBAAiB,OAAA;AACjB,yHAAA,mBAAmB,OAAA;AACnB,qHAAA,eAAe,OAAA;AACf,yHAAA,mBAAmB,OAAA;AACnB,0HAAA,oBAAoB,OAAA;AAExB,uDAAyE;AAAhE,oHAAA,gBAAgB,OAAA;AAAE,qHAAA,iBAAiB,OAAA;AAC5C,2DAQ8B;AAP1B,qHAAA,eAAe,OAAA;AACf,wHAAA,kBAAkB,OAAA;AAClB,6HAAA,uBAAuB,OAAA;AACvB,4HAAA,sBAAsB,OAAA;AACtB,8HAAA,wBAAwB,OAAA;AACxB,4HAAA,sBAAsB,OAAA;AACtB,yHAAA,mBAAmB,OAAA;AAGvB,+CAAkD;AAAzC,gHAAA,gBAAgB,OAAA;AACzB,uCAMoB;AALhB,4GAAA,gBAAgB,OAAA;AAChB,kHAAA,sBAAsB,OAAA;AACtB,kHAAA,sBAAsB,OAAA;AACtB,uGAAA,WAAW,OAAA;AACX,0GAAA,cAAc,OAAA;AAElB,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA;AAEjB,yCAA+D;AAAtD,2GAAA,cAAc,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AACzC,yCAA6C;AAApC,2GAAA,cAAc,OAAA;AACvB,2CAYsB;AAXlB,wGAAA,UAAU,OAAA;AACV,yGAAA,WAAW,OAAA;AACX,6GAAA,eAAe,OAAA;AACf,yGAAA,WAAW,OAAA;AACX,mHAAA,qBAAqB,OAAA;AACrB,2HAAA,6BAA6B,OAAA;AAC7B,+GAAA,iBAAiB,OAAA;AACjB,6GAAA,eAAe,OAAA;AACf,uGAAA,SAAS,OAAA;AACT,uGAAA,SAAS,OAAA;AACT,iHAAA,mBAAmB,OAAA;AAEvB,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,yCAYqB;AAXjB,8GAAA,iBAAiB,OAAA;AACjB,uGAAA,UAAU,OAAA;AACV,uGAAA,UAAU,OAAA;AACV,8GAAA,iBAAiB,OAAA;AACjB,2GAAA,cAAc,OAAA;AACd,0GAAA,aAAa,OAAA;AACb,mHAAA,sBAAsB,OAAA;AACtB,mHAAA,sBAAsB,OAAA;AACtB,gHAAA,mBAAmB,OAAA;AACnB,kHAAA,qBAAqB,OAAA;AACrB,iHAAA,oBAAoB,OAAA;AAExB,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAC7B,2DAQ8B;AAP1B,sHAAA,gBAAgB,OAAA;AAChB,qHAAA,eAAe,OAAA;AACf,sHAAA,gBAAgB,OAAA;AAChB,wHAAA,kBAAkB,OAAA;AAClB,yHAAA,mBAAmB,OAAA;AACnB,iHAAA,WAAW,OAAA;AACX,wHAAA,kBAAkB,OAAA;AAEtB,+CAoCwB;AAnCpB,oHAAA,oBAAoB,OAAA;AACpB,kHAAA,kBAAkB,OAAA;AAClB,uHAAA,uBAAuB,OAAA;AACvB,0HAAA,0BAA0B,OAAA;AAC1B,kHAAA,kBAAkB,OAAA;AAClB,mHAAA,mBAAmB,OAAA;AACnB,wHAAA,wBAAwB,OAAA;AACxB,qHAAA,qBAAqB,OAAA;AACrB,mHAAA,mBAAmB,OAAA;AACnB,2HAAA,2BAA2B,OAAA;AAC3B,uHAAA,uBAAuB,OAAA;AACvB,wHAAA,wBAAwB,OAAA;AACxB,kIAAA,kCAAkC,OAAA;AAClC,sHAAA,sBAAsB,OAAA;AACtB,iHAAA,iBAAiB,OAAA;AACjB,8HAAA,8BAA8B,OAAA;AAC9B,4HAAA,4BAA4B,OAAA;AAC5B,+IAAA,+CAA+C,OAAA;AAC/C,kHAAA,kBAAkB,OAAA;AAClB,6GAAA,aAAa,OAAA;AACb,uHAAA,uBAAuB,OAAA;AACvB,yHAAA,yBAAyB,OAAA;AACzB,sHAAA,sBAAsB,OAAA;AACtB,wHAAA,wBAAwB,OAAA;AACxB,yHAAA,yBAAyB,OAAA;AACzB,8GAAA,cAAc,OAAA;AACd,6GAAA,aAAa,OAAA;AACb,+GAAA,eAAe,OAAA;AACf,qHAAA,qBAAqB,OAAA;AACrB,mIAAA,mCAAmC,OAAA;AACnC,kIAAA,kCAAkC,OAAA;AAClC,yHAAA,yBAAyB,OAAA;AACzB,4HAAA,4BAA4B,OAAA;AAC5B,wHAAA,wBAAwB,OAAA;AACxB,8GAAA,cAAc,OAAA;AAElB,wFAAwF;AACxF,+CAcwB;AAbpB,kHAAA,kBAAkB,OAAA;AAClB,gHAAA,gBAAgB,OAAA;AAChB,iHAAA,iBAAiB,OAAA;AACjB,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AACnB,6GAAA,aAAa,OAAA;AACb,iHAAA,iBAAiB,OAAA;AACjB,sHAAA,sBAAsB,OAAA;AACtB,yHAAA,yBAAyB,OAAA;AACzB,iHAAA,iBAAiB,OAAA;AACjB,4GAAA,YAAY,OAAA;AACZ,gHAAA,gBAAgB,OAAA;AAChB,iHAAA,iBAAiB,OAAA;AAErB,yEAGqC;AAFjC,wJAAA,2CAA2C,OAAA;AAC3C,uIAAA,0BAA0B,OAAA;AAG9B,yGAAyG;AACzG,qGAAqG;AACrG,iEAIiC;AAH7B,sIAAA,6BAA6B,OAAA;AAC7B,8HAAA,qBAAqB,OAAA;AACrB,2IAAA,kCAAkC,OAAA;AAiBtC,qEAA+F;AAAtF,iIAAA,sBAAsB,OAAA;AAAE,qIAAA,0BAA0B,OAAA;AAC3D,mDAmB0B;AAlBtB,gHAAA,cAAc,OAAA;AACd,8GAAA,YAAY,OAAA;AACZ,uHAAA,qBAAqB,OAAA;AACrB,8GAAA,YAAY,OAAA;AACZ,iHAAA,eAAe,OAAA;AACf,8HAAA,4BAA4B,OAAA;AAC5B,oHAAA,kBAAkB,OAAA;AAClB,oHAAA,kBAAkB,OAAA;AAClB,8GAAA,YAAY,OAAA;AACZ,qHAAA,mBAAmB,OAAA;AACnB,qHAAA,mBAAmB,OAAA;AACnB,wHAAA,sBAAsB,OAAA;AACtB,mHAAA,iBAAiB,OAAA;AACjB,mHAAA,iBAAiB,OAAA;AACjB,sHAAA,oBAAoB,OAAA;AACpB,iHAAA,eAAe,OAAA;AACf,iHAAA,eAAe,OAAA;AACf,6GAAA,WAAW,OAAA;AAEf,uDAQ4B;AAPxB,uHAAA,mBAAmB,OAAA;AACnB,uHAAA,mBAAmB,OAAA;AACnB,+HAAA,2BAA2B,OAAA;AAC3B,+HAAA,2BAA2B,OAAA;AAC3B,+GAAA,WAAW,OAAA;AACX,yHAAA,qBAAqB,OAAA;AACrB,kHAAA,cAAc,OAAA;AAGlB,6DAA2D;AAAlD,yHAAA,kBAAkB,OAAA;AAC3B,mEAAwE;AAA/D,sIAAA,4BAA4B,OAAA;AACrC,iEAOiC;AAN7B,oIAAA,2BAA2B,OAAA;AAC3B,yHAAA,gBAAgB,OAAA;AAChB,oHAAA,WAAW,OAAA;AACX,qHAAA,YAAY,OAAA;AACZ,8HAAA,qBAAqB,OAAA;AACrB,gIAAA,uBAAuB,OAAA;AAE3B,2CAMsB;AALlB,8GAAA,gBAAgB,OAAA;AAChB,8GAAA,gBAAgB,OAAA;AAChB,6GAAA,eAAe,OAAA;AACf,8GAAA,gBAAgB,OAAA;AAChB,6GAAA,eAAe,OAAA;AAEnB,6DAU+B;AAT3B,gIAAA,yBAAyB,OAAA;AACzB,uHAAA,gBAAgB,OAAA;AAChB,sHAAA,eAAe,OAAA;AACf,uHAAA,gBAAgB,OAAA;AAChB,qHAAA,cAAc,OAAA;AACd,uHAAA,gBAAgB,OAAA;AAChB,oHAAA,aAAa,OAAA;AACb,yHAAA,kBAAkB,OAAA;AAClB,yHAAA,kBAAkB,OAAA;AAEtB,yDAQ6B;AAPzB,4HAAA,uBAAuB,OAAA;AACvB,qHAAA,gBAAgB,OAAA;AAChB,uHAAA,kBAAkB,OAAA;AAClB,kHAAA,aAAa,OAAA;AACb,mHAAA,cAAc,OAAA;AACd,2HAAA,sBAAsB,OAAA;AACtB,2HAAA,sBAAsB,OAAA;AAE1B,6CAyBuB;AAxBnB,yGAAA,UAAU,OAAA;AACV,wGAAA,SAAS,OAAA;AACT,8GAAA,eAAe,OAAA;AACf,+GAAA,gBAAgB,OAAA;AAChB,gHAAA,iBAAiB,OAAA;AACjB,uHAAA,wBAAwB,OAAA;AACxB,uHAAA,wBAAwB,OAAA;AACxB,sGAAA,OAAO,OAAA;AACP,sGAAA,OAAO,OAAA;AACP,4GAAA,aAAa,OAAA;AACb,sGAAA,OAAO,OAAA;AACP,yGAAA,UAAU,OAAA;AACV,4GAAA,aAAa,OAAA;AACb,4GAAA,aAAa,OAAA;AACb,6GAAA,cAAc,OAAA;AACd,0GAAA,WAAW,OAAA;AACX,+GAAA,gBAAgB,OAAA;AAChB,mIAAA,oCAAoC,OAAA;AACpC,gHAAA,iBAAiB,OAAA;AACjB,qHAAA,sBAAsB,OAAA;AACtB,gHAAA,iBAAiB,OAAA;AACjB,uGAAA,QAAQ,OAAA;AACR,6GAAA,cAAc,OAAA;AACd,mHAAA,oBAAoB,OAAA;AAExB,mDAM0B;AALtB,gHAAA,cAAc,OAAA;AACd,oHAAA,kBAAkB,OAAA;AAClB,mHAAA,iBAAiB,OAAA;AACjB,kHAAA,gBAAgB,OAAA;AAChB,0HAAA,wBAAwB,OAAA;AAE5B,uDAqB4B;AApBxB,gHAAA,YAAY,OAAA;AACZ,yHAAA,qBAAqB,OAAA;AACrB,gIAAA,4BAA4B,OAAA;AAC5B,sHAAA,kBAAkB,OAAA;AAClB,oHAAA,gBAAgB,OAAA;AAChB,sHAAA,kBAAkB,OAAA;AAClB,0HAAA,sBAAsB,OAAA;AACtB,uHAAA,mBAAmB,OAAA;AACnB,2HAAA,uBAAuB,OAAA;AACvB,8HAAA,0BAA0B,OAAA;AAC1B,oHAAA,gBAAgB,OAAA;AAChB,qHAAA,iBAAiB,OAAA;AACjB,+GAAA,WAAW,OAAA;AACX,uHAAA,mBAAmB,OAAA;AACnB,0HAAA,sBAAsB,OAAA;AACtB,iHAAA,aAAa,OAAA;AACb,gHAAA,YAAY,OAAA;AACZ,yHAAA,qBAAqB,OAAA;AACrB,4HAAA,wBAAwB,OAAA;AACxB,uHAAA,mBAAmB,OAAA;AAEvB,qDAqB2B;AApBvB,+GAAA,YAAY,OAAA;AACZ,kHAAA,eAAe,OAAA;AACf,oHAAA,iBAAiB,OAAA;AACjB,sHAAA,mBAAmB,OAAA;AACnB,wHAAA,qBAAqB,OAAA;AACrB,iHAAA,cAAc,OAAA;AACd,uHAAA,oBAAoB,OAAA;AACpB,2HAAA,wBAAwB,OAAA;AACxB,kIAAA,+BAA+B,OAAA;AAC/B,gIAAA,6BAA6B,OAAA;AAC7B,4HAAA,yBAAyB,OAAA;AACzB,4HAAA,yBAAyB,OAAA;AACzB,iIAAA,8BAA8B,OAAA;AAC9B,gIAAA,6BAA6B,OAAA;AAC7B,wHAAA,qBAAqB,OAAA;AACrB,0HAAA,uBAAuB,OAAA;AACvB,wHAAA,qBAAqB,OAAA;AACrB,yHAAA,sBAAsB,OAAA;AACtB,0HAAA,uBAAuB,OAAA;AACvB,8HAAA,2BAA2B,OAAA;AAE/B,qDAQ2B;AAPvB,iHAAA,cAAc,OAAA;AACd,gHAAA,aAAa,OAAA;AACb,qHAAA,kBAAkB,OAAA;AAClB,oHAAA,iBAAiB,OAAA;AACjB,0HAAA,uBAAuB,OAAA;AACvB,+HAAA,4BAA4B,OAAA;AAC5B,wHAAA,qBAAqB,OAAA;AAEzB,yCAA8E;AAArE,qGAAA,QAAQ,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAAE,4GAAA,eAAe,OAAA;AACxD,6DAAmF;AAA1E,wHAAA,iBAAiB,OAAA;AAAE,8HAAA,uBAAuB,OAAA;AACnD,mEAMkC;AAL9B,+HAAA,qBAAqB,OAAA;AACrB,oIAAA,0BAA0B,OAAA;AAC1B,sHAAA,YAAY,OAAA;AACZ,sHAAA,YAAY,OAAA;AACZ,8HAAA,oBAAoB,OAAA;AAExB,mEAOkC;AAN9B,6HAAA,mBAAmB,OAAA;AACnB,iIAAA,uBAAuB,OAAA;AACvB,gIAAA,sBAAsB,OAAA;AACtB,mIAAA,yBAAyB,OAAA;AACzB,uHAAA,aAAa,OAAA;AACb,oIAAA,0BAA0B,OAAA;AAE9B,iDAAyE;AAAhE,6GAAA,YAAY,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,6GAAA,YAAY,OAAA;AAC/C,qDAAuF;AAA9E,iHAAA,cAAc,OAAA;AAAE,qHAAA,kBAAkB,OAAA;AAAE,iHAAA,cAAc,OAAA;AAE3D,6DAK+B;AAJ3B,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AAErB,qDAK2B;AAJvB,iHAAA,cAAc,OAAA;AACd,sHAAA,mBAAmB,OAAA;AACnB,4HAAA,yBAAyB,OAAA;AACzB,iIAAA,8BAA8B,OAAA;AAElC,qDAAsF;AAA7E,kHAAA,eAAe,OAAA;AAAE,kHAAA,eAAe,OAAA;AAAE,kHAAA,eAAe,OAAA;AAC1D,mDAA8D;AAArD,8GAAA,YAAY,OAAA;AAAE,8GAAA,YAAY,OAAA;AACnC,yDAAwE;AAA/D,oHAAA,eAAe,OAAA;AAAE,qHAAA,gBAAgB,OAAA;AAC1C,yDAAwG;AAA/F,sHAAA,iBAAiB,OAAA;AAAE,+HAAA,0BAA0B,OAAA;AAAE,uHAAA,kBAAkB,OAAA","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { RuleFailError, renderRuleFailForAi, renderRuleFailForHuman } from './rule-fail-error';\n// THE one representation of a cure, shared by RuleFailError (build-time) and FixHint (edit-time), plus\n// the one renderer that owns the \"Fix Option N:\" numbering and the \"(preferred)\" tag.\nexport { Option, formatFixOptions } from './fix-option';\nexport { CliExitError } from './cli-exit-error';\nexport { CliUsage, CliFlag, CliArgSet, CliArgsCheck, CliArgs } from './cli-args';\nexport { runMain } from './run-main';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig, ConfigLoader } from './load-config';\n// The validation-failure banner: ONE cure (edit the file), plus the marker phrases the validator\n// messages embed rather than re-type.\nexport {\n formatConfigErrorsBanner,\n CONFIG_POLICY_DOC,\n RETIRED_KEY_MARKER,\n RETIRED_TOP_LEVEL_MARKER,\n SECTION_PLACEMENT_MARKER,\n} from './config-error-banner';\nexport {\n findConfigFile,\n CONFIG_FILENAME,\n ConfigFile,\n ConfigParseAttempt,\n CONFIG_PARSE_ATTEMPTS,\n CONFIG_PARSE_RETRY_MILLIS,\n} from './config-file';\n// The PARSED-BUT-UNVALIDATED config shape. Exported for readers that walk the file generically rather\n// than through the typed config (the pr-gate active-hatch dashboard section reads every rule's hatches).\nexport type { RawConfigFile } from './config-file';\nexport { RepoRootFinder, INSTRUCT_AI_DIR, INSTRUCT_AI_LEAF } from './repo-root';\n// The scoped `.webpieces` resolver. EVERY reader/writer of `.webpieces/...` goes through one of its two\n// named methods so the call site declares whether the state is repo-wide or worktree-private.\nexport {\n DotWebpieces,\n dotWebpieces,\n GitDirs,\n WORKTREE_STATE_DIR,\n LOGS_STATE_DIR,\n} from './state-dir';\nexport { StateDirMigrator, StateMigrationReport } from './state-dir-migration';\n// There is NO machine-global state root. `MachineStateHome`/`StateHome`/`WEBPIECES_STATE_HOME` and the\n// `PrBodyStore` that used them are DELETED: the one artifact that needed a scope above the clone was the\n// gated squash body, and GitHub holds it now (it IS the PR description). Every `.webpieces` path a\n// webpieces tool writes is `{repo}/.webpieces`, resolved through `DotWebpieces` above. See\n// `decisions/0005-the-pr-description-is-the-merge-body.md`.\nexport { AgedTreeSweeper, SweepCount, RETENTION_DAYS } from './aged-tree-sweep';\nexport {\n ClaudeEnv,\n claudeEnv,\n CLAUDE_PROJECT_DIR_ENV,\n CLAUDE_PROJECT_DIR_UNSET,\n} from './claude-env';\nexport { AtomicFile } from './atomic-file';\n// The ONE formatter for a remedy that must run in a named directory: `cd '<root>' && <command>`.\n// Single-quoted so a repo path containing a space is still runnable (and still un-smuggleable).\nexport { atRoot } from './at-root';\nexport { RulesConfigDesign } from './rules-config-design';\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './di';\nexport { ExcludePaths, isWebpiecesStateDir } from './exclude-hook-paths';\nexport { isPathExcluded, matchesAnyGlob } from './exclude-paths';\n// The machine-generated trees a line-count rule never fires on. A FLOOR, not a default value:\n// `max-file-lines.allowedPaths` adds to it, so configuring your own tree cannot lose it.\nexport { GENERATED_CODE_PATHS } from './generated-code-paths';\n// THE one `no-custom-css` path exemption. Both engines that enforce the rule (the edit-time hook and the\n// CI validator) consult this class, so `allowGlobs` cannot be honoured by one half and ignored by the other.\nexport { NoCustomCssScope } from './no-custom-css-scope';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport {\n loadTemplate,\n writeTemplateIfMissing,\n writeTemplate,\n TemplateWriter,\n} from './load-template';\n// The instruct-ai docs are delivered as a SET: writing one writes the transitive closure of the docs it\n// links to, so a doc and everything it points at always land together. See instruct-ai-docs.ts.\nexport {\n GIT_WORKFLOW_DOC,\n GitWorkflowDoc,\n InstructAiDoc,\n InstructAiDocSet,\n MergeProcessDoc,\n} from './instruct-ai-docs';\nexport {\n MERGE_PROCESS_DOC,\n MergeProcessText,\n MergeRun,\n ReferenceMergeRun,\n} from './merge-process-doc';\nexport { BUILD_LOG_DOC } from './build-log-doc';\nexport {\n validateWebpiecesConfig,\n validatePrGateSection,\n validateChecklistsSection,\n validateSectionPlacement,\n validateExcludePaths,\n validateMatchRulesSection,\n allRuleNames,\n recommendedSeedMode,\n recommendedSeedModeFor,\n seedEntryForRule,\n} from './validate-config';\nexport { validateCommandsSection } from './commands-section-validators';\nexport {\n unknownKeyErrors,\n isCommentKey,\n validateTopLevelKeys,\n COMMENT_KEY_SUFFIX,\n} from './config-key-rules';\n// The retired-key table + the no-back-compat policy it enforces. Exported so the installer can migrate\n// what the errors instruct, and so consumers can enumerate retirements.\nexport {\n RETIRED_CONFIG_KEYS,\n RETIRED_SCOPE_KEY,\n RETIRED_SCOPE_RULE,\n RetiredConfigKey,\n isRetiredKey,\n retiredEntry,\n retiredKeyError,\n retiredKeyErrorsIn,\n retiredRuleFor,\n} from './retired-config-keys';\n// The MECHANICAL cure the unknown-rule error and the banner both name: strip every key no validator has a\n// schema for, so cleanliness is one command rather than a judgement call made while every Bash call is\n// blocked. `PRUNE_UNKNOWN_COMMAND` (constants.ts) is the single spelling of that command.\nexport { ConfigPruner, PruneResult, PrunedKey } from './config-pruner';\nexport { validateChecklistDocs } from './checklist-docs-validator';\n// The OPTIONAL machine-local `~/.webpieces/config.json`: absent (the normal state for every consumer) means\n// each key's declared default, silently; present means STRICT about what it understands and FORWARD-COMPATIBLE\n// about what it does not. A retired key (its own retirement table), a known key of the wrong TYPE and an\n// unparseable document all REJECT; a key this release simply does not recognise is IGNORED with a warning,\n// because the file is machine-global and the repos reading it pin different releases — rejecting a newer\n// release's key would hard-block every repo on the machine that is not yet on it. See home-config.ts.\n// `isHomeConfigPath` is what grants the file its unconditional Write/Edit PASS in the hook guards, which is\n// what keeps a rejection repairable. Every `experimental.*` key is an OPT-IN that defaults OFF, including\n// `whole-repo-build-guard`: ON requires an explicit `true`, and there is no per-key default to export.\nexport {\n HomeConfig,\n HomeConfigService,\n RetiredHomeConfigKey,\n RETIRED_HOME_CONFIG_KEYS,\n HOME_CONFIG_DIR,\n HOME_CONFIG_FILE,\n HOME_EXPERIMENTAL_SECTION,\n HOME_KEY_ORPHAN_DIR_SWEEP,\n HOME_KEY_WHOLE_REPO_BUILD_GUARD,\n HOME_KEY_MAX_CONCURRENT_BUILDS,\n HOME_KEY_TURN_OFF_ALL_REVIEWERS,\n HOME_KEY_SINGLE_ROUND_REVIEW,\n DEFAULT_MAX_CONCURRENT_BUILDS,\n HOME_KEY_DOC,\n HOME_KEY_AI_DOC,\n DOCUMENTATION_KEYS,\n} from './home-config';\n// The MACHINE-WIDE build ledger, `~/.webpieces/builds.log`. THE one carve-out from\n// `no-machine-global-state.spec.ts`'s rule that webpieces writes only under `{repo}/.webpieces` — the\n// argument is in `decisions/0006-the-build-ledger-is-machine-global.md`, and the short form is that \"how\n// many builds are burning this box's CPU\" is a fact about the MACHINE, is not a cache of anything a\n// remote owns, and cannot be answered from a per-repo file because every linked worktree has its own\n// `.webpieces/` and would be blind to the sibling it is contending with. See builds-log.ts.\nexport {\n BuildsLog,\n BuildTicket,\n BuildTermination,\n RunningBuild,\n BUILDS_LOG_FILE,\n BUILDS_LOCK_FILE,\n BUILD_START,\n BUILD_DONE_SUCCESS,\n BUILD_DONE_FAIL,\n MAX_BUILDS_LOG_BYTES,\n BUILDS_LOG_GENERATIONS,\n MAX_ROW_BYTES,\n} from './builds-log';\n// The orphan-directory sweep: the corpse an `nx g move` leaves on every clone, which git cannot remove\n// because an ignored dist/ or node_modules/ outlives every tracked file under it. See orphan-dir-scan.ts\n// for why the predicate is git's own `clean -Xdn` answer rather than a hand-rolled ignore walk.\nexport { OrphanDirScanner, OrphanCandidate } from './orphan-dir-scan';\nexport {\n OrphanDirArchiver,\n ArchivedOrphan,\n FailedOrphan,\n OrphanSweepResult,\n OrphanSweepManifest,\n TRASH_STATE_DIR,\n TRASH_MANIFEST_FILE,\n TRASH_RETENTION_DAYS,\n} from './orphan-dir-archive';\nexport { OrphanDirSweeper, OrphanSweepReport } from './orphan-dir-sweep';\nexport {\n MatchRuleConfig,\n MatchRuleViolation,\n findMatchRuleViolations,\n isMatchRuleAllowedPath,\n compileMatchRulePatterns,\n renderMatchRuleMessage,\n DEFAULT_MATCH_RULES,\n} from './match-rules-config';\nexport type { ConfigSection } from './sections';\nexport { schemaFieldNames } from './rule-schemas';\nexport {\n HOOK_GUARD_NAMES,\n BRANCH_STATE_GUARD_KEY,\n PR_LIFECYCLE_GUARD_KEY,\n isHookGuard,\n sectionForRule,\n} from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport { SkipRuleResult } from './skip-rule';\nexport {\n detectBase,\n resolveBase,\n getChangedFiles,\n getFileDiff,\n getChangedLineNumbers,\n findNewMethodSignaturesInDiff,\n hasChangesInRange,\n isNewOrModified,\n DiffScope,\n DiffRange,\n ChangedFilesOptions,\n} from './diff-scope';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_INFO_DIR,\n PR_REVIEW_DIR,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n PUSH_DEV_STATE_FILE,\n PRUNE_UNKNOWN_COMMAND,\n UPGRADE_SHIM_COMMAND,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n SyncFlowGuidance,\n WP_START_UPDATE,\n WP_FINISH_UPDATE,\n WP_START_UPSERT_PR,\n WP_FINISH_UPSERT_PR,\n WP_PUSH_DEV,\n WP_FINISH_PUSH_DEV,\n} from './sync-flow-guidance';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n EnsureWeAreSecureConfig,\n BranchCreationGuardConfig,\n PrLifecycleGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n ValidateArchitectureUnchangedConfig,\n ValidateNoArchitectureCyclesConfig,\n ValidatePackageJsonConfig,\n ValidateVersionsLockedConfig,\n ValidateEslintSyncConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PROJECT_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n STRUCTURAL_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport {\n NoClientCreationOutsideServerOrClientConfig,\n CLIENT_CREATION_SEVERITIES,\n} from './no-client-creation-config';\nexport type { ClientCreationSeverity } from './no-client-creation-config';\n// The `no-state-paths-in-templates` config, in its own module for the same reason no-client-creation is:\n// rule-configs.ts is at its file-size cap and a rule that carries real defaults belongs beside them.\nexport {\n NoStatePathsInTemplatesConfig,\n DEFAULT_TEMPLATE_DIRS,\n DEFAULT_BANNED_STATE_PATH_PREFIXES,\n} from './no-state-paths-config';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n ProjectMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n StructuralMode,\n ValidateTsMode,\n} from './rule-configs';\nexport { BranchStateGuardConfig, DEFAULT_MAX_COMMITS_BEHIND } from './main-sync-guard-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n DEFAULT_BUILD_COMMAND,\n LandPrConfig,\n DevDeployConfig,\n DEFAULT_DEV_BRANCH_NAMESPACE,\n DEFAULT_DEV_BRANCH,\n ReviewContextEntry,\n defaultGates,\n defaultPrGateConfig,\n defaultLandPrConfig,\n defaultDevDeployConfig,\n buildPrGateConfig,\n buildLandPrConfig,\n buildDevDeployConfig,\n MERGE_MODE_AUTO,\n MERGE_MODE_NONE,\n MERGE_MODES,\n} from './pr-gate-config';\nexport {\n ChecklistDefinition,\n ReviewerAgentPolicy,\n REVIEWER_AGENTS_PLACEHOLDER,\n DEFAULT_REVIEWER_AGENT_NAME,\n toChecklist,\n normalizeChecklistDoc,\n formatFileList,\n} from './checklist-config';\nexport type { RawChecklistItem } from './checklist-config';\nexport { ChecklistValidator } from './checklist-validator';\nexport { ChecklistInstructionsService } from './checklist-instructions';\nexport {\n ReviewerInstructionsService,\n ReviewerBriefing,\n BriefedFile,\n ContextEntry,\n READ_TRUNCATION_LINES,\n ALL_DIFF_ONE_READ_LINES,\n} from './reviewer-instructions';\nexport {\n GateTokenService,\n computeGateToken,\n gateTokenMarker,\n extractGateToken,\n verifyGateToken,\n} from './gate-token';\nexport {\n SubagentProvenanceService,\n ReviewerEvidence,\n ReviewerContext,\n ExpectedReviewer,\n TranscriptScan,\n ProvenanceResult,\n PROVENANCE_OK,\n PROVENANCE_MISSING,\n PROVENANCE_SKIPPED,\n} from './subagent-provenance';\nexport {\n ReviewProvenanceService,\n ReviewProvenance,\n ReviewerTranscript,\n ReviewerPaths,\n OfferedContext,\n ProvenanceWriteRequest,\n DEFAULT_RETENTION_DAYS,\n} from './review-provenance';\nexport {\n ReviewJson,\n PrContext,\n ChecklistResult,\n ChecklistVerdict,\n ChecklistOverride,\n ChecklistOverrideService,\n checklistOverrideService,\n CK_PASS,\n CK_WARN,\n CK_OVERRIDDEN,\n CK_FAIL,\n CK_MISSING,\n CK_BAD_FORMAT,\n VERDICT_GREEN,\n VERDICT_YELLOW,\n VERDICT_RED,\n VERDICT_STATUSES,\n SINGLE_ROUND_MAIN_AGENT_INSTRUCTIONS,\n RequiredChecklist,\n ChecklistReviewContext,\n ReviewJsonService,\n prDirFor,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncStatusFile,\n MainSyncFileStore,\n PullRequestIndex,\n MAIN_SYNC_STATUS_VERSION,\n} from './main-sync-file';\nexport {\n MainSyncLock,\n MainSyncStatusService,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n readMainSyncStatusFile,\n writeMainSyncStatus,\n writeMainSyncStatusFile,\n computeAllMainSyncStatuses,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n tryAcquireMainSyncLock,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n MergedBranch,\n DeletableBranch,\n DeletableWorktree,\n MergedBranchesCache,\n MergedBranchesService,\n CacheFreshness,\n CACHE_STALE_AFTER_MS,\n CLASSIFICATION_MERGED_PR,\n CLASSIFICATION_BACKUP_OF_MERGED,\n CLASSIFICATION_BACKUP_OF_LIVE,\n CLASSIFICATION_NO_COMMITS,\n CLASSIFICATION_SUPERSEDED,\n CLASSIFICATION_CONTENT_IN_MAIN,\n CLASSIFICATION_NEVER_PROPOSED,\n CLASSIFICATION_IN_USE,\n CLASSIFICATION_PRUNABLE,\n CLASSIFICATION_LOCKED,\n CLASSIFICATION_CURRENT,\n CLASSIFICATION_DETACHED,\n ADJUDICATED_CLASSIFICATIONS,\n} from './merged-branches';\nexport {\n BranchArchiver,\n ArchiveResult,\n ARCHIVE_TAG_PREFIX,\n BRANCH_RETENTIONS,\n BRANCH_RETENTION_DELETE,\n BRANCH_RETENTION_ARCHIVE_TAG,\n BRANCH_RETENTION_KEEP,\n} from './branch-archiver';\nexport { Worktree, WorktreeWorkInFlight, WorktreeService } from './worktrees';\nexport { AgentWorktreeLock, AgentWorktreeLockReader } from './agent-worktree-lock';\nexport {\n HARNESS_NOT_CONSULTED,\n LOCK_LIVENESS_UNVERIFIABLE,\n LockDecision,\n LockEvidence,\n WorktreeLockVerdicts,\n} from './worktree-lock-verdicts';\nexport {\n AGENT_ACTIVITY_LIVE,\n AGENT_ACTIVITY_RETURNED,\n AGENT_ACTIVITY_UNKNOWN,\n AGENT_TRANSCRIPT_QUIET_MS,\n AgentActivity,\n HarnessAgentActivityReader,\n} from './harness-agent-activity';\nexport { ReapedBranch, ReapResult, BranchReaper } from './branch-reaper';\nexport { ReapedWorktree, WorktreeReapResult, WorktreeReaper } from './worktree-reaper';\nexport type { MutationVerb, MutationPhase } from './branch-mutation-log';\nexport {\n BranchMutationEvent,\n BranchMutationLog,\n branchMutationLogPath,\n logBranchMutation,\n} from './branch-mutation-log';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\nexport { StaleBinRemoval, StaleBinSweeper, staleBinSweeper } from './stale-bin-sweep';\nexport { SpecTempDirs, specTempDirs } from './spec-temp-dirs';\nexport { RepoScratchDirs, SCRATCH_DIR_NAME } from './repo-scratch-dirs';\nexport { TmpScratchSweeper, TMP_SCRATCH_RETENTION_DAYS, TMP_SCRATCH_PREFIX } from './tmp-scratch-sweep';\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DotWebpieces } from './state-dir';
|
|
2
|
+
/** The subdirectory of the per-worktree `.webpieces` scope that holds throwaway runtime files. */
|
|
3
|
+
export declare const SCRATCH_DIR_NAME = "scratch";
|
|
4
|
+
/**
|
|
5
|
+
* Creates short-lived scratch directories under this worktree's `.webpieces/` scope.
|
|
6
|
+
*
|
|
7
|
+
* `local()` (not `aiWritable()`) is the right scope: these files are written by the TOOLING, never by an
|
|
8
|
+
* agent, and `local()` keeps them under the primary clone so they outlive a reaped worktree exactly like
|
|
9
|
+
* the gate logs beside them.
|
|
10
|
+
*/
|
|
11
|
+
export declare class RepoScratchDirs {
|
|
12
|
+
private readonly dotDir;
|
|
13
|
+
constructor(dotDir?: DotWebpieces);
|
|
14
|
+
/**
|
|
15
|
+
* `fs.mkdtempSync` under `<.webpieces scope>/scratch/`, creating the parent if this is the first call.
|
|
16
|
+
*
|
|
17
|
+
* `prefix` keeps the `wp-<area>-` convention, so a leftover names the code path that wrote it.
|
|
18
|
+
*/
|
|
19
|
+
make(repoRoot: string, prefix: string): string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RepoScratchDirs = exports.SCRATCH_DIR_NAME = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
const inversify_1 = require("inversify");
|
|
8
|
+
const state_dir_1 = require("./state-dir");
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// SHORT-LIVED RUNTIME SCRATCH FILES BELONG IN `.webpieces/`, NOT IN `$TMPDIR`.
|
|
11
|
+
//
|
|
12
|
+
// Two `wp-*` code paths needed a path on disk for the length of one subprocess call — the squash body for
|
|
13
|
+
// `gh pr merge --body-file`, and the nx graph dump — and both reached for `os.tmpdir()`. Neither has the
|
|
14
|
+
// reason that justifies `$TMPDIR` for a SPEC fixture (see `spec-temp-dirs.ts`): they are not isolating
|
|
15
|
+
// themselves from the developer's `$HOME`, and they do not `git init` inside themselves. They are
|
|
16
|
+
// ordinary gate state, and every other piece of gate state lives under `.webpieces/`.
|
|
17
|
+
//
|
|
18
|
+
// Putting them there is not tidiness — it is what gives them an OWNER. `CleanTmp` already sweeps
|
|
19
|
+
// `DotWebpieces.local()` on a 30-day retention at the end of every merge/PR flow, so a scratch file
|
|
20
|
+
// written here is reaped by a mechanism that already exists and is already tested. The same file in
|
|
21
|
+
// `$TMPDIR` had no owner at all, which is how 4,222 `wp-merge-body-` directories accumulated on one
|
|
22
|
+
// machine.
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/** The subdirectory of the per-worktree `.webpieces` scope that holds throwaway runtime files. */
|
|
25
|
+
exports.SCRATCH_DIR_NAME = 'scratch';
|
|
26
|
+
/**
|
|
27
|
+
* Creates short-lived scratch directories under this worktree's `.webpieces/` scope.
|
|
28
|
+
*
|
|
29
|
+
* `local()` (not `aiWritable()`) is the right scope: these files are written by the TOOLING, never by an
|
|
30
|
+
* agent, and `local()` keeps them under the primary clone so they outlive a reaped worktree exactly like
|
|
31
|
+
* the gate logs beside them.
|
|
32
|
+
*/
|
|
33
|
+
let RepoScratchDirs = class RepoScratchDirs {
|
|
34
|
+
dotDir;
|
|
35
|
+
constructor(dotDir = state_dir_1.dotWebpieces) {
|
|
36
|
+
this.dotDir = dotDir;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* `fs.mkdtempSync` under `<.webpieces scope>/scratch/`, creating the parent if this is the first call.
|
|
40
|
+
*
|
|
41
|
+
* `prefix` keeps the `wp-<area>-` convention, so a leftover names the code path that wrote it.
|
|
42
|
+
*/
|
|
43
|
+
make(repoRoot, prefix) {
|
|
44
|
+
const base = path.join(this.dotDir.local(repoRoot), exports.SCRATCH_DIR_NAME);
|
|
45
|
+
fs.mkdirSync(base, { recursive: true });
|
|
46
|
+
return fs.mkdtempSync(path.join(base, prefix));
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.RepoScratchDirs = RepoScratchDirs;
|
|
50
|
+
exports.RepoScratchDirs = RepoScratchDirs = tslib_1.__decorate([
|
|
51
|
+
(0, inversify_1.injectable)(inversify_1.bindingScopeValues.Singleton),
|
|
52
|
+
tslib_1.__metadata("design:paramtypes", [state_dir_1.DotWebpieces])
|
|
53
|
+
], RepoScratchDirs);
|
|
54
|
+
//# sourceMappingURL=repo-scratch-dirs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-scratch-dirs.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/repo-scratch-dirs.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,mDAA6B;AAC7B,yCAA2D;AAC3D,2CAAyD;AAEzD,8EAA8E;AAC9E,+EAA+E;AAC/E,EAAE;AACF,0GAA0G;AAC1G,yGAAyG;AACzG,uGAAuG;AACvG,kGAAkG;AAClG,sFAAsF;AACtF,EAAE;AACF,iGAAiG;AACjG,oGAAoG;AACpG,oGAAoG;AACpG,oGAAoG;AACpG,WAAW;AACX,8EAA8E;AAE9E,kGAAkG;AACrF,QAAA,gBAAgB,GAAG,SAAS,CAAC;AAE1C;;;;;;GAMG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAe;IACK;IAA7B,YAA6B,SAAuB,wBAAY;QAAnC,WAAM,GAAN,MAAM,CAA6B;IAAG,CAAC;IAEpE;;;;OAIG;IACH,IAAI,CAAC,QAAgB,EAAE,MAAc;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,wBAAgB,CAAC,CAAC;QACtE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,OAAO,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC;CACJ,CAAA;AAbY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,sBAAU,EAAC,8BAAkB,CAAC,SAAS,CAAC;6CAEA,wBAAY;GADxC,eAAe,CAa3B","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { DotWebpieces, dotWebpieces } from './state-dir';\n\n// ---------------------------------------------------------------------------\n// SHORT-LIVED RUNTIME SCRATCH FILES BELONG IN `.webpieces/`, NOT IN `$TMPDIR`.\n//\n// Two `wp-*` code paths needed a path on disk for the length of one subprocess call — the squash body for\n// `gh pr merge --body-file`, and the nx graph dump — and both reached for `os.tmpdir()`. Neither has the\n// reason that justifies `$TMPDIR` for a SPEC fixture (see `spec-temp-dirs.ts`): they are not isolating\n// themselves from the developer's `$HOME`, and they do not `git init` inside themselves. They are\n// ordinary gate state, and every other piece of gate state lives under `.webpieces/`.\n//\n// Putting them there is not tidiness — it is what gives them an OWNER. `CleanTmp` already sweeps\n// `DotWebpieces.local()` on a 30-day retention at the end of every merge/PR flow, so a scratch file\n// written here is reaped by a mechanism that already exists and is already tested. The same file in\n// `$TMPDIR` had no owner at all, which is how 4,222 `wp-merge-body-` directories accumulated on one\n// machine.\n// ---------------------------------------------------------------------------\n\n/** The subdirectory of the per-worktree `.webpieces` scope that holds throwaway runtime files. */\nexport const SCRATCH_DIR_NAME = 'scratch';\n\n/**\n * Creates short-lived scratch directories under this worktree's `.webpieces/` scope.\n *\n * `local()` (not `aiWritable()`) is the right scope: these files are written by the TOOLING, never by an\n * agent, and `local()` keeps them under the primary clone so they outlive a reaped worktree exactly like\n * the gate logs beside them.\n */\n@injectable(bindingScopeValues.Singleton)\nexport class RepoScratchDirs {\n constructor(private readonly dotDir: DotWebpieces = dotWebpieces) {}\n\n /**\n * `fs.mkdtempSync` under `<.webpieces scope>/scratch/`, creating the parent if this is the first call.\n *\n * `prefix` keeps the `wp-<area>-` convention, so a leftover names the code path that wrote it.\n */\n make(repoRoot: string, prefix: string): string {\n const base = path.join(this.dotDir.local(repoRoot), SCRATCH_DIR_NAME);\n fs.mkdirSync(base, { recursive: true });\n return fs.mkdtempSync(path.join(base, prefix));\n }\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates `$TMPDIR` scratch directories for specs and testkits, and reaps every one of them when the
|
|
3
|
+
* process exits.
|
|
4
|
+
*
|
|
5
|
+
* Use the shared `specTempDirs` instance — the reaper is registered per-instance, so a caller that
|
|
6
|
+
* constructs its own gets a second `exit` listener and no benefit.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SpecTempDirs {
|
|
9
|
+
private readonly created;
|
|
10
|
+
private reaperRegistered;
|
|
11
|
+
/**
|
|
12
|
+
* `fs.mkdtempSync` under `os.tmpdir()`, with the path remembered for cleanup.
|
|
13
|
+
*
|
|
14
|
+
* `prefix` keeps the existing `wp-<area>-` convention so a leaked tree still names its creator; the
|
|
15
|
+
* trailing dash matters because mkdtemp appends six random characters directly onto it.
|
|
16
|
+
*/
|
|
17
|
+
make(prefix: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* `make`, with symlinks resolved.
|
|
20
|
+
*
|
|
21
|
+
* macOS hands back `/var/folders/...` from `os.tmpdir()` while `/var` is a symlink to `/private/var`,
|
|
22
|
+
* so a fixture that compares a path it was given against one the code under test computed sees two
|
|
23
|
+
* different strings for the same directory. Specs that do that comparison call this instead.
|
|
24
|
+
*/
|
|
25
|
+
makeReal(prefix: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Removes every directory this instance created, then forgets them.
|
|
28
|
+
*
|
|
29
|
+
* Deliberately never throws: it runs from an `exit` handler where a throw would replace a passing
|
|
30
|
+
* test run's exit code with a crash, and a scratch directory that cannot be removed is a leak, not a
|
|
31
|
+
* failure. Callers may also invoke it directly — a long suite that wants its fixtures gone before the
|
|
32
|
+
* end of the run.
|
|
33
|
+
*/
|
|
34
|
+
reapAll(): void;
|
|
35
|
+
private registerReaper;
|
|
36
|
+
}
|
|
37
|
+
export declare const specTempDirs: SpecTempDirs;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.specTempDirs = exports.SpecTempDirs = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
+
const os = tslib_1.__importStar(require("os"));
|
|
7
|
+
const path = tslib_1.__importStar(require("path"));
|
|
8
|
+
const to_error_1 = require("./to-error");
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// ONE OWNER FOR EVERY `$TMPDIR` SCRATCH TREE THE TOOLING CREATES.
|
|
11
|
+
//
|
|
12
|
+
// THE DEFECT. Every `packages/tooling/**` spec builds its fixture with
|
|
13
|
+
// `specTempDirs.make('wp-<something>-')` and NONE of them removed it afterwards.
|
|
14
|
+
// Measured on one developer machine: 270,200 abandoned `wp-*` directories out of 286,270 total entries
|
|
15
|
+
// in `$TMPDIR` — 64,828 of them from `vitest.setup.mts` alone, which mints one isolated `$HOME` per test
|
|
16
|
+
// FILE per run. The cost is not disk (every `wp-*` prefix together is under 1 GiB; the `$HOME` dirs are
|
|
17
|
+
// empty by design) — it is INODES and the fact that `$TMPDIR` stops being inspectable: `ls` takes ~30s
|
|
18
|
+
// and `du` takes minutes, which is how this went unnoticed for as long as it did.
|
|
19
|
+
//
|
|
20
|
+
// WHY `$TMPDIR` AND NOT `.webpieces/`, WHICH IS WHERE EVERYTHING ELSE GOES. Because for a TEST fixture
|
|
21
|
+
// the whole point is to be outside the repo, and two separate mechanisms depend on that:
|
|
22
|
+
// - `vitest.setup.mts` mints a throwaway `$HOME` so a spec cannot read the developer's real
|
|
23
|
+
// `~/.webpieces/config.json`. A fake HOME inside the repo defeats its own isolation.
|
|
24
|
+
// - The fixtures `git init` and `git worktree add` INSIDE themselves. A nested git repo under the real
|
|
25
|
+
// repo root is what breaks the nx graph — the same hazard that makes `.claude/worktrees/` a
|
|
26
|
+
// mandatory gitignore entry.
|
|
27
|
+
// So the location was never the bug. The missing cleanup was.
|
|
28
|
+
//
|
|
29
|
+
// WHO ACTUALLY CALLS `reapAll`, AND WHY IT IS NOT A LINE IN EACH SPEC. An `afterAll` written into each
|
|
30
|
+
// of the 212 call sites is a line somebody has to remember, forever, in every new spec — precisely the
|
|
31
|
+
// discipline already demonstrated not to hold here. Instead `vitest.setup.mts` calls `reapAll()` in ONE
|
|
32
|
+
// global `afterAll`, so a call site swaps `fs.mkdtempSync(...)` for `specTempDirs.make(...)` and there
|
|
33
|
+
// is no other half to forget.
|
|
34
|
+
//
|
|
35
|
+
// THE `exit` REAPER BELOW IS THE SECONDARY BELT, NOT THE PRIMARY ONE — and the first cut of this file
|
|
36
|
+
// had that backwards. It relied on `process.on('exit')` alone, and a 145-file tooling run then left
|
|
37
|
+
// exactly 145 `wp-vitest-home-` directories behind: a 100% miss. The cause is `pool: 'forks'` (see
|
|
38
|
+
// vitest.config.mts) — vitest KILLS its workers rather than letting them exit, and a killed process runs
|
|
39
|
+
// no exit handler. The handler stays because it costs one listener and does fire for the non-vitest
|
|
40
|
+
// callers (testkits driven from plain node scripts), but nothing here should depend on it.
|
|
41
|
+
//
|
|
42
|
+
// SO CLEANUP IS BEST-EFFORT BY CONSTRUCTION, at two levels: a worker killed mid-file skips the
|
|
43
|
+
// `afterAll` too. That residue is why `CleanTmp` sweeps aged `wp-*` out of `$TMPDIR` via
|
|
44
|
+
// `TmpScratchSweeper` — belt, braces, and a sweep for what both of them miss.
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Creates `$TMPDIR` scratch directories for specs and testkits, and reaps every one of them when the
|
|
48
|
+
* process exits.
|
|
49
|
+
*
|
|
50
|
+
* Use the shared `specTempDirs` instance — the reaper is registered per-instance, so a caller that
|
|
51
|
+
* constructs its own gets a second `exit` listener and no benefit.
|
|
52
|
+
*/
|
|
53
|
+
class SpecTempDirs {
|
|
54
|
+
created = [];
|
|
55
|
+
reaperRegistered = false;
|
|
56
|
+
/**
|
|
57
|
+
* `fs.mkdtempSync` under `os.tmpdir()`, with the path remembered for cleanup.
|
|
58
|
+
*
|
|
59
|
+
* `prefix` keeps the existing `wp-<area>-` convention so a leaked tree still names its creator; the
|
|
60
|
+
* trailing dash matters because mkdtemp appends six random characters directly onto it.
|
|
61
|
+
*/
|
|
62
|
+
make(prefix) {
|
|
63
|
+
this.registerReaper();
|
|
64
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
|
65
|
+
this.created.push(dir);
|
|
66
|
+
return dir;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* `make`, with symlinks resolved.
|
|
70
|
+
*
|
|
71
|
+
* macOS hands back `/var/folders/...` from `os.tmpdir()` while `/var` is a symlink to `/private/var`,
|
|
72
|
+
* so a fixture that compares a path it was given against one the code under test computed sees two
|
|
73
|
+
* different strings for the same directory. Specs that do that comparison call this instead.
|
|
74
|
+
*/
|
|
75
|
+
makeReal(prefix) {
|
|
76
|
+
return fs.realpathSync(this.make(prefix));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Removes every directory this instance created, then forgets them.
|
|
80
|
+
*
|
|
81
|
+
* Deliberately never throws: it runs from an `exit` handler where a throw would replace a passing
|
|
82
|
+
* test run's exit code with a crash, and a scratch directory that cannot be removed is a leak, not a
|
|
83
|
+
* failure. Callers may also invoke it directly — a long suite that wants its fixtures gone before the
|
|
84
|
+
* end of the run.
|
|
85
|
+
*/
|
|
86
|
+
reapAll() {
|
|
87
|
+
const dirs = this.created.splice(0, this.created.length);
|
|
88
|
+
for (const dir of dirs) {
|
|
89
|
+
// webpieces-disable no-unmanaged-exceptions -- chokepoint: this runs from vitest's afterAll and
|
|
90
|
+
// from an exit handler, where a throw would turn a passing run into a crash over a scratch dir
|
|
91
|
+
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
92
|
+
try {
|
|
93
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
const error = (0, to_error_1.toError)(err);
|
|
97
|
+
process.stderr.write(`SpecTempDirs: could not remove ${dir}: ${error.message}\n`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// One listener per instance, added lazily so a process that never makes a fixture never registers.
|
|
102
|
+
registerReaper() {
|
|
103
|
+
if (this.reaperRegistered)
|
|
104
|
+
return;
|
|
105
|
+
this.reaperRegistered = true;
|
|
106
|
+
process.on('exit', () => this.reapAll());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.SpecTempDirs = SpecTempDirs;
|
|
110
|
+
// The shared instance — the reaper and the created-list are per-instance, so every caller must use this.
|
|
111
|
+
exports.specTempDirs = new SpecTempDirs();
|
|
112
|
+
//# sourceMappingURL=spec-temp-dirs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-temp-dirs.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/spec-temp-dirs.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,+CAAyB;AACzB,mDAA6B;AAC7B,yCAAqC;AAErC,8EAA8E;AAC9E,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,iFAAiF;AACjF,uGAAuG;AACvG,yGAAyG;AACzG,wGAAwG;AACxG,uGAAuG;AACvG,kFAAkF;AAClF,EAAE;AACF,uGAAuG;AACvG,yFAAyF;AACzF,8FAA8F;AAC9F,yFAAyF;AACzF,yGAAyG;AACzG,gGAAgG;AAChG,iCAAiC;AACjC,8DAA8D;AAC9D,EAAE;AACF,uGAAuG;AACvG,uGAAuG;AACvG,wGAAwG;AACxG,uGAAuG;AACvG,8BAA8B;AAC9B,EAAE;AACF,sGAAsG;AACtG,oGAAoG;AACpG,mGAAmG;AACnG,yGAAyG;AACzG,oGAAoG;AACpG,2FAA2F;AAC3F,EAAE;AACF,+FAA+F;AAC/F,yFAAyF;AACzF,8EAA8E;AAC9E,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAa,YAAY;IACJ,OAAO,GAAa,EAAE,CAAC;IAChC,gBAAgB,GAAG,KAAK,CAAC;IAEjC;;;;;OAKG;IACH,IAAI,CAAC,MAAc;QACf,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,MAAc;QACnB,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;OAOG;IACH,OAAO;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,gGAAgG;YAChG,+FAA+F;YAC/F,8DAA8D;YAC9D,IAAI,CAAC;gBACD,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;gBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,GAAG,KAAK,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACtF,CAAC;QACL,CAAC;IACL,CAAC;IAED,mGAAmG;IAC3F,cAAc;QAClB,IAAI,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;CACJ;AAzDD,oCAyDC;AAED,yGAAyG;AAC5F,QAAA,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC","sourcesContent":["import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { toError } from './to-error';\n\n// ---------------------------------------------------------------------------\n// ONE OWNER FOR EVERY `$TMPDIR` SCRATCH TREE THE TOOLING CREATES.\n//\n// THE DEFECT. Every `packages/tooling/**` spec builds its fixture with\n// `specTempDirs.make('wp-<something>-')` and NONE of them removed it afterwards.\n// Measured on one developer machine: 270,200 abandoned `wp-*` directories out of 286,270 total entries\n// in `$TMPDIR` — 64,828 of them from `vitest.setup.mts` alone, which mints one isolated `$HOME` per test\n// FILE per run. The cost is not disk (every `wp-*` prefix together is under 1 GiB; the `$HOME` dirs are\n// empty by design) — it is INODES and the fact that `$TMPDIR` stops being inspectable: `ls` takes ~30s\n// and `du` takes minutes, which is how this went unnoticed for as long as it did.\n//\n// WHY `$TMPDIR` AND NOT `.webpieces/`, WHICH IS WHERE EVERYTHING ELSE GOES. Because for a TEST fixture\n// the whole point is to be outside the repo, and two separate mechanisms depend on that:\n// - `vitest.setup.mts` mints a throwaway `$HOME` so a spec cannot read the developer's real\n// `~/.webpieces/config.json`. A fake HOME inside the repo defeats its own isolation.\n// - The fixtures `git init` and `git worktree add` INSIDE themselves. A nested git repo under the real\n// repo root is what breaks the nx graph — the same hazard that makes `.claude/worktrees/` a\n// mandatory gitignore entry.\n// So the location was never the bug. The missing cleanup was.\n//\n// WHO ACTUALLY CALLS `reapAll`, AND WHY IT IS NOT A LINE IN EACH SPEC. An `afterAll` written into each\n// of the 212 call sites is a line somebody has to remember, forever, in every new spec — precisely the\n// discipline already demonstrated not to hold here. Instead `vitest.setup.mts` calls `reapAll()` in ONE\n// global `afterAll`, so a call site swaps `fs.mkdtempSync(...)` for `specTempDirs.make(...)` and there\n// is no other half to forget.\n//\n// THE `exit` REAPER BELOW IS THE SECONDARY BELT, NOT THE PRIMARY ONE — and the first cut of this file\n// had that backwards. It relied on `process.on('exit')` alone, and a 145-file tooling run then left\n// exactly 145 `wp-vitest-home-` directories behind: a 100% miss. The cause is `pool: 'forks'` (see\n// vitest.config.mts) — vitest KILLS its workers rather than letting them exit, and a killed process runs\n// no exit handler. The handler stays because it costs one listener and does fire for the non-vitest\n// callers (testkits driven from plain node scripts), but nothing here should depend on it.\n//\n// SO CLEANUP IS BEST-EFFORT BY CONSTRUCTION, at two levels: a worker killed mid-file skips the\n// `afterAll` too. That residue is why `CleanTmp` sweeps aged `wp-*` out of `$TMPDIR` via\n// `TmpScratchSweeper` — belt, braces, and a sweep for what both of them miss.\n// ---------------------------------------------------------------------------\n\n/**\n * Creates `$TMPDIR` scratch directories for specs and testkits, and reaps every one of them when the\n * process exits.\n *\n * Use the shared `specTempDirs` instance — the reaper is registered per-instance, so a caller that\n * constructs its own gets a second `exit` listener and no benefit.\n */\nexport class SpecTempDirs {\n private readonly created: string[] = [];\n private reaperRegistered = false;\n\n /**\n * `fs.mkdtempSync` under `os.tmpdir()`, with the path remembered for cleanup.\n *\n * `prefix` keeps the existing `wp-<area>-` convention so a leaked tree still names its creator; the\n * trailing dash matters because mkdtemp appends six random characters directly onto it.\n */\n make(prefix: string): string {\n this.registerReaper();\n const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));\n this.created.push(dir);\n return dir;\n }\n\n /**\n * `make`, with symlinks resolved.\n *\n * macOS hands back `/var/folders/...` from `os.tmpdir()` while `/var` is a symlink to `/private/var`,\n * so a fixture that compares a path it was given against one the code under test computed sees two\n * different strings for the same directory. Specs that do that comparison call this instead.\n */\n makeReal(prefix: string): string {\n return fs.realpathSync(this.make(prefix));\n }\n\n /**\n * Removes every directory this instance created, then forgets them.\n *\n * Deliberately never throws: it runs from an `exit` handler where a throw would replace a passing\n * test run's exit code with a crash, and a scratch directory that cannot be removed is a leak, not a\n * failure. Callers may also invoke it directly — a long suite that wants its fixtures gone before the\n * end of the run.\n */\n reapAll(): void {\n const dirs = this.created.splice(0, this.created.length);\n for (const dir of dirs) {\n // webpieces-disable no-unmanaged-exceptions -- chokepoint: this runs from vitest's afterAll and\n // from an exit handler, where a throw would turn a passing run into a crash over a scratch dir\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n } catch (err: unknown) {\n const error = toError(err);\n process.stderr.write(`SpecTempDirs: could not remove ${dir}: ${error.message}\\n`);\n }\n }\n }\n\n // One listener per instance, added lazily so a process that never makes a fixture never registers.\n private registerReaper(): void {\n if (this.reaperRegistered) return;\n this.reaperRegistered = true;\n process.on('exit', (): void => this.reapAll());\n }\n}\n\n// The shared instance — the reaper and the created-list are per-instance, so every caller must use this.\nexport const specTempDirs = new SpecTempDirs();\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { SweepCount } from './aged-tree-sweep';
|
|
2
|
+
/**
|
|
3
|
+
* How long a `$TMPDIR` scratch tree survives before the backstop reaps it.
|
|
4
|
+
*
|
|
5
|
+
* Much shorter than `RETENTION_DAYS` (30) because the two are protecting different things: that one
|
|
6
|
+
* guards logs and state somebody may still want to read, while a scratch tree here is dead the moment
|
|
7
|
+
* its process ended. Three days is long enough that a suite running while a sweep happens cannot lose
|
|
8
|
+
* its own fixture, and it matches the interval macOS's own temp cleaner is documented to use.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TMP_SCRATCH_RETENTION_DAYS = 3;
|
|
11
|
+
/** The one name prefix webpieces mints under `os.tmpdir()`. Nothing outside it is ever a candidate. */
|
|
12
|
+
export declare const TMP_SCRATCH_PREFIX = "wp-";
|
|
13
|
+
/**
|
|
14
|
+
* Removes aged `wp-*` scratch trees from the shared user temp directory.
|
|
15
|
+
*
|
|
16
|
+
* Read `TMP_SCRATCH_PREFIX`'s comment before widening anything here: this walks a directory owned by
|
|
17
|
+
* the OS and shared with every program the developer runs.
|
|
18
|
+
*/
|
|
19
|
+
export declare class TmpScratchSweeper {
|
|
20
|
+
/**
|
|
21
|
+
* Delete every direct child of `os.tmpdir()` whose name starts with `wp-` and whose mtime is older
|
|
22
|
+
* than `cutoffMs`.
|
|
23
|
+
*
|
|
24
|
+
* Only DIRECT children, and only whole subtrees: it never descends looking for individual old files,
|
|
25
|
+
* because a half-emptied fixture is worse than an intact stale one. Counts removals as `dirs`.
|
|
26
|
+
*
|
|
27
|
+
* Never throws. It runs at the tail of a merge/PR flow that has already succeeded, and a temp
|
|
28
|
+
* directory that will not delete — held open, owned by another user — must not fail that flow.
|
|
29
|
+
*/
|
|
30
|
+
sweep(cutoffMs: number, onDelete?: (removed: string) => void): SweepCount;
|
|
31
|
+
private candidates;
|
|
32
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TmpScratchSweeper = exports.TMP_SCRATCH_PREFIX = exports.TMP_SCRATCH_RETENTION_DAYS = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
+
const os = tslib_1.__importStar(require("os"));
|
|
7
|
+
const path = tslib_1.__importStar(require("path"));
|
|
8
|
+
const inversify_1 = require("inversify");
|
|
9
|
+
const aged_tree_sweep_1 = require("./aged-tree-sweep");
|
|
10
|
+
const to_error_1 = require("./to-error");
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// THE BACKSTOP FOR SCRATCH TREES NO EXIT HANDLER GOT TO REAP.
|
|
13
|
+
//
|
|
14
|
+
// `SpecTempDirs` and `vitest.setup.mts` both reap on `process.on('exit')`, which covers every ordinary
|
|
15
|
+
// end of a run — pass, fail, thrown error, Ctrl-C. It does not cover a worker killed with SIGKILL, a
|
|
16
|
+
// box that loses power, or a vitest pool torn down harder than the handler can survive. Those leak
|
|
17
|
+
// exactly as before, at a much lower rate, and with nothing else on the machine owning the residue.
|
|
18
|
+
//
|
|
19
|
+
// So this exists, and it is deliberately NOT `AgedTreeSweeper` pointed at `os.tmpdir()`. That sweeper
|
|
20
|
+
// deletes every file under a root older than the cutoff, which is correct for a directory webpieces
|
|
21
|
+
// OWNS and catastrophic for one it SHARES with the operating system and every other program on the box.
|
|
22
|
+
// This one removes whole subtrees and only ones whose NAME webpieces minted, so the blast radius is
|
|
23
|
+
// stated in the predicate rather than trusted to the caller's choice of root.
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* How long a `$TMPDIR` scratch tree survives before the backstop reaps it.
|
|
27
|
+
*
|
|
28
|
+
* Much shorter than `RETENTION_DAYS` (30) because the two are protecting different things: that one
|
|
29
|
+
* guards logs and state somebody may still want to read, while a scratch tree here is dead the moment
|
|
30
|
+
* its process ended. Three days is long enough that a suite running while a sweep happens cannot lose
|
|
31
|
+
* its own fixture, and it matches the interval macOS's own temp cleaner is documented to use.
|
|
32
|
+
*/
|
|
33
|
+
exports.TMP_SCRATCH_RETENTION_DAYS = 3;
|
|
34
|
+
/** The one name prefix webpieces mints under `os.tmpdir()`. Nothing outside it is ever a candidate. */
|
|
35
|
+
exports.TMP_SCRATCH_PREFIX = 'wp-';
|
|
36
|
+
/**
|
|
37
|
+
* Removes aged `wp-*` scratch trees from the shared user temp directory.
|
|
38
|
+
*
|
|
39
|
+
* Read `TMP_SCRATCH_PREFIX`'s comment before widening anything here: this walks a directory owned by
|
|
40
|
+
* the OS and shared with every program the developer runs.
|
|
41
|
+
*/
|
|
42
|
+
let TmpScratchSweeper = class TmpScratchSweeper {
|
|
43
|
+
/**
|
|
44
|
+
* Delete every direct child of `os.tmpdir()` whose name starts with `wp-` and whose mtime is older
|
|
45
|
+
* than `cutoffMs`.
|
|
46
|
+
*
|
|
47
|
+
* Only DIRECT children, and only whole subtrees: it never descends looking for individual old files,
|
|
48
|
+
* because a half-emptied fixture is worse than an intact stale one. Counts removals as `dirs`.
|
|
49
|
+
*
|
|
50
|
+
* Never throws. It runs at the tail of a merge/PR flow that has already succeeded, and a temp
|
|
51
|
+
* directory that will not delete — held open, owned by another user — must not fail that flow.
|
|
52
|
+
*/
|
|
53
|
+
sweep(cutoffMs, onDelete = () => { }) {
|
|
54
|
+
const root = os.tmpdir();
|
|
55
|
+
const count = new aged_tree_sweep_1.SweepCount();
|
|
56
|
+
const now = Date.now();
|
|
57
|
+
for (const name of this.candidates(root)) {
|
|
58
|
+
const full = path.join(root, name);
|
|
59
|
+
// webpieces-disable no-unmanaged-exceptions -- chokepoint: this sweeps a directory shared with
|
|
60
|
+
// the OS at the tail of an already-successful flow; one unremovable entry must not fail it
|
|
61
|
+
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
62
|
+
try {
|
|
63
|
+
if (now - fs.statSync(full).mtimeMs < cutoffMs)
|
|
64
|
+
continue;
|
|
65
|
+
fs.rmSync(full, { recursive: true, force: true });
|
|
66
|
+
count.dirs += 1;
|
|
67
|
+
onDelete(full);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
// A vanished entry is the common case — a concurrent run reaped its own fixture between
|
|
71
|
+
// the listing and the stat — and is not worth a word. Anything else is reported and skipped.
|
|
72
|
+
const error = (0, to_error_1.toError)(err);
|
|
73
|
+
if (fs.existsSync(full))
|
|
74
|
+
process.stderr.write(`TmpScratchSweeper: skipped ${full}: ${error.message}\n`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return count;
|
|
78
|
+
}
|
|
79
|
+
// An unreadable temp dir is a no-op, not an error: the backstop is best-effort by construction.
|
|
80
|
+
candidates(root) {
|
|
81
|
+
// webpieces-disable no-unmanaged-exceptions -- chokepoint: an unreadable temp dir is a no-op for a
|
|
82
|
+
// best-effort backstop, never an error worth propagating
|
|
83
|
+
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
84
|
+
try {
|
|
85
|
+
return fs.readdirSync(root).filter((name) => name.startsWith(exports.TMP_SCRATCH_PREFIX));
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
// webpieces-disable catch-error-pattern -- the error is deliberately unused: "cannot read it"
|
|
89
|
+
// and "it is empty" are the same answer here
|
|
90
|
+
//const error = toError(err);
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
exports.TmpScratchSweeper = TmpScratchSweeper;
|
|
96
|
+
exports.TmpScratchSweeper = TmpScratchSweeper = tslib_1.__decorate([
|
|
97
|
+
(0, inversify_1.injectable)(inversify_1.bindingScopeValues.Singleton)
|
|
98
|
+
], TmpScratchSweeper);
|
|
99
|
+
//# sourceMappingURL=tmp-scratch-sweep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmp-scratch-sweep.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/tmp-scratch-sweep.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,+CAAyB;AACzB,mDAA6B;AAC7B,yCAA2D;AAC3D,uDAA+C;AAC/C,yCAAqC;AAErC,8EAA8E;AAC9E,8DAA8D;AAC9D,EAAE;AACF,uGAAuG;AACvG,qGAAqG;AACrG,mGAAmG;AACnG,oGAAoG;AACpG,EAAE;AACF,sGAAsG;AACtG,oGAAoG;AACpG,wGAAwG;AACxG,oGAAoG;AACpG,8EAA8E;AAC9E,8EAA8E;AAE9E;;;;;;;GAOG;AACU,QAAA,0BAA0B,GAAG,CAAC,CAAC;AAE5C,uGAAuG;AAC1F,QAAA,kBAAkB,GAAG,KAAK,CAAC;AAExC;;;;;GAKG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAC1B;;;;;;;;;OASG;IACH,KAAK,CAAC,QAAgB,EAAE,WAAsC,GAAS,EAAE,GAAE,CAAC;QACxE,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,4BAAU,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACnC,+FAA+F;YAC/F,2FAA2F;YAC3F,8DAA8D;YAC9D,IAAI,CAAC;gBACD,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,QAAQ;oBAAE,SAAS;gBACzD,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;gBAChB,QAAQ,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,wFAAwF;gBACxF,6FAA6F;gBAC7F,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;gBAC3B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;oBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,IAAI,KAAK,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YAC5G,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,gGAAgG;IACxF,UAAU,CAAC,IAAY;QAC3B,mGAAmG;QACnG,yDAAyD;QACzD,8DAA8D;QAC9D,IAAI,CAAC;YACD,OAAO,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAY,EAAW,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,0BAAkB,CAAC,CAAC,CAAC;QACvG,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,8FAA8F;YAC9F,6CAA6C;YAC7C,6BAA6B;YAC7B,OAAO,EAAE,CAAC;QACd,CAAC;IACL,CAAC;CACJ,CAAA;AAjDY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,sBAAU,EAAC,8BAAkB,CAAC,SAAS,CAAC;GAC5B,iBAAiB,CAiD7B","sourcesContent":["import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { SweepCount } from './aged-tree-sweep';\nimport { toError } from './to-error';\n\n// ---------------------------------------------------------------------------\n// THE BACKSTOP FOR SCRATCH TREES NO EXIT HANDLER GOT TO REAP.\n//\n// `SpecTempDirs` and `vitest.setup.mts` both reap on `process.on('exit')`, which covers every ordinary\n// end of a run — pass, fail, thrown error, Ctrl-C. It does not cover a worker killed with SIGKILL, a\n// box that loses power, or a vitest pool torn down harder than the handler can survive. Those leak\n// exactly as before, at a much lower rate, and with nothing else on the machine owning the residue.\n//\n// So this exists, and it is deliberately NOT `AgedTreeSweeper` pointed at `os.tmpdir()`. That sweeper\n// deletes every file under a root older than the cutoff, which is correct for a directory webpieces\n// OWNS and catastrophic for one it SHARES with the operating system and every other program on the box.\n// This one removes whole subtrees and only ones whose NAME webpieces minted, so the blast radius is\n// stated in the predicate rather than trusted to the caller's choice of root.\n// ---------------------------------------------------------------------------\n\n/**\n * How long a `$TMPDIR` scratch tree survives before the backstop reaps it.\n *\n * Much shorter than `RETENTION_DAYS` (30) because the two are protecting different things: that one\n * guards logs and state somebody may still want to read, while a scratch tree here is dead the moment\n * its process ended. Three days is long enough that a suite running while a sweep happens cannot lose\n * its own fixture, and it matches the interval macOS's own temp cleaner is documented to use.\n */\nexport const TMP_SCRATCH_RETENTION_DAYS = 3;\n\n/** The one name prefix webpieces mints under `os.tmpdir()`. Nothing outside it is ever a candidate. */\nexport const TMP_SCRATCH_PREFIX = 'wp-';\n\n/**\n * Removes aged `wp-*` scratch trees from the shared user temp directory.\n *\n * Read `TMP_SCRATCH_PREFIX`'s comment before widening anything here: this walks a directory owned by\n * the OS and shared with every program the developer runs.\n */\n@injectable(bindingScopeValues.Singleton)\nexport class TmpScratchSweeper {\n /**\n * Delete every direct child of `os.tmpdir()` whose name starts with `wp-` and whose mtime is older\n * than `cutoffMs`.\n *\n * Only DIRECT children, and only whole subtrees: it never descends looking for individual old files,\n * because a half-emptied fixture is worse than an intact stale one. Counts removals as `dirs`.\n *\n * Never throws. It runs at the tail of a merge/PR flow that has already succeeded, and a temp\n * directory that will not delete — held open, owned by another user — must not fail that flow.\n */\n sweep(cutoffMs: number, onDelete: (removed: string) => void = (): void => {}): SweepCount {\n const root = os.tmpdir();\n const count = new SweepCount();\n const now = Date.now();\n for (const name of this.candidates(root)) {\n const full = path.join(root, name);\n // webpieces-disable no-unmanaged-exceptions -- chokepoint: this sweeps a directory shared with\n // the OS at the tail of an already-successful flow; one unremovable entry must not fail it\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n if (now - fs.statSync(full).mtimeMs < cutoffMs) continue;\n fs.rmSync(full, { recursive: true, force: true });\n count.dirs += 1;\n onDelete(full);\n } catch (err: unknown) {\n // A vanished entry is the common case — a concurrent run reaped its own fixture between\n // the listing and the stat — and is not worth a word. Anything else is reported and skipped.\n const error = toError(err);\n if (fs.existsSync(full)) process.stderr.write(`TmpScratchSweeper: skipped ${full}: ${error.message}\\n`);\n }\n }\n return count;\n }\n\n // An unreadable temp dir is a no-op, not an error: the backstop is best-effort by construction.\n private candidates(root: string): string[] {\n // webpieces-disable no-unmanaged-exceptions -- chokepoint: an unreadable temp dir is a no-op for a\n // best-effort backstop, never an error worth propagating\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return fs.readdirSync(root).filter((name: string): boolean => name.startsWith(TMP_SCRATCH_PREFIX));\n } catch (err: unknown) {\n // webpieces-disable catch-error-pattern -- the error is deliberately unused: \"cannot read it\"\n // and \"it is empty\" are the same answer here\n //const error = toError(err);\n return [];\n }\n }\n}\n"]}
|