@danmoisan/drm-copilot-mcp 1.1.4 → 1.1.5
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/out/mcp-server.js +286 -10
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +477 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +120 -12
- package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +131 -2
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +9 -0
- package/resources/claude-customizations/config/orchestration-routing.json +1 -0
- package/resources/claude-customizations/pack-manifests/core.json +1 -0
- package/resources/codex-and-agents-customizations/.agents/skills/codex-model-routing/SKILL.md +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward-c1.toml +22 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward-c2.toml +22 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward-c3-elevated.toml +22 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward-c3.toml +22 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward-c4.toml +22 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward.toml +2 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +7 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +7 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +7 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +7 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +7 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +7 -0
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +477 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +125 -12
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +8 -1
- package/resources/config/orchestration-routing.json +1 -0
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +10 -2
package/out/mcp-server.js
CHANGED
|
@@ -2671,18 +2671,18 @@ var require_validate = __commonJS({
|
|
|
2671
2671
|
const { schemaCode } = this;
|
|
2672
2672
|
this.fail((0, codegen_1._)`${schemaCode} !== undefined && (${(0, codegen_1.or)(this.invalid$data(), condition)})`);
|
|
2673
2673
|
}
|
|
2674
|
-
error(
|
|
2674
|
+
error(append2, errorParams, errorPaths) {
|
|
2675
2675
|
if (errorParams) {
|
|
2676
2676
|
this.setParams(errorParams);
|
|
2677
|
-
this._error(
|
|
2677
|
+
this._error(append2, errorPaths);
|
|
2678
2678
|
this.setParams({});
|
|
2679
2679
|
return;
|
|
2680
2680
|
}
|
|
2681
|
-
this._error(
|
|
2681
|
+
this._error(append2, errorPaths);
|
|
2682
2682
|
}
|
|
2683
|
-
_error(
|
|
2683
|
+
_error(append2, errorPaths) {
|
|
2684
2684
|
;
|
|
2685
|
-
(
|
|
2685
|
+
(append2 ? errors_1.reportExtraError : errors_1.reportError)(this, this.def.error, errorPaths);
|
|
2686
2686
|
}
|
|
2687
2687
|
$dataError() {
|
|
2688
2688
|
(0, errors_1.reportError)(this, this.def.$dataError || errors_1.keyword$DataError);
|
|
@@ -23551,6 +23551,7 @@ var GENERATED_AGENT_FAMILIES = /* @__PURE__ */ new Set([
|
|
|
23551
23551
|
"atomic-planner",
|
|
23552
23552
|
"atomic-executor",
|
|
23553
23553
|
"feature-reviewer",
|
|
23554
|
+
"commit-steward",
|
|
23554
23555
|
"task-researcher",
|
|
23555
23556
|
"prd-feature",
|
|
23556
23557
|
"pr-author",
|
|
@@ -26957,7 +26958,14 @@ function classifyKind(argv) {
|
|
|
26957
26958
|
return "other";
|
|
26958
26959
|
}
|
|
26959
26960
|
function splitLines2(text) {
|
|
26960
|
-
|
|
26961
|
+
if (text === "") {
|
|
26962
|
+
return [];
|
|
26963
|
+
}
|
|
26964
|
+
const lines = text.split(/\r\n|\n|\r/);
|
|
26965
|
+
if (lines[lines.length - 1] === "") {
|
|
26966
|
+
lines.pop();
|
|
26967
|
+
}
|
|
26968
|
+
return lines;
|
|
26961
26969
|
}
|
|
26962
26970
|
function inlineSpans(line) {
|
|
26963
26971
|
const spans = [];
|
|
@@ -26979,34 +26987,63 @@ function appendCommand(commands, taskId, sourceLine, rawSpan) {
|
|
|
26979
26987
|
sourceLine,
|
|
26980
26988
|
rawSpan,
|
|
26981
26989
|
argv,
|
|
26982
|
-
kind: classifyKind(argv)
|
|
26990
|
+
kind: classifyKind(argv),
|
|
26991
|
+
taskText: ""
|
|
26983
26992
|
});
|
|
26984
26993
|
}
|
|
26994
|
+
function closeWindow(commands, windowStart, windowLines) {
|
|
26995
|
+
if (windowStart >= commands.length) {
|
|
26996
|
+
return;
|
|
26997
|
+
}
|
|
26998
|
+
const taskText = windowLines.join("\n");
|
|
26999
|
+
for (let index = windowStart; index < commands.length; index += 1) {
|
|
27000
|
+
const record2 = commands[index];
|
|
27001
|
+
if (record2 === void 0) {
|
|
27002
|
+
continue;
|
|
27003
|
+
}
|
|
27004
|
+
commands[index] = { ...record2, taskText };
|
|
27005
|
+
}
|
|
27006
|
+
}
|
|
26985
27007
|
function extractPlanCommands(text) {
|
|
26986
27008
|
const commands = [];
|
|
26987
27009
|
let currentTask = null;
|
|
26988
27010
|
let inFence = false;
|
|
27011
|
+
let windowLines = [];
|
|
27012
|
+
let windowStart = 0;
|
|
26989
27013
|
const lines = splitLines2(text);
|
|
26990
27014
|
for (let index = 0; index < lines.length; index += 1) {
|
|
26991
27015
|
const line = lines[index] ?? "";
|
|
26992
27016
|
const lineNumber = index + 1;
|
|
26993
27017
|
if (FENCE_RE.test(line)) {
|
|
26994
27018
|
inFence = !inFence;
|
|
27019
|
+
if (currentTask !== null) {
|
|
27020
|
+
windowLines.push(line);
|
|
27021
|
+
}
|
|
26995
27022
|
continue;
|
|
26996
27023
|
}
|
|
26997
27024
|
if (inFence) {
|
|
27025
|
+
if (currentTask === null) {
|
|
27026
|
+
continue;
|
|
27027
|
+
}
|
|
27028
|
+
windowLines.push(line);
|
|
26998
27029
|
const fenced = line.trim();
|
|
26999
|
-
if (
|
|
27030
|
+
if (fenced !== "") {
|
|
27000
27031
|
appendCommand(commands, currentTask, lineNumber, fenced);
|
|
27001
27032
|
}
|
|
27002
27033
|
continue;
|
|
27003
27034
|
}
|
|
27004
27035
|
if (PLAN_GATE_HEADING_PATTERN.test(line)) {
|
|
27036
|
+
closeWindow(commands, windowStart, windowLines);
|
|
27037
|
+
windowStart = commands.length;
|
|
27038
|
+
windowLines = [];
|
|
27005
27039
|
currentTask = null;
|
|
27006
27040
|
continue;
|
|
27007
27041
|
}
|
|
27008
27042
|
const taskMatch = PLAN_GATE_TASK_PATTERN.exec(line);
|
|
27009
27043
|
if (taskMatch !== null) {
|
|
27044
|
+
closeWindow(commands, windowStart, windowLines);
|
|
27045
|
+
windowStart = commands.length;
|
|
27046
|
+
windowLines = [];
|
|
27010
27047
|
const phase = taskMatch.groups?.["phase"] ?? "";
|
|
27011
27048
|
const task = taskMatch.groups?.["task"] ?? "";
|
|
27012
27049
|
currentTask = `P${phase}-T${task}`;
|
|
@@ -27014,10 +27051,12 @@ function extractPlanCommands(text) {
|
|
|
27014
27051
|
if (currentTask === null) {
|
|
27015
27052
|
continue;
|
|
27016
27053
|
}
|
|
27054
|
+
windowLines.push(line);
|
|
27017
27055
|
for (const span of inlineSpans(line)) {
|
|
27018
27056
|
appendCommand(commands, currentTask, lineNumber, span);
|
|
27019
27057
|
}
|
|
27020
27058
|
}
|
|
27059
|
+
closeWindow(commands, windowStart, windowLines);
|
|
27021
27060
|
return commands;
|
|
27022
27061
|
}
|
|
27023
27062
|
|
|
@@ -27167,6 +27206,242 @@ function hasCrossLinePresence(context, literal2) {
|
|
|
27167
27206
|
return false;
|
|
27168
27207
|
}
|
|
27169
27208
|
|
|
27209
|
+
// ../../extensions/drm-copilot/src/lib/validate/plan-gate-observability.ts
|
|
27210
|
+
var G7_SEVERITY = "warning";
|
|
27211
|
+
var G8_SEVERITY = "warning";
|
|
27212
|
+
var G8B_SEVERITY = "warning";
|
|
27213
|
+
var G9_SEVERITY = "warning";
|
|
27214
|
+
var WRITE_MODE_REGISTER = [
|
|
27215
|
+
{
|
|
27216
|
+
name: "black-write",
|
|
27217
|
+
shapes: [{ words: ["black"] }],
|
|
27218
|
+
excludes: ["--check", "--diff"],
|
|
27219
|
+
markers: ["reformatted", "left unchanged", "unchanged"]
|
|
27220
|
+
},
|
|
27221
|
+
{
|
|
27222
|
+
name: "ruff-fix",
|
|
27223
|
+
shapes: [{ words: ["ruff", "check"] }],
|
|
27224
|
+
excludes: ["--no-fix"],
|
|
27225
|
+
markers: ["Fixed", "All checks passed", "fixes applied"]
|
|
27226
|
+
},
|
|
27227
|
+
{
|
|
27228
|
+
name: "prettier-write",
|
|
27229
|
+
shapes: [
|
|
27230
|
+
{ words: ["prettier"], requires: ["--write"] },
|
|
27231
|
+
{ words: ["npm", "run", "format"] }
|
|
27232
|
+
],
|
|
27233
|
+
excludes: [],
|
|
27234
|
+
markers: ["(unchanged)", "unchanged", "rewrote"]
|
|
27235
|
+
},
|
|
27236
|
+
{
|
|
27237
|
+
name: "poshqc-format",
|
|
27238
|
+
shapes: [{ suffix: "run_poshqc_format" }],
|
|
27239
|
+
excludes: [],
|
|
27240
|
+
markers: ["formatted", "unchanged"]
|
|
27241
|
+
},
|
|
27242
|
+
{
|
|
27243
|
+
name: "poshqc-analyze-autofix",
|
|
27244
|
+
shapes: [{ suffix: "run_poshqc_analyze_autofix" }],
|
|
27245
|
+
excludes: [],
|
|
27246
|
+
markers: ["autofix", "Fixed", "unchanged"]
|
|
27247
|
+
},
|
|
27248
|
+
{
|
|
27249
|
+
name: "poshqc-suite",
|
|
27250
|
+
shapes: [{ suffix: "run_poshqc_suite" }],
|
|
27251
|
+
excludes: [],
|
|
27252
|
+
markers: ["formatted", "unchanged"]
|
|
27253
|
+
}
|
|
27254
|
+
];
|
|
27255
|
+
var EXECUTABLE_SCAN_LIMIT2 = 4;
|
|
27256
|
+
var PATHSPEC_SEPARATOR = "--";
|
|
27257
|
+
var INDEX_FLAGS = ["--cached", "--staged"];
|
|
27258
|
+
var NAME_LISTING_FLAGS = ["--name-only", "--name-status"];
|
|
27259
|
+
var GIT_DIFF_SPAN = "git diff";
|
|
27260
|
+
var GIT_STATUS_SPAN = "git status";
|
|
27261
|
+
var GIT_ADD_SPAN = "git add";
|
|
27262
|
+
var GIT_PORCELAIN_SPAN = "git status --porcelain";
|
|
27263
|
+
var PROJECT_CONFIG_PATH = "pyproject.toml";
|
|
27264
|
+
var TERMINAL_REPORTER_PREFIX = "--cov-report=term";
|
|
27265
|
+
var FAIL_UNDER_PREFIX = "--cov-fail-under";
|
|
27266
|
+
var ADDOPTS_PATTERNS = [
|
|
27267
|
+
/addopts[ \t]*=[ \t]*"([^"]*)"/,
|
|
27268
|
+
/addopts[ \t]*=[ \t]*'([^']*)'/
|
|
27269
|
+
];
|
|
27270
|
+
function append(report, severity, finding) {
|
|
27271
|
+
const channel = severity === BLOCKING_CHANNEL ? report.blocking : report.warnings;
|
|
27272
|
+
channel.push(finding);
|
|
27273
|
+
}
|
|
27274
|
+
function executablePositions(argv) {
|
|
27275
|
+
const limit = Math.min(argv.length, EXECUTABLE_SCAN_LIMIT2);
|
|
27276
|
+
const positions = [];
|
|
27277
|
+
for (let index = 0; index < limit; index += 1) {
|
|
27278
|
+
if (index === 0 || !(argv[index - 1] ?? "").startsWith("-")) {
|
|
27279
|
+
positions.push(index);
|
|
27280
|
+
}
|
|
27281
|
+
}
|
|
27282
|
+
return positions;
|
|
27283
|
+
}
|
|
27284
|
+
function shapeMatches(argv, shape) {
|
|
27285
|
+
const requires = shape.requires ?? [];
|
|
27286
|
+
if (requires.some((required2) => !argv.includes(required2))) {
|
|
27287
|
+
return false;
|
|
27288
|
+
}
|
|
27289
|
+
const words2 = shape.words ?? [];
|
|
27290
|
+
for (const index of executablePositions(argv)) {
|
|
27291
|
+
if (shape.suffix !== void 0 && shape.suffix !== "") {
|
|
27292
|
+
if ((argv[index] ?? "").endsWith(shape.suffix)) {
|
|
27293
|
+
return true;
|
|
27294
|
+
}
|
|
27295
|
+
continue;
|
|
27296
|
+
}
|
|
27297
|
+
const end = index + words2.length;
|
|
27298
|
+
if (end <= argv.length && words2.every((word, offset) => argv[index + offset] === word)) {
|
|
27299
|
+
return true;
|
|
27300
|
+
}
|
|
27301
|
+
}
|
|
27302
|
+
return false;
|
|
27303
|
+
}
|
|
27304
|
+
function matchingEntry(argv) {
|
|
27305
|
+
for (const entry of WRITE_MODE_REGISTER) {
|
|
27306
|
+
if (entry.excludes.some((excluded) => argv.includes(excluded))) {
|
|
27307
|
+
continue;
|
|
27308
|
+
}
|
|
27309
|
+
if (entry.shapes.some((shape) => shapeMatches(argv, shape))) {
|
|
27310
|
+
return entry;
|
|
27311
|
+
}
|
|
27312
|
+
}
|
|
27313
|
+
return null;
|
|
27314
|
+
}
|
|
27315
|
+
function taskTextWithoutSpan(command) {
|
|
27316
|
+
return command.taskText.replace(command.rawSpan, " ");
|
|
27317
|
+
}
|
|
27318
|
+
function evaluateWriteMode(report, command) {
|
|
27319
|
+
const entry = matchingEntry(command.argv);
|
|
27320
|
+
if (entry === null) {
|
|
27321
|
+
return;
|
|
27322
|
+
}
|
|
27323
|
+
const remainder = taskTextWithoutSpan(command);
|
|
27324
|
+
if (entry.markers.some((marker) => remainder.includes(marker))) {
|
|
27325
|
+
return;
|
|
27326
|
+
}
|
|
27327
|
+
append(
|
|
27328
|
+
report,
|
|
27329
|
+
G7_SEVERITY,
|
|
27330
|
+
`[${command.taskId}] write-mode command \`${command.rawSpan}\` rewrites tracked source and exits 0 after rewriting; the attributed task text carries none of its observation markers. Record an observation beyond the exit code.`
|
|
27331
|
+
);
|
|
27332
|
+
}
|
|
27333
|
+
function gitDiffIndex(argv) {
|
|
27334
|
+
const limit = Math.min(argv.length, EXECUTABLE_SCAN_LIMIT2);
|
|
27335
|
+
for (let index = 0; index < limit; index += 1) {
|
|
27336
|
+
if (argv[index] === "git" && argv[index + 1] === "diff") {
|
|
27337
|
+
return index + 1;
|
|
27338
|
+
}
|
|
27339
|
+
}
|
|
27340
|
+
return null;
|
|
27341
|
+
}
|
|
27342
|
+
function diffOperands(argv, diffIndex) {
|
|
27343
|
+
const operands = [];
|
|
27344
|
+
for (const word of argv.slice(diffIndex + 1)) {
|
|
27345
|
+
if (word === PATHSPEC_SEPARATOR) {
|
|
27346
|
+
break;
|
|
27347
|
+
}
|
|
27348
|
+
operands.push(word);
|
|
27349
|
+
}
|
|
27350
|
+
return operands;
|
|
27351
|
+
}
|
|
27352
|
+
function carriesPairingCompanion(command) {
|
|
27353
|
+
const remainder = taskTextWithoutSpan(command);
|
|
27354
|
+
return remainder.includes(GIT_DIFF_SPAN) || remainder.includes(GIT_STATUS_SPAN);
|
|
27355
|
+
}
|
|
27356
|
+
function carriesListingCompanion(command) {
|
|
27357
|
+
const remainder = taskTextWithoutSpan(command);
|
|
27358
|
+
return remainder.includes(GIT_ADD_SPAN) || remainder.includes(GIT_PORCELAIN_SPAN);
|
|
27359
|
+
}
|
|
27360
|
+
function evaluateGitDiff(report, command) {
|
|
27361
|
+
const argv = command.argv;
|
|
27362
|
+
const diffIndex = gitDiffIndex(argv);
|
|
27363
|
+
if (diffIndex === null) {
|
|
27364
|
+
return;
|
|
27365
|
+
}
|
|
27366
|
+
const operands = diffOperands(argv, diffIndex);
|
|
27367
|
+
const hasRefOperand = operands.some((word) => !word.startsWith("-"));
|
|
27368
|
+
const hasIndexFlag = INDEX_FLAGS.some((flag) => argv.includes(flag));
|
|
27369
|
+
if (!hasRefOperand && !hasIndexFlag) {
|
|
27370
|
+
if (!carriesPairingCompanion(command)) {
|
|
27371
|
+
append(
|
|
27372
|
+
report,
|
|
27373
|
+
G8_SEVERITY,
|
|
27374
|
+
`[${command.taskId}] git diff span \`${command.rawSpan}\` carries no ref operand and no --cached flag; it compares the worktree against the index and passes vacuously once the change is committed. Anchor the diff to a ref.`
|
|
27375
|
+
);
|
|
27376
|
+
}
|
|
27377
|
+
return;
|
|
27378
|
+
}
|
|
27379
|
+
if (hasRefOperand && NAME_LISTING_FLAGS.some((flag) => argv.includes(flag))) {
|
|
27380
|
+
if (!carriesListingCompanion(command)) {
|
|
27381
|
+
append(
|
|
27382
|
+
report,
|
|
27383
|
+
G8B_SEVERITY,
|
|
27384
|
+
`[${command.taskId}] name-listing diff \`${command.rawSpan}\` never reports an untracked file, and the attributed task text carries neither a staging span nor a porcelain-status span; a path the plan creates is invisible to it. Add a staging or porcelain-status companion.`
|
|
27385
|
+
);
|
|
27386
|
+
}
|
|
27387
|
+
}
|
|
27388
|
+
}
|
|
27389
|
+
function projectAddopts(context) {
|
|
27390
|
+
const text = context.git.readTrackedText(PROJECT_CONFIG_PATH);
|
|
27391
|
+
if (text === "") {
|
|
27392
|
+
return null;
|
|
27393
|
+
}
|
|
27394
|
+
for (const pattern of ADDOPTS_PATTERNS) {
|
|
27395
|
+
const match = pattern.exec(text);
|
|
27396
|
+
if (match !== null) {
|
|
27397
|
+
return match[1] ?? "";
|
|
27398
|
+
}
|
|
27399
|
+
}
|
|
27400
|
+
return "";
|
|
27401
|
+
}
|
|
27402
|
+
function collectCoverageReporter(pending, command, addopts) {
|
|
27403
|
+
const argv = command.argv;
|
|
27404
|
+
if (!argv.some((word) => isCovFlagToken(word))) {
|
|
27405
|
+
return;
|
|
27406
|
+
}
|
|
27407
|
+
if (argv.some((word) => word.startsWith(TERMINAL_REPORTER_PREFIX))) {
|
|
27408
|
+
return;
|
|
27409
|
+
}
|
|
27410
|
+
if (argv.some((word) => word.startsWith(FAIL_UNDER_PREFIX))) {
|
|
27411
|
+
return;
|
|
27412
|
+
}
|
|
27413
|
+
if (addopts.includes(TERMINAL_REPORTER_PREFIX)) {
|
|
27414
|
+
return;
|
|
27415
|
+
}
|
|
27416
|
+
pending.push(
|
|
27417
|
+
`[${command.taskId}] coverage command \`${command.rawSpan}\` supplies no terminal reporter and the project addopts supplies none either, so no coverage table is printed. Add --cov-report=term-missing.`
|
|
27418
|
+
);
|
|
27419
|
+
}
|
|
27420
|
+
function evaluateObservabilityGates(report, commands, context) {
|
|
27421
|
+
for (const command of commands) {
|
|
27422
|
+
evaluateWriteMode(report, command);
|
|
27423
|
+
evaluateGitDiff(report, command);
|
|
27424
|
+
}
|
|
27425
|
+
if (context === void 0) {
|
|
27426
|
+
return;
|
|
27427
|
+
}
|
|
27428
|
+
const pending = [];
|
|
27429
|
+
try {
|
|
27430
|
+
const addopts = projectAddopts(context);
|
|
27431
|
+
if (addopts === null) {
|
|
27432
|
+
return;
|
|
27433
|
+
}
|
|
27434
|
+
for (const command of commands) {
|
|
27435
|
+
collectCoverageReporter(pending, command, addopts);
|
|
27436
|
+
}
|
|
27437
|
+
} catch {
|
|
27438
|
+
return;
|
|
27439
|
+
}
|
|
27440
|
+
for (const finding of pending) {
|
|
27441
|
+
append(report, G9_SEVERITY, finding);
|
|
27442
|
+
}
|
|
27443
|
+
}
|
|
27444
|
+
|
|
27170
27445
|
// ../../extensions/drm-copilot/src/lib/validate/plan-gate-discrimination.ts
|
|
27171
27446
|
var G5_SEVERITY = "warning";
|
|
27172
27447
|
var CommandRunnerPlanGateRepository = class {
|
|
@@ -27262,6 +27537,7 @@ function evaluatePlanGates(text, context) {
|
|
|
27262
27537
|
evaluateCovValue(report, command, cov, context);
|
|
27263
27538
|
}
|
|
27264
27539
|
}
|
|
27540
|
+
evaluateObservabilityGates(report, commands, context);
|
|
27265
27541
|
if (context !== void 0) {
|
|
27266
27542
|
evaluateLiteralRules(report, text, commands, context);
|
|
27267
27543
|
}
|
|
@@ -31555,12 +31831,12 @@ function buildAppendixText(collected, clock) {
|
|
|
31555
31831
|
}
|
|
31556
31832
|
return appendixText;
|
|
31557
31833
|
}
|
|
31558
|
-
function writeOutput(fs10, text, outPath,
|
|
31834
|
+
function writeOutput(fs10, text, outPath, append2) {
|
|
31559
31835
|
const parent = parentDir(outPath);
|
|
31560
31836
|
if (parent) {
|
|
31561
31837
|
fs10.ensureDir(parent);
|
|
31562
31838
|
}
|
|
31563
|
-
if (
|
|
31839
|
+
if (append2 && fs10.isFile(outPath)) {
|
|
31564
31840
|
const existing = fs10.readTextFile(outPath);
|
|
31565
31841
|
fs10.writeTextFile(outPath, existing + text);
|
|
31566
31842
|
} else {
|