@codyswann/lisa 4.33.6 → 4.33.9
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/README.md +22 -0
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +44 -1
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +361 -10
- package/dist/cli/apply.d.ts.map +1 -1
- package/dist/cli/apply.js +8 -1
- package/dist/cli/apply.js.map +1 -1
- package/dist/configs/vitest/base.d.ts +76 -11
- package/dist/configs/vitest/base.d.ts.map +1 -1
- package/dist/configs/vitest/base.js +121 -14
- package/dist/configs/vitest/base.js.map +1 -1
- package/dist/core/apply-receipt.d.ts +18 -0
- package/dist/core/apply-receipt.d.ts.map +1 -1
- package/dist/core/apply-receipt.js +7 -5
- package/dist/core/apply-receipt.js.map +1 -1
- package/dist/core/config.d.ts +34 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +12 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa.d.ts +75 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +125 -6
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +31 -13
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/core/workflow-deletion-ownership.d.ts +69 -0
- package/dist/core/workflow-deletion-ownership.d.ts.map +1 -0
- package/dist/core/workflow-deletion-ownership.js +156 -0
- package/dist/core/workflow-deletion-ownership.js.map +1 -0
- package/dist/opencode/plugin-templates/parity-safety-net.sh +44 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +17 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-intake-explain/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +32 -20
- package/plugins/lisa/.codex-plugin/skills/lisa-ticket-triage/SKILL.md +1 -1
- package/plugins/lisa/hooks/parity-safety-net.sh +44 -1
- package/plugins/lisa/rules/eager/blocker-containment.md +44 -0
- package/plugins/lisa/rules/reference/blocker-containment.md +92 -0
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +17 -2
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-intake-explain/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +32 -20
- package/plugins/lisa/skills/lisa-ticket-triage/SKILL.md +1 -1
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +44 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +17 -2
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-intake-explain/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +32 -20
- package/plugins/lisa-agy/skills/lisa-ticket-triage/SKILL.md +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +44 -1
- package/plugins/lisa-copilot/rules/eager/blocker-containment.md +44 -0
- package/plugins/lisa-copilot/rules/reference/blocker-containment.md +92 -0
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +17 -2
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-intake-explain/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +32 -20
- package/plugins/lisa-copilot/skills/lisa-ticket-triage/SKILL.md +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +44 -1
- package/plugins/lisa-cursor/rules/blocker-containment-reference.mdc +97 -0
- package/plugins/lisa-cursor/rules/blocker-containment.mdc +49 -0
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +17 -2
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-intake-explain/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +32 -20
- package/plugins/lisa-cursor/skills/lisa-ticket-triage/SKILL.md +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/parity-safety-net.sh +44 -1
- package/plugins/src/base/rules/eager/blocker-containment.md +44 -0
- package/plugins/src/base/rules/reference/blocker-containment.md +92 -0
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +17 -2
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-intake-explain/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +32 -20
- package/plugins/src/base/skills/lisa-ticket-triage/SKILL.md +1 -1
- package/scripts/two-channel-couplings.json +1 -1
- package/typescript/copy-overwrite/.github/GITHUB_ACTIONS.md +2 -2
- package/typescript/copy-overwrite/scripts/lisa-mutation.mjs +96 -12
- package/typescript/copy-overwrite/scripts/reconcile-nightly-e2e-tracking.mjs +3 -2
- package/typescript/deletions.json +8 -1
package/README.md
CHANGED
|
@@ -264,6 +264,28 @@ Lisa can watch a queue of ready work and dispatch each item through the lifecycl
|
|
|
264
264
|
> **Prompt for your coding agent**
|
|
265
265
|
> "Which commands let this Lisa scan a work queue, dispatch ready items, repair stuck ones, and report on scheduled-automation health? Show me how I'd point one at my queue and what it expects in configuration."
|
|
266
266
|
|
|
267
|
+
### Running several agents on one machine
|
|
268
|
+
|
|
269
|
+
Test runners size themselves to the machine, not to what else is running on it. Left alone, each run claims roughly one worker per core, so *k* agents working at once claim *k* × cores. That is not merely slow: past a certain point the machine starts terminating processes, and a gate that was killed looks exactly like a gate that failed — so an agent "fixes" a phantom, retries, and adds the load that kills the next run.
|
|
270
|
+
|
|
271
|
+
Lisa caps the pool for you, in three layers:
|
|
272
|
+
|
|
273
|
+
| layer | what it does | when it applies |
|
|
274
|
+
|---|---|---|
|
|
275
|
+
| **Floor** | Half the machine's cores | Always, when this run is the only one |
|
|
276
|
+
| **Divisor** | Floor ÷ concurrent runs, never below 2 workers | Whenever other Lisa runs are live |
|
|
277
|
+
| **Override** | Exactly the number you give it | Whenever you set it |
|
|
278
|
+
|
|
279
|
+
You do not have to configure any of this. A run discovers how many sibling runs are live by looking at the shared scratch namespace, so the divisor applies to a fleet nobody told it about. Two variables are available when you want to steer it:
|
|
280
|
+
|
|
281
|
+
- **`LISA_FLEET_CONCURRENCY`** — state how many runs are coming, rather than letting the run count what has already started. Useful when you are about to launch six agents and want the first one sized for six.
|
|
282
|
+
- **`LISA_VITEST_MAX_WORKERS`** — set the pool size outright. Wins over both other layers, in both directions: raise it above the floor as readily as you lower it.
|
|
283
|
+
|
|
284
|
+
A smaller pool is not automatically safer, which is why the floor is a proportion rather than a small constant and why the divisor stops at two workers. Below that a suite serialises, every file waits behind every other file, and per-test time budgets start expiring even as machine load falls — trading a visible failure for a subtler one.
|
|
285
|
+
|
|
286
|
+
> **Prompt for your coding agent**
|
|
287
|
+
> "Show me how this project's test worker pool is sized — find the resolver, tell me what each of the three layers would give on this machine right now, and how many sibling runs it currently detects."
|
|
288
|
+
|
|
267
289
|
## Working across trackers and sources
|
|
268
290
|
|
|
269
291
|
Lisa is deliberately vendor-neutral. The lifecycle runs the same whether your tickets live in one tracker or another and whether your product specs originate in one document tool or another — a thin dispatch layer selects the right integration from configuration, so the workflow you learn transfers.
|
|
@@ -1690,7 +1690,50 @@ fi
|
|
|
1690
1690
|
|
|
1691
1691
|
# 13. Dropping or truncating a database / schema / table (Lisa-only guard —
|
|
1692
1692
|
# upstream has no SQL protection; keep).
|
|
1693
|
-
|
|
1693
|
+
#
|
|
1694
|
+
# The two arms used to be asymmetric, and only the lopsided one produced false
|
|
1695
|
+
# positives (issue #3530). The `drop` arm requires a following keyword —
|
|
1696
|
+
# `drop database|schema|table` — so `drop the ball` never matched it. The
|
|
1697
|
+
# `truncate` arm made that keyword OPTIONAL:
|
|
1698
|
+
#
|
|
1699
|
+
# truncate[[:space:]]+(table[[:space:]]+)?[[:alnum:]_."`]+
|
|
1700
|
+
#
|
|
1701
|
+
# which reduces to "`truncate`, whitespace, any identifier-ish word", so
|
|
1702
|
+
# `truncate the board`, `truncate results` and `truncate output` all matched.
|
|
1703
|
+
# A session was refused for a bug-report TITLE describing a connection that
|
|
1704
|
+
# truncates results — and a title has no escape hatch, because the remedy this
|
|
1705
|
+
# hook prints at the wall (write the text to a file, pass it BY PATH) covers a
|
|
1706
|
+
# body, while the title flag of an issue-filing CLI is necessarily inline. The
|
|
1707
|
+
# only exit left was to reword, which is what trains people to route around a
|
|
1708
|
+
# guard.
|
|
1709
|
+
#
|
|
1710
|
+
# The fix keeps the coverage and drops the English, in three arms.
|
|
1711
|
+
#
|
|
1712
|
+
# ARM 1 — `drop`, byte-identical to before. It was already correct, and a
|
|
1713
|
+
# rewrite that unified the arms could only make it permissive.
|
|
1714
|
+
readonly SQL_DROP='\bdrop[[:space:]]+(database|schema|table)\b'
|
|
1715
|
+
# ARM 2 — `truncate` carrying its own evidence that it is a statement rather
|
|
1716
|
+
# than a verb: the TABLE keyword (what the drop arm demands), a
|
|
1717
|
+
# schema-qualified name, a quoted identifier, a trailing `;`, or one of the
|
|
1718
|
+
# tail keywords that only ever follow a TRUNCATE. English has none of these.
|
|
1719
|
+
readonly SQL_TRUNCATE_TAIL='(cascade|restrict|restart[[:space:]]+identity|continue[[:space:]]+identity)([^[:alnum:]_]|$)'
|
|
1720
|
+
readonly SQL_TRUNCATE_EVIDENCE='\btruncate[[:space:]]+(table[[:space:]]+[[:alnum:]_."`]+|(only[[:space:]]+)?([[:alnum:]_]+\.[[:alnum:]_."`]+|["`][[:alnum:]_. ]+["`]|[[:alnum:]_]+[[:space:]]*(;|'"$SQL_TRUNCATE_TAIL"')))'
|
|
1721
|
+
# ARM 3 — the permissive-dialect `TRUNCATE <name>` with none of that evidence.
|
|
1722
|
+
# Deleting this shape is what a lazy fix does: it passes every prose scenario
|
|
1723
|
+
# while silently removing the coverage a regression fixture already asserts
|
|
1724
|
+
# (`mysql -e 'TRUNCATE sessions'`). So it is recognized by CONTEXT instead —
|
|
1725
|
+
# the same command must also invoke a command-line database client. Prose in a
|
|
1726
|
+
# tracker filing or a commit message invokes none, which is exactly the
|
|
1727
|
+
# difference the text scan could not see on its own.
|
|
1728
|
+
readonly SQL_CLIENT='(^|[^[:alnum:]_./-])([[:alnum:]_./-]*/)?(psql|pgcli|mysql|mysqladmin|mysqlsh|mariadb|mycli|sqlite3|sqlcmd|cqlsh|clickhouse-client|cockroach|mongosh|duckdb|usql)([[:space:]]|$)'
|
|
1729
|
+
readonly SQL_TRUNCATE_BARE='\btruncate[[:space:]]+(only[[:space:]]+)?[[:alnum:]_."`]'
|
|
1730
|
+
# Residual, accepted and stated: a bare `TRUNCATE <name>` with no terminator,
|
|
1731
|
+
# no qualification and no recognized client in the same command goes unmatched
|
|
1732
|
+
# — the same trade the `drop` arm has always made for `drop the ball`. No DROP
|
|
1733
|
+
# shape is weakened, and the guard still fails in the safe direction.
|
|
1734
|
+
if matches "$SQL_DROP" \
|
|
1735
|
+
|| matches "$SQL_TRUNCATE_EVIDENCE" \
|
|
1736
|
+
|| { matches "$SQL_CLIENT" && matches "$SQL_TRUNCATE_BARE"; }; then
|
|
1694
1737
|
block "destructive SQL (DROP/TRUNCATE) detected"
|
|
1695
1738
|
fi
|
|
1696
1739
|
|
|
@@ -25,6 +25,14 @@ const RELEASE_SUBJECT =
|
|
|
25
25
|
/^chore\(release\): \d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)? \[skip ci\]$/;
|
|
26
26
|
const ZERO_OID = /^0+$/;
|
|
27
27
|
const MARKER = "[lisa-pr-link]";
|
|
28
|
+
/**
|
|
29
|
+
* The deploy environment whose done role is terminal — the only one that
|
|
30
|
+
* closes a work item. Named once because three separate readers compare
|
|
31
|
+
* against it, and a literal repeated three times is three places to drift.
|
|
32
|
+
*/
|
|
33
|
+
const PRODUCTION = "production";
|
|
34
|
+
/** How a base branch that maps to no deploy environment is described. */
|
|
35
|
+
const NOT_A_DEPLOY_BRANCH = "not a deploy branch";
|
|
28
36
|
/**
|
|
29
37
|
* The command that establishes the ticket-side backlink.
|
|
30
38
|
*
|
|
@@ -513,8 +521,11 @@ function lifecycleContract(config, provider) {
|
|
|
513
521
|
// state is called `Done` — a message that sends someone looking for a state
|
|
514
522
|
// that is not what they configured and not what Linear shows them.
|
|
515
523
|
const terminalName = String(terminal ?? "");
|
|
524
|
+
const byEnvironment = doneRolesByEnvironment(roles.done, terminalName);
|
|
516
525
|
return {
|
|
517
526
|
claimed: requireString(roles.claimed, `${provider} claimed lifecycle role`),
|
|
527
|
+
done: byEnvironment,
|
|
528
|
+
productionEnvironment: productionEnvironmentOf(byEnvironment, terminalName),
|
|
518
529
|
ready: requireString(roles.ready, `${provider} ready lifecycle role`),
|
|
519
530
|
roles: lifecycleRoleSet(roles, done),
|
|
520
531
|
terminal: terminalName.toLowerCase(),
|
|
@@ -522,6 +533,55 @@ function lifecycleContract(config, provider) {
|
|
|
522
533
|
};
|
|
523
534
|
}
|
|
524
535
|
|
|
536
|
+
/**
|
|
537
|
+
* The done roles keyed by deploy environment, in configured order.
|
|
538
|
+
*
|
|
539
|
+
* The single-string form (`done: "Done"`) is a project that names one done
|
|
540
|
+
* role for every environment, so it is read as the production one — that is
|
|
541
|
+
* the only environment whose role closes anything.
|
|
542
|
+
* @param {unknown} done The configured `done` role or role map.
|
|
543
|
+
* @param {string} terminalName The resolved terminal role's spelling.
|
|
544
|
+
* @returns {[string, string][]} `[environment, role]` pairs, order preserved.
|
|
545
|
+
*/
|
|
546
|
+
function doneRolesByEnvironment(done, terminalName) {
|
|
547
|
+
const entries =
|
|
548
|
+
typeof done === "string"
|
|
549
|
+
? [[PRODUCTION, done]]
|
|
550
|
+
: done && typeof done === "object"
|
|
551
|
+
? Object.entries(done)
|
|
552
|
+
: [];
|
|
553
|
+
const mapped = entries
|
|
554
|
+
.map(([environment, role]) => [
|
|
555
|
+
String(environment).trim().toLowerCase(),
|
|
556
|
+
typeof role === "string" ? role.trim() : "",
|
|
557
|
+
])
|
|
558
|
+
.filter(([environment, role]) => environment !== "" && role !== "");
|
|
559
|
+
// A shape this reader could not decompose must never leave the writer with
|
|
560
|
+
// NO environment to apply, which would refuse every completion in a project
|
|
561
|
+
// whose `done` nests. The resolved terminal is always an answer.
|
|
562
|
+
return mapped.length > 0 ? mapped : [[PRODUCTION, terminalName]];
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Which of the configured environments is the production one.
|
|
567
|
+
*
|
|
568
|
+
* Found by matching the already-resolved TERMINAL ROLE, not by position. The
|
|
569
|
+
* terminal role is the single existing answer to "which role closes an item",
|
|
570
|
+
* so deriving the environment from it means the two can never disagree — and
|
|
571
|
+
* it avoids deriving anything a second, independent way from JSON key order,
|
|
572
|
+
* which is not semantically meaningful and which no schema constrains.
|
|
573
|
+
* @param {[string, string][]} byEnvironment `[environment, role]` pairs.
|
|
574
|
+
* @param {string} terminalName The resolved terminal role's spelling.
|
|
575
|
+
* @returns {string} The production environment's name.
|
|
576
|
+
*/
|
|
577
|
+
function productionEnvironmentOf(byEnvironment, terminalName) {
|
|
578
|
+
const folded = terminalName.trim().toLowerCase();
|
|
579
|
+
const matched = byEnvironment.find(
|
|
580
|
+
([, role]) => role.toLowerCase() === folded
|
|
581
|
+
);
|
|
582
|
+
return matched?.[0] ?? PRODUCTION;
|
|
583
|
+
}
|
|
584
|
+
|
|
525
585
|
/**
|
|
526
586
|
* Every lifecycle role a project has configured, in the project's own spelling.
|
|
527
587
|
*
|
|
@@ -670,6 +730,46 @@ function verifyLevel(config) {
|
|
|
670
730
|
return value;
|
|
671
731
|
}
|
|
672
732
|
|
|
733
|
+
/**
|
|
734
|
+
* Deploy branches reversed: branch name -> the environment it deploys.
|
|
735
|
+
*
|
|
736
|
+
* `deploy.branches` is written env-first (`production: main`) because that is
|
|
737
|
+
* how a human thinks about it. Every reader here starts from a branch — a
|
|
738
|
+
* merged pull request's base — and needs the environment, so the map is
|
|
739
|
+
* inverted once, here, rather than searched at each use.
|
|
740
|
+
*
|
|
741
|
+
* **The fallback is deliberate and narrow.** A project that configures no
|
|
742
|
+
* deploy branches at all is not saying "nothing ever deploys"; it is saying
|
|
743
|
+
* nothing unusual happens, and its default branch is its production branch.
|
|
744
|
+
* Treating the absent map as "no branch deploys anything" would refuse every
|
|
745
|
+
* completion in every project that never wrote the key — a fix that stops
|
|
746
|
+
* completing anything is not a fix. What the fallback does NOT do is invent an
|
|
747
|
+
* environment for a branch that is simply not in a map the project DID write:
|
|
748
|
+
* that is the stacked-integration case, and it is exactly the one that must
|
|
749
|
+
* not be read as production.
|
|
750
|
+
* @param {object} config The resolved Lisa configuration.
|
|
751
|
+
* @returns {Map<string, string>} Branch name to deploy environment.
|
|
752
|
+
*/
|
|
753
|
+
export function deployBranchEnvironments(config) {
|
|
754
|
+
const configured = config?.deploy?.branches;
|
|
755
|
+
const entries =
|
|
756
|
+
configured && typeof configured === "object"
|
|
757
|
+
? Object.entries(configured)
|
|
758
|
+
: [];
|
|
759
|
+
const mapped = new Map();
|
|
760
|
+
for (const [environment, branch] of entries) {
|
|
761
|
+
const name = typeof branch === "string" ? branch.trim() : "";
|
|
762
|
+
if (name !== "") mapped.set(name, String(environment).trim().toLowerCase());
|
|
763
|
+
}
|
|
764
|
+
if (mapped.size > 0) return mapped;
|
|
765
|
+
const fallback = config?.policy?.repository?.default_branch;
|
|
766
|
+
const branch =
|
|
767
|
+
typeof fallback === "string" && fallback.trim() !== ""
|
|
768
|
+
? fallback.trim()
|
|
769
|
+
: "main";
|
|
770
|
+
return new Map([[branch, PRODUCTION]]);
|
|
771
|
+
}
|
|
772
|
+
|
|
673
773
|
function trackerContract(config = readConfig()) {
|
|
674
774
|
const provider = requireString(config.tracker, "tracker").toLowerCase();
|
|
675
775
|
const identityRepo = currentRepoIdentity(config);
|
|
@@ -686,6 +786,7 @@ function trackerContract(config = readConfig()) {
|
|
|
686
786
|
provider,
|
|
687
787
|
repository,
|
|
688
788
|
identityRepo,
|
|
789
|
+
deployBranches: deployBranchEnvironments(config),
|
|
689
790
|
verify: verifyLevel(config),
|
|
690
791
|
lifecycle: lifecycleContract(config, provider),
|
|
691
792
|
repositoryIsIdentity:
|
|
@@ -3127,9 +3228,193 @@ function githubTimeline(ref) {
|
|
|
3127
3228
|
}
|
|
3128
3229
|
|
|
3129
3230
|
/**
|
|
3130
|
-
*
|
|
3231
|
+
* The branch a merged pull request was merged INTO.
|
|
3131
3232
|
*
|
|
3132
|
-
*
|
|
3233
|
+
* A second call per pull request, because the timeline cannot answer it: a
|
|
3234
|
+
* `cross-referenced` event carries the referencing item in ISSUE shape, and an
|
|
3235
|
+
* issue has no base branch. Reading the base is the whole point — without it
|
|
3236
|
+
* "a merged pull request references this item" is the only evidence there is,
|
|
3237
|
+
* and that sentence is true of a merge into an integration branch that shipped
|
|
3238
|
+
* nothing.
|
|
3239
|
+
* @param {string} repository `owner/name` the pull request belongs to.
|
|
3240
|
+
* @param {number} number The pull-request number.
|
|
3241
|
+
* @returns {string} The base branch name, empty when it could not be read.
|
|
3242
|
+
*/
|
|
3243
|
+
function pullRequestBaseBranch(repository, number) {
|
|
3244
|
+
const result = run(
|
|
3245
|
+
"gh",
|
|
3246
|
+
["api", `repos/${repository}/pulls/${number}`, "--jq", ".base.ref"],
|
|
3247
|
+
{ allowFailure: true }
|
|
3248
|
+
);
|
|
3249
|
+
if (result.status !== 0)
|
|
3250
|
+
throw githubFailure(result, `${repository}#${number}`);
|
|
3251
|
+
return result.stdout.trim();
|
|
3252
|
+
}
|
|
3253
|
+
|
|
3254
|
+
/**
|
|
3255
|
+
* Decide which lifecycle role a set of merged pull requests has earned.
|
|
3256
|
+
*
|
|
3257
|
+
* The defect this exists to end: completion read "is there a merged pull
|
|
3258
|
+
* request referencing this item" and never asked which branch it merged into,
|
|
3259
|
+
* so a stacked pull request landing on an integration branch stamped the
|
|
3260
|
+
* PRODUCTION terminal role and closed the item. Nothing had reached the deploy
|
|
3261
|
+
* branch and nothing had deployed, but every recovery flow — sweep, repair
|
|
3262
|
+
* intake, the rollup reconcilers — reads a closed item carrying the terminal
|
|
3263
|
+
* role as finished, so the corruption is in the direction that stops recovery
|
|
3264
|
+
* from firing.
|
|
3265
|
+
*
|
|
3266
|
+
* **Production is recognised, never ranked.** An earlier draft of this
|
|
3267
|
+
* function ordered environments by their POSITION in the configured `done`
|
|
3268
|
+
* map, which makes correctness depend on JSON key order — not semantically
|
|
3269
|
+
* meaningful, constrained by no schema, and able to fail in the direction of
|
|
3270
|
+
* writing the WRONG TERMINAL ROLE rather than merely refusing, which is the
|
|
3271
|
+
* original defect with extra steps. So the only distinction drawn here is
|
|
3272
|
+
* production versus not: a merge into the production environment is terminal,
|
|
3273
|
+
* a single non-production environment records its own role, and several
|
|
3274
|
+
* different non-production environments are reported rather than ranked. That
|
|
3275
|
+
* is enough, because the role this ticket is about is the terminal one.
|
|
3276
|
+
*
|
|
3277
|
+
* Pure and exported so the decision can be asserted without a network.
|
|
3278
|
+
* @param {{base: string, number: number}[]} pullRequests Merged pull requests.
|
|
3279
|
+
* @param {Map<string, string>} branchEnvironments Branch to deploy environment.
|
|
3280
|
+
* @param {{done: [string, string][], productionEnvironment: string}} lifecycle
|
|
3281
|
+
* The resolved lifecycle contract.
|
|
3282
|
+
* @returns {{ambiguous: boolean, environment: string|null, evidence: {base: string, environment: string|null, number: number}[], role: string|null, terminal: boolean}}
|
|
3283
|
+
* The role earned, or a null role when nothing was earned or nothing ranks.
|
|
3284
|
+
*/
|
|
3285
|
+
export function mergedBaseDecision(
|
|
3286
|
+
pullRequests,
|
|
3287
|
+
branchEnvironments,
|
|
3288
|
+
lifecycle
|
|
3289
|
+
) {
|
|
3290
|
+
const roles = new Map(lifecycle?.done ?? []);
|
|
3291
|
+
const production = lifecycle?.productionEnvironment;
|
|
3292
|
+
const evidence = (pullRequests ?? []).map(request => {
|
|
3293
|
+
const base = String(request?.base ?? "");
|
|
3294
|
+
return {
|
|
3295
|
+
base,
|
|
3296
|
+
environment: branchEnvironments?.get(base) ?? null,
|
|
3297
|
+
number: request?.number,
|
|
3298
|
+
};
|
|
3299
|
+
});
|
|
3300
|
+
const reached = [
|
|
3301
|
+
...new Set(
|
|
3302
|
+
evidence
|
|
3303
|
+
.map(entry => entry.environment)
|
|
3304
|
+
.filter(environment => roles.has(environment))
|
|
3305
|
+
),
|
|
3306
|
+
];
|
|
3307
|
+
if (reached.includes(production)) {
|
|
3308
|
+
return {
|
|
3309
|
+
ambiguous: false,
|
|
3310
|
+
environment: production,
|
|
3311
|
+
evidence,
|
|
3312
|
+
role: roles.get(production),
|
|
3313
|
+
terminal: true,
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
3316
|
+
// Exactly one non-production environment is unambiguous. Two different ones
|
|
3317
|
+
// would need an ordering the configuration does not state, so they are
|
|
3318
|
+
// reported instead of guessed at.
|
|
3319
|
+
if (reached.length !== 1) {
|
|
3320
|
+
return {
|
|
3321
|
+
ambiguous: reached.length > 1,
|
|
3322
|
+
environment: null,
|
|
3323
|
+
evidence,
|
|
3324
|
+
role: null,
|
|
3325
|
+
terminal: false,
|
|
3326
|
+
};
|
|
3327
|
+
}
|
|
3328
|
+
return {
|
|
3329
|
+
ambiguous: false,
|
|
3330
|
+
environment: reached[0],
|
|
3331
|
+
evidence,
|
|
3332
|
+
role: roles.get(reached[0]),
|
|
3333
|
+
terminal: false,
|
|
3334
|
+
};
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3337
|
+
/**
|
|
3338
|
+
* Name every merged pull request and the branch it landed on.
|
|
3339
|
+
*
|
|
3340
|
+
* An operator reading a run that completed nothing has to be able to tell WHY
|
|
3341
|
+
* without opening the code, and "which branch did it actually merge into" is
|
|
3342
|
+
* the whole answer.
|
|
3343
|
+
* @param {{base: string, environment: string|null, number: number}[]} evidence
|
|
3344
|
+
* What each merged pull request was observed to target.
|
|
3345
|
+
* @returns {string} A readable one-line summary.
|
|
3346
|
+
*/
|
|
3347
|
+
function describeMergeBases(evidence) {
|
|
3348
|
+
return evidence
|
|
3349
|
+
.map(
|
|
3350
|
+
entry =>
|
|
3351
|
+
`#${entry.number} -> ${entry.base || "(unknown base)"} [${entry.environment ?? NOT_A_DEPLOY_BRANCH}]`
|
|
3352
|
+
)
|
|
3353
|
+
.join(", ");
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3356
|
+
/**
|
|
3357
|
+
* Name the branches this project does deploy, and which one it took to be
|
|
3358
|
+
* production.
|
|
3359
|
+
*
|
|
3360
|
+
* Naming the production branch explicitly is what makes a wrong ASSUMPTION
|
|
3361
|
+
* visible. A project that never wrote `deploy.branches` has its default branch
|
|
3362
|
+
* read as production; if that is not its real production branch, every
|
|
3363
|
+
* completion refuses and the operator has to be able to see the assumption in
|
|
3364
|
+
* the refusal rather than infer it from a list.
|
|
3365
|
+
* @param {Map<string, string>} branchEnvironments Branch to deploy environment.
|
|
3366
|
+
* @param {string} production The production environment's name.
|
|
3367
|
+
* @returns {string} A readable list, with the production branch called out.
|
|
3368
|
+
*/
|
|
3369
|
+
function describeDeployBranches(branchEnvironments, production) {
|
|
3370
|
+
const listed =
|
|
3371
|
+
[...branchEnvironments]
|
|
3372
|
+
.map(([branch, environment]) => `${branch} [${environment}]`)
|
|
3373
|
+
.join(", ") || "(none configured)";
|
|
3374
|
+
const [productionBranch] =
|
|
3375
|
+
[...branchEnvironments].find(
|
|
3376
|
+
([, environment]) => environment === production
|
|
3377
|
+
) ?? [];
|
|
3378
|
+
return productionBranch === undefined
|
|
3379
|
+
? `${listed}; no branch maps to "${production}"`
|
|
3380
|
+
: `${listed}; production is taken to be "${productionBranch}"`;
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3383
|
+
/**
|
|
3384
|
+
* Record a deploy role that is NOT the production terminal.
|
|
3385
|
+
*
|
|
3386
|
+
* Adds the environment's role and stops. It deliberately does not close the
|
|
3387
|
+
* item and does not retire the claimed role: the work is genuinely still in
|
|
3388
|
+
* flight until it reaches the production branch, and native closure fires only
|
|
3389
|
+
* at the production terminal.
|
|
3390
|
+
* @param {string} ref Canonical work-item reference.
|
|
3391
|
+
* @param {{labels: string[]}} before The pre-write tracker state.
|
|
3392
|
+
* @param {string} role The environment's configured done role.
|
|
3393
|
+
* @returns {void}
|
|
3394
|
+
*/
|
|
3395
|
+
function recordDeployRole(ref, before, role) {
|
|
3396
|
+
if (carriesLabel(before.labels, role)) return;
|
|
3397
|
+
const [repository, number] = ref.split("#");
|
|
3398
|
+
const edited = run(
|
|
3399
|
+
"gh",
|
|
3400
|
+
[
|
|
3401
|
+
"issue",
|
|
3402
|
+
"edit",
|
|
3403
|
+
String(number),
|
|
3404
|
+
"--repo",
|
|
3405
|
+
repository,
|
|
3406
|
+
"--add-label",
|
|
3407
|
+
role,
|
|
3408
|
+
],
|
|
3409
|
+
{ allowFailure: true }
|
|
3410
|
+
);
|
|
3411
|
+
if (edited.status !== 0) throw githubFailure(edited, ref);
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
/**
|
|
3415
|
+
* Move a work item to the lifecycle role its merges have actually earned.
|
|
3416
|
+
*
|
|
3417
|
+
* The role is RESOLVED from configuration, never assumed. Lisa's own
|
|
3133
3418
|
* repository maps `production` to `status:done`, but the map is environment
|
|
3134
3419
|
* aware — a project whose target is `dev` has a different terminal role, and a
|
|
3135
3420
|
* hardcoded label would silently apply the wrong one there while looking
|
|
@@ -3139,9 +3424,18 @@ function githubTimeline(ref) {
|
|
|
3139
3424
|
* is pointed at is a way to make unfinished work disappear, which is the same
|
|
3140
3425
|
* defect class as a gate that passes because it found nothing. Evidence is a
|
|
3141
3426
|
* merged pull request in this repository.
|
|
3427
|
+
*
|
|
3428
|
+
* **And a merged pull request is not evidence on its own.** The base branch it
|
|
3429
|
+
* merged into decides which role it earned: only a merge into the production
|
|
3430
|
+
* deploy branch is terminal. A merge into an integration branch records the
|
|
3431
|
+
* environment's role at most, and a merge into a branch this project does not
|
|
3432
|
+
* deploy at all records nothing and closes nothing — reported, never silent,
|
|
3433
|
+
* because a completion that quietly did not happen is the same failure as one
|
|
3434
|
+
* that wrongly did.
|
|
3142
3435
|
* @param {string} ref Canonical work-item reference.
|
|
3143
3436
|
* @param {object} contract The resolved tracker contract.
|
|
3144
|
-
* @returns {{merged: number[], terminal: string}}
|
|
3437
|
+
* @returns {{applied: boolean, merged: number[], report: string, terminal: string|null}}
|
|
3438
|
+
* What was applied, and why.
|
|
3145
3439
|
*/
|
|
3146
3440
|
function completeGithubWorkItem(ref, contract) {
|
|
3147
3441
|
const [repository] = ref.split("#");
|
|
@@ -3154,11 +3448,51 @@ function completeGithubWorkItem(ref, contract) {
|
|
|
3154
3448
|
`from a real one afterwards. If the work shipped some other way, say so on the item and close it deliberately.`
|
|
3155
3449
|
);
|
|
3156
3450
|
}
|
|
3451
|
+
const decision = mergedBaseDecision(
|
|
3452
|
+
merged.map(number => ({
|
|
3453
|
+
base: pullRequestBaseBranch(repository, number),
|
|
3454
|
+
number,
|
|
3455
|
+
})),
|
|
3456
|
+
contract.deployBranches,
|
|
3457
|
+
contract.lifecycle
|
|
3458
|
+
);
|
|
3459
|
+
const evidence = merged.map(number => `#${number}`).join(", ");
|
|
3460
|
+
const bases = describeMergeBases(decision.evidence);
|
|
3461
|
+
if (decision.role === null) {
|
|
3462
|
+
const why = decision.ambiguous
|
|
3463
|
+
? `Several different non-production deploy environments were reached, and the configuration states\n` +
|
|
3464
|
+
`no ordering between them, so this writer reports them rather than guessing which is furthest.`
|
|
3465
|
+
: `No merged pull request reached a branch this project deploys, so no lifecycle role was\n` +
|
|
3466
|
+
`applied and ${ref} stays open. It completes when the change reaches a deploy branch.`;
|
|
3467
|
+
return {
|
|
3468
|
+
applied: false,
|
|
3469
|
+
bases,
|
|
3470
|
+
merged,
|
|
3471
|
+
report:
|
|
3472
|
+
`work-item NOT completed: ${ref} (merged: ${evidence}) bases: ${bases}\n` +
|
|
3473
|
+
`${why}\n` +
|
|
3474
|
+
`Deploy branches: ${describeDeployBranches(contract.deployBranches, contract.lifecycle.productionEnvironment)}.\n` +
|
|
3475
|
+
`If that production branch is wrong, "deploy.branches" in .lisa.config.json is what to fix.`,
|
|
3476
|
+
terminal: null,
|
|
3477
|
+
};
|
|
3478
|
+
}
|
|
3157
3479
|
const before = githubLifecycleState(
|
|
3158
3480
|
ref,
|
|
3159
3481
|
`GitHub issue ${ref} completion read`
|
|
3160
3482
|
);
|
|
3161
3483
|
assertNotAbandoned(ref, before);
|
|
3484
|
+
if (!decision.terminal) {
|
|
3485
|
+
recordDeployRole(ref, before, decision.role);
|
|
3486
|
+
return {
|
|
3487
|
+
applied: true,
|
|
3488
|
+
bases,
|
|
3489
|
+
merged,
|
|
3490
|
+
report:
|
|
3491
|
+
`work-item advanced: ${ref} -> ${decision.role} (merged: ${evidence}) bases: ${bases}\n` +
|
|
3492
|
+
`${decision.environment} is not the production environment, so ${ref} stays open.`,
|
|
3493
|
+
terminal: decision.role,
|
|
3494
|
+
};
|
|
3495
|
+
}
|
|
3162
3496
|
reconcileGithubLifecycle(ref, before, contract);
|
|
3163
3497
|
// A SECOND read, deliberately. The edit and the close each reported their own
|
|
3164
3498
|
// success, and a writer that trusts those is asserting about tracker state it
|
|
@@ -3168,7 +3502,13 @@ function completeGithubWorkItem(ref, contract) {
|
|
|
3168
3502
|
`GitHub issue ${ref} completion readback`
|
|
3169
3503
|
);
|
|
3170
3504
|
assertCompletionReadback(ref, after, contract);
|
|
3171
|
-
return {
|
|
3505
|
+
return {
|
|
3506
|
+
applied: true,
|
|
3507
|
+
bases,
|
|
3508
|
+
merged,
|
|
3509
|
+
report: `work-item completed: ${ref} -> ${contract.lifecycle.terminalName} (merged: ${evidence}) bases: ${bases}`,
|
|
3510
|
+
terminal: contract.lifecycle.terminalName,
|
|
3511
|
+
};
|
|
3172
3512
|
}
|
|
3173
3513
|
|
|
3174
3514
|
/**
|
|
@@ -3582,11 +3922,15 @@ function complete(args) {
|
|
|
3582
3922
|
}
|
|
3583
3923
|
const ref = canonicalizeRef(supplied ?? bound, contract);
|
|
3584
3924
|
const prUrl = pullRequestUrlOption(args);
|
|
3585
|
-
const
|
|
3925
|
+
const outcome = completeWorkItem(ref, contract, prUrl);
|
|
3926
|
+
// The writer composes its own sentence when the base branch shaped the
|
|
3927
|
+
// outcome, because only the writer knows which bases it read. The Linear
|
|
3928
|
+
// path has no such decision to report, so it keeps the original line.
|
|
3586
3929
|
console.log(
|
|
3587
|
-
|
|
3588
|
-
.
|
|
3589
|
-
|
|
3930
|
+
outcome.report ??
|
|
3931
|
+
`work-item completed: ${ref} -> ${outcome.terminal} (merged: ${outcome.merged
|
|
3932
|
+
.map(number => `#${number}`)
|
|
3933
|
+
.join(", ")})`
|
|
3590
3934
|
);
|
|
3591
3935
|
}
|
|
3592
3936
|
|
|
@@ -3645,8 +3989,15 @@ function sweep(args) {
|
|
|
3645
3989
|
console.log(`DRIFT ${ref} merged: ${evidence} ${issue.title}`);
|
|
3646
3990
|
continue;
|
|
3647
3991
|
}
|
|
3648
|
-
const
|
|
3649
|
-
|
|
3992
|
+
const outcome = completeWorkItem(ref, contract);
|
|
3993
|
+
// A sweep must not abort on the first item whose merges have not reached a
|
|
3994
|
+
// deploy branch. It reports that item and carries on, which is what makes
|
|
3995
|
+
// the backstop safe to run over a whole queue.
|
|
3996
|
+
console.log(
|
|
3997
|
+
outcome.applied
|
|
3998
|
+
? `completed ${ref} -> ${outcome.terminal} (merged: ${evidence}) bases: ${outcome.bases}`
|
|
3999
|
+
: outcome.report
|
|
4000
|
+
);
|
|
3650
4001
|
}
|
|
3651
4002
|
if (drifted === 0) {
|
|
3652
4003
|
console.log(
|
package/dist/cli/apply.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AAgB/B,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AAgB/B,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,qBAAqB,CAAC;AAmP7B;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,eAAe,GACrB,MAAM,GAAG,SAAS,CAepB;AAmCD;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CAyEf"}
|
package/dist/cli/apply.js
CHANGED
|
@@ -129,9 +129,10 @@ function buildApplyConfig(parts) {
|
|
|
129
129
|
* @param parts.harness - Resolved harness for this invocation
|
|
130
130
|
* @param parts.persistence - Inputs deciding whether config must be written
|
|
131
131
|
* @param parts.stalePaths - Managed files this apply left out of date
|
|
132
|
+
* @param parts.deletedWorkflowPaths - Workflow files this apply removed
|
|
132
133
|
*/
|
|
133
134
|
async function finalizeSuccessfulApply(parts) {
|
|
134
|
-
const { destDir, logger, config, harness, persistence, stalePaths } = parts;
|
|
135
|
+
const { destDir, logger, config, harness, persistence, stalePaths, deletedWorkflowPaths, } = parts;
|
|
135
136
|
// Ensure every applied project carries a .lisa.config.json. A missing file is
|
|
136
137
|
// always backfilled with the resolved harness (the default when no --harness
|
|
137
138
|
// was passed) so no project is left config-less; an existing file is only
|
|
@@ -161,6 +162,11 @@ async function finalizeSuccessfulApply(parts) {
|
|
|
161
162
|
// upstream fixes. Doctor reads the receipt, so the finding outlives the
|
|
162
163
|
// install (CodySwannGT/lisa#3033).
|
|
163
164
|
stalePaths,
|
|
165
|
+
// Same argument as stalePaths, one degree worse. A workflow Lisa removed
|
|
166
|
+
// leaves nothing on disk to notice and cannot fail a check afterwards, so
|
|
167
|
+
// the receipt is the only place the removal is still recorded once the
|
|
168
|
+
// install output is gone (CodySwannGT/lisa#3656).
|
|
169
|
+
deletedWorkflowPaths,
|
|
164
170
|
});
|
|
165
171
|
}
|
|
166
172
|
/**
|
|
@@ -284,6 +290,7 @@ export async function runApply(destination, options) {
|
|
|
284
290
|
resolvedHarness: harness,
|
|
285
291
|
},
|
|
286
292
|
stalePaths: result.stalePaths,
|
|
293
|
+
deletedWorkflowPaths: result.deletedWorkflowPaths,
|
|
287
294
|
});
|
|
288
295
|
}
|
|
289
296
|
// After a real apply, surface (read-only) whether any locally-authored
|
package/dist/cli/apply.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"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"}
|