@basou/core 0.31.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +299 -16
- package/dist/index.js +218 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5481,6 +5481,65 @@ function shortId(id) {
|
|
|
5481
5481
|
return id.slice(0, sep + 1) + id.slice(sep + 1, sep + 1 + 10);
|
|
5482
5482
|
}
|
|
5483
5483
|
|
|
5484
|
+
// src/project/anchor-starter.ts
|
|
5485
|
+
function renderAnchorStarter(input) {
|
|
5486
|
+
const lines = [];
|
|
5487
|
+
const title = input.projectName ?? input.anchorName;
|
|
5488
|
+
lines.push(`# AGENTS.md (${input.anchorName})`);
|
|
5489
|
+
lines.push("");
|
|
5490
|
+
lines.push(
|
|
5491
|
+
`> \u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306F **${title} \u306E planning master(anchor)** \u3067\u3059\u3002\u3053\u3053\u3067\u4F5C\u696D\u3059\u308B AI \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306F\u3001\u307E\u305A\u3053\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u3093\u3067\u304F\u3060\u3055\u3044\u3002`
|
|
5492
|
+
);
|
|
5493
|
+
lines.push(">");
|
|
5494
|
+
lines.push(
|
|
5495
|
+
"> \u3053\u306E\u30D5\u30A1\u30A4\u30EB\u306F `basou project derive` \u304C greenfield \u7ACB\u3061\u4E0A\u3052\u6642\u306B **\u4E00\u5EA6\u3060\u3051\u751F\u6210\u3057\u305F starter** \u3067\u3059\u3002\u4EE5\u5F8C\u306F\u624B\u7BA1\u7406\u3057\u3066\u304F\u3060\u3055\u3044 \u2014 basou \u306F\u518D\u751F\u6210\u3082\u4E0A\u66F8\u304D\u3082\u3057\u307E\u305B\u3093(BASOU:GENERATED \u30DE\u30FC\u30AB\u30FC\u306F\u7121\u304F\u3001\u81EA\u7531\u306B\u7DE8\u96C6\u3067\u304D\u307E\u3059)\u3002"
|
|
5496
|
+
);
|
|
5497
|
+
lines.push("");
|
|
5498
|
+
lines.push("## \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u57FA\u672C\u60C5\u5831");
|
|
5499
|
+
lines.push("");
|
|
5500
|
+
lines.push("<!-- TODO: manifest \u304B\u3089\u306F\u5C0E\u51FA\u3067\u304D\u306A\u3044\u9805\u76EE\u3067\u3059\u3002\u57CB\u3081\u3066\u304F\u3060\u3055\u3044\u3002 -->");
|
|
5501
|
+
lines.push("");
|
|
5502
|
+
lines.push("```text");
|
|
5503
|
+
lines.push(`Product name: ${input.projectName ?? "<!-- TODO -->"}`);
|
|
5504
|
+
lines.push("Domain: <!-- TODO -->");
|
|
5505
|
+
lines.push("GitHub Organization: <!-- TODO -->");
|
|
5506
|
+
lines.push("Public repository: <!-- TODO -->");
|
|
5507
|
+
lines.push("Planning repository: <!-- TODO -->");
|
|
5508
|
+
lines.push("License: <!-- TODO -->");
|
|
5509
|
+
lines.push("```");
|
|
5510
|
+
lines.push("");
|
|
5511
|
+
lines.push("## \u3069\u3053\u3067 commit \u3059\u308B\u304B");
|
|
5512
|
+
lines.push("");
|
|
5513
|
+
lines.push("- **\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA(planning master)**: \u69CB\u60F3\u30FB\u8A08\u753B\u30FB\u8A2D\u8A08\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3002");
|
|
5514
|
+
lines.push("- **\u5404\u5B9F\u88C5 repo**: \u5B9F\u88C5\u30B3\u30FC\u30C9\u3002\u5FC5\u305A\u5BFE\u8C61 repo \u306B `cd` \u3057\u3066\u304B\u3089 commit \u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5515
|
+
lines.push("- **workspace view**: git \u7BA1\u7406\u5916\u3002view \u3067\u306F commit \u3067\u304D\u307E\u305B\u3093\u3002");
|
|
5516
|
+
lines.push("");
|
|
5517
|
+
lines.push("## \u5FC5\u305A\u8AAD\u3080\u3079\u304D\u898F\u7D04");
|
|
5518
|
+
lines.push("");
|
|
5519
|
+
lines.push("\u4F5C\u696D\u898F\u7D04\u306F\u5404 repo \u306E AGENTS.md \u306B\u3042\u308A\u307E\u3059\u3002\u4EE5\u4E0B\u3092\u8AAD\u3093\u3067\u304B\u3089\u4F5C\u696D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5520
|
+
lines.push("");
|
|
5521
|
+
for (const r of input.repos) {
|
|
5522
|
+
if (r.anchor === true) continue;
|
|
5523
|
+
lines.push(`- ${r.name}/AGENTS.md`);
|
|
5524
|
+
}
|
|
5525
|
+
if (input.viewName !== void 0) {
|
|
5526
|
+
lines.push(
|
|
5527
|
+
`- ${input.viewName}/AGENTS.md(workspace view\u30FBbasou \u304C\u751F\u6210)\u2014 **\u6700\u65B0\u306E repo \u69CB\u6210(roster)\u306F\u3053\u3053\u3092\u6B63\u3068\u3059\u308B**`
|
|
5528
|
+
);
|
|
5529
|
+
}
|
|
5530
|
+
lines.push("");
|
|
5531
|
+
lines.push("## \u4F5C\u696D\u65B9\u91DD(\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u56FA\u6709\u4E8B\u9805)");
|
|
5532
|
+
lines.push("");
|
|
5533
|
+
lines.push("<!-- TODO: \u4EE5\u4E0B\u3092\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u5408\u308F\u305B\u3066\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5534
|
+
lines.push(" - \u73FE\u5728\u306E\u30D5\u30A7\u30FC\u30BA / \u91CD\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8");
|
|
5535
|
+
lines.push(" - \u6A5F\u5BC6\u60C5\u5831\u306E\u6271\u3044(\u3069\u3053\u306B\u66F8\u304B\u306A\u3044\u304B)");
|
|
5536
|
+
lines.push(" - \u8A00\u8A9E\u30DD\u30EA\u30B7\u30FC(commit / \u30B3\u30E1\u30F3\u30C8 / \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u8A00\u8A9E)");
|
|
5537
|
+
lines.push(" - commit \u904B\u7528(\u6DF7\u5728\u30B3\u30DF\u30C3\u30C8\u3092\u907F\u3051\u308B \u7B49)");
|
|
5538
|
+
lines.push("-->");
|
|
5539
|
+
return `${lines.join("\n")}
|
|
5540
|
+
`;
|
|
5541
|
+
}
|
|
5542
|
+
|
|
5484
5543
|
// src/project/relative-path.ts
|
|
5485
5544
|
function normalizeRelativePath(p) {
|
|
5486
5545
|
const trimmed = p.trim();
|
|
@@ -5657,10 +5716,69 @@ function renderPresetBlock(repo) {
|
|
|
5657
5716
|
}
|
|
5658
5717
|
return lines.join("\n");
|
|
5659
5718
|
}
|
|
5719
|
+
function visibilityShortLabel(v) {
|
|
5720
|
+
return v ?? "\u672A\u8A2D\u5B9A";
|
|
5721
|
+
}
|
|
5722
|
+
function languageShortLabel(l) {
|
|
5723
|
+
return l ?? "\u672A\u8A2D\u5B9A";
|
|
5724
|
+
}
|
|
5725
|
+
function instructionsLabel(repo) {
|
|
5726
|
+
if (repo.anchor === true) return "anchor(\u624B\u7BA1\u7406)";
|
|
5727
|
+
return repo.self === true ? "self(repo \u304C\u81EA\u5DF1\u7BA1\u7406)" : "hub(basou \u304C\u751F\u6210)";
|
|
5728
|
+
}
|
|
5729
|
+
function renderViewPresetBlock(input) {
|
|
5730
|
+
const lines = [];
|
|
5731
|
+
lines.push("## workspace view \u69CB\u6210(basou \u304C\u751F\u6210 \u2014 manifest \u304C\u6B63\u672C)");
|
|
5732
|
+
lines.push("");
|
|
5733
|
+
lines.push(
|
|
5734
|
+
"\u3053\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u306F `.basou/manifest.yaml` \u306E\u5BA3\u8A00\u304B\u3089 `basou project preset` \u304C\u751F\u6210\u3057\u307E\u3059\u3002\u7DE8\u96C6\u306F manifest \u5074\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044(\u30DE\u30FC\u30AB\u30FC\u5916\u306E\u8A18\u8FF0\u306F\u4FDD\u6301\u3055\u308C\u307E\u3059)\u3002"
|
|
5735
|
+
);
|
|
5736
|
+
lines.push(
|
|
5737
|
+
`\u3053\u306E AGENTS.md \u81EA\u8EAB\u3082 basou \u306E\u751F\u6210\u7269\u3067\u3059(\u5B9F\u4F53: \`agents/${input.viewName}/AGENTS.md\`\u3001\u30DE\u30FC\u30AB\u30FC\u5916\u306E\u8A18\u8FF0\u306F\u4FDD\u6301\u3055\u308C\u307E\u3059)\u3002`
|
|
5738
|
+
);
|
|
5739
|
+
lines.push("");
|
|
5740
|
+
lines.push(
|
|
5741
|
+
`\u3053\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u3001\u5BA3\u8A00\u3055\u308C\u305F ${input.repos.length} \u500B\u306E repo \u3092 symlink \u3067\u96C6\u7D04\u3059\u308B **view** \u3067\u3059\u3002\u5B9F\u4F53\u3092\u6301\u305F\u305A\u3001git \u7BA1\u7406\u5916\u3067\u3059\u3002`
|
|
5742
|
+
);
|
|
5743
|
+
lines.push("");
|
|
5744
|
+
lines.push("### \u96C6\u7D04\u3057\u3066\u3044\u308B repo");
|
|
5745
|
+
lines.push("");
|
|
5746
|
+
lines.push("| repo | \u53EF\u8996\u6027 | \u8A00\u8A9E | \u6307\u793A\u66F8 |");
|
|
5747
|
+
lines.push("|---|---|---|---|");
|
|
5748
|
+
for (const r of input.repos) {
|
|
5749
|
+
lines.push(
|
|
5750
|
+
`| ${r.name} | ${visibilityShortLabel(r.visibility)} | ${languageShortLabel(r.language)} | ${instructionsLabel(r)} |`
|
|
5751
|
+
);
|
|
5752
|
+
}
|
|
5753
|
+
lines.push("");
|
|
5754
|
+
lines.push("### \u3069\u3053\u3067 commit \u3059\u308B\u304B");
|
|
5755
|
+
lines.push("");
|
|
5756
|
+
lines.push(
|
|
5757
|
+
"view \u3067\u306F commit \u3067\u304D\u307E\u305B\u3093(git \u7BA1\u7406\u5916)\u3002\u5909\u66F4\u306F\u5FC5\u305A\u5B9F\u4F53\u306E repo \u306B `cd` \u3057\u3066\u304B\u3089 commit \u3057\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
5758
|
+
);
|
|
5759
|
+
lines.push("");
|
|
5760
|
+
for (const r of input.repos) {
|
|
5761
|
+
lines.push(`- ${r.name} \u2192 \`cd ${r.name}\``);
|
|
5762
|
+
}
|
|
5763
|
+
lines.push("");
|
|
5764
|
+
lines.push("### \u5FC5\u305A\u8AAD\u3080\u3079\u304D\u898F\u7D04");
|
|
5765
|
+
lines.push("");
|
|
5766
|
+
lines.push("\u4F5C\u696D\u898F\u7D04\u306F\u5404 repo \u306E AGENTS.md \u306B\u3042\u308A\u307E\u3059\u3002\u4EE5\u4E0B\u3092\u8AAD\u3093\u3067\u304B\u3089\u4F5C\u696D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
5767
|
+
lines.push("");
|
|
5768
|
+
for (const r of input.repos) {
|
|
5769
|
+
lines.push(`- ${r.name}/AGENTS.md`);
|
|
5770
|
+
}
|
|
5771
|
+
lines.push("");
|
|
5772
|
+
lines.push("### \u91CD\u8981\u539F\u5247");
|
|
5773
|
+
lines.push("");
|
|
5774
|
+
lines.push("- \u3053\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u72B6\u614B\u3092\u6301\u305F\u306A\u3044(git \u7BA1\u7406\u5916)");
|
|
5775
|
+
lines.push("- \u91CD\u8981\u306A\u30D5\u30A1\u30A4\u30EB\u3092\u3053\u3053\u306B\u76F4\u63A5\u7F6E\u304B\u306A\u3044(\u5B9F\u4F53\u306F\u5404 repo \u306B\u7F6E\u304F)");
|
|
5776
|
+
return lines.join("\n");
|
|
5777
|
+
}
|
|
5660
5778
|
function normalizeBlock(s) {
|
|
5661
5779
|
return s.replace(/\r\n/g, "\n").replace(/\n+$/, "");
|
|
5662
5780
|
}
|
|
5663
|
-
function summarizePresetPlan(facts) {
|
|
5781
|
+
function summarizePresetPlan(facts, opts) {
|
|
5664
5782
|
const deduped = [];
|
|
5665
5783
|
const seenPath = /* @__PURE__ */ new Set();
|
|
5666
5784
|
for (const f of facts) {
|
|
@@ -5680,8 +5798,9 @@ function summarizePresetPlan(facts) {
|
|
|
5680
5798
|
const collisions = [];
|
|
5681
5799
|
const collidingPaths = /* @__PURE__ */ new Set();
|
|
5682
5800
|
for (const [canonicalName, repos] of byCanonical) {
|
|
5683
|
-
|
|
5684
|
-
|
|
5801
|
+
const viewCollision = opts?.viewCanonicalName !== void 0 && canonicalName === opts.viewCanonicalName;
|
|
5802
|
+
if (repos.length > 1 || viewCollision) {
|
|
5803
|
+
collisions.push({ canonicalName, repos, ...viewCollision ? { view: true } : {} });
|
|
5685
5804
|
for (const r of repos) collidingPaths.add(r);
|
|
5686
5805
|
}
|
|
5687
5806
|
}
|
|
@@ -5846,6 +5965,8 @@ function classifyRetrofit(facts) {
|
|
|
5846
5965
|
if (facts.agentsState === "symlink")
|
|
5847
5966
|
return { ...base, action: "skip", reason: "already-symlink" };
|
|
5848
5967
|
if (facts.agentsState === "absent") return { ...base, action: "skip", reason: "absent" };
|
|
5968
|
+
if (facts.viewCanonicalName !== void 0 && facts.canonicalName === facts.viewCanonicalName)
|
|
5969
|
+
return { ...base, action: "refuse", reason: "view-collision" };
|
|
5849
5970
|
if (facts.canonicalExists) return { ...base, action: "refuse", reason: "canonical-exists" };
|
|
5850
5971
|
return {
|
|
5851
5972
|
...base,
|
|
@@ -5942,7 +6063,7 @@ function summarizeSymlinkPlan(facts) {
|
|
|
5942
6063
|
const selfAgentsMissing = [];
|
|
5943
6064
|
const unreachable = [];
|
|
5944
6065
|
for (const f of deduped) {
|
|
5945
|
-
if (f.isAnchor) continue;
|
|
6066
|
+
if (f.isAnchor && !f.canonicalPresent) continue;
|
|
5946
6067
|
if (!f.reachable) {
|
|
5947
6068
|
unreachable.push(f.path);
|
|
5948
6069
|
continue;
|
|
@@ -6021,6 +6142,68 @@ function summarizeWiring(facts) {
|
|
|
6021
6142
|
};
|
|
6022
6143
|
}
|
|
6023
6144
|
|
|
6145
|
+
// src/project/wiring-drift.ts
|
|
6146
|
+
function summarizeWiringDrift(input) {
|
|
6147
|
+
const plan = summarizeSymlinkPlan(input.repos);
|
|
6148
|
+
const missingCanonicals = [
|
|
6149
|
+
...plan.missingCanonical.map((path2) => ({ target: "repo-hub", name: path2 })),
|
|
6150
|
+
...plan.selfAgentsMissing.map(
|
|
6151
|
+
(path2) => ({ target: "repo-self", name: path2 })
|
|
6152
|
+
)
|
|
6153
|
+
];
|
|
6154
|
+
const incompleteWiring = plan.plans.map((p) => ({
|
|
6155
|
+
target: "repo",
|
|
6156
|
+
path: p.path,
|
|
6157
|
+
files: p.toCreate.map((c) => c.name)
|
|
6158
|
+
}));
|
|
6159
|
+
const conflicts = plan.conflicts.map((c) => ({
|
|
6160
|
+
target: "repo",
|
|
6161
|
+
path: c.repo,
|
|
6162
|
+
file: c.file,
|
|
6163
|
+
reason: c.reason,
|
|
6164
|
+
...c.actualTarget !== void 0 ? { actualTarget: c.actualTarget } : {}
|
|
6165
|
+
}));
|
|
6166
|
+
const collisions = plan.collisions.map((c) => ({
|
|
6167
|
+
canonicalName: c.canonicalName,
|
|
6168
|
+
repos: c.repos
|
|
6169
|
+
}));
|
|
6170
|
+
const view = input.view;
|
|
6171
|
+
if (view.kind === "collision") {
|
|
6172
|
+
collisions.push({ canonicalName: view.viewName, repos: [view.repoPath], view: true });
|
|
6173
|
+
} else if (view.kind === "missing-canonical") {
|
|
6174
|
+
missingCanonicals.push({ target: "view", name: view.viewName });
|
|
6175
|
+
} else if (view.kind === "gathered") {
|
|
6176
|
+
const missingSpokes = [];
|
|
6177
|
+
for (const f of view.files) {
|
|
6178
|
+
if (f.state === "missing") {
|
|
6179
|
+
missingSpokes.push(f.name);
|
|
6180
|
+
} else if (f.state === "mismatch" || f.state === "occupied" || f.state === "blocked") {
|
|
6181
|
+
conflicts.push({
|
|
6182
|
+
target: "view",
|
|
6183
|
+
path: view.viewName,
|
|
6184
|
+
file: f.name,
|
|
6185
|
+
reason: f.state,
|
|
6186
|
+
...f.actualTarget !== void 0 ? { actualTarget: f.actualTarget } : {}
|
|
6187
|
+
});
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
6190
|
+
if (missingSpokes.length > 0) {
|
|
6191
|
+
incompleteWiring.push({ target: "view", path: view.viewName, files: missingSpokes });
|
|
6192
|
+
}
|
|
6193
|
+
}
|
|
6194
|
+
return {
|
|
6195
|
+
missingCanonicals,
|
|
6196
|
+
incompleteWiring,
|
|
6197
|
+
conflicts,
|
|
6198
|
+
collisions,
|
|
6199
|
+
unreachable: plan.unreachable,
|
|
6200
|
+
// `unreachable` is intentionally NOT part of `ok`: a declared repo that is not
|
|
6201
|
+
// cloned on this machine is an advisory fact (partial checkout), not drift the
|
|
6202
|
+
// operator must fix here. Only actionable drift denies `ok`.
|
|
6203
|
+
ok: missingCanonicals.length === 0 && incompleteWiring.length === 0 && conflicts.length === 0 && collisions.length === 0
|
|
6204
|
+
};
|
|
6205
|
+
}
|
|
6206
|
+
|
|
6024
6207
|
// src/project/workspace-view.ts
|
|
6025
6208
|
function planWorkspaceView(facts, existing = [], rosterNames = []) {
|
|
6026
6209
|
const deduped = [];
|
|
@@ -7545,6 +7728,33 @@ ${normalized}${markers.end}${section.after}`;
|
|
|
7545
7728
|
throw new Error(`Markers mismatched in ${fileLabel}`);
|
|
7546
7729
|
}
|
|
7547
7730
|
}
|
|
7731
|
+
function seedMarkers(existing, generated, fileLabel, markers = DEFAULT_MARKERS) {
|
|
7732
|
+
const normalized = generated.endsWith("\n") ? generated : `${generated}
|
|
7733
|
+
`;
|
|
7734
|
+
if (existing === null) {
|
|
7735
|
+
return `${markers.start}
|
|
7736
|
+
${normalized}${markers.end}
|
|
7737
|
+
`;
|
|
7738
|
+
}
|
|
7739
|
+
const section = parseMarkers(existing, markers);
|
|
7740
|
+
switch (section.kind) {
|
|
7741
|
+
case "ok":
|
|
7742
|
+
return renderWithMarkers(existing, generated, fileLabel, markers);
|
|
7743
|
+
case "no_markers": {
|
|
7744
|
+
const bom = existing.charCodeAt(0) === 65279 ? "\uFEFF" : "";
|
|
7745
|
+
const body = bom === "" ? existing : existing.slice(1);
|
|
7746
|
+
return `${bom}${markers.start}
|
|
7747
|
+
${normalized}${markers.end}
|
|
7748
|
+
|
|
7749
|
+
${body}`;
|
|
7750
|
+
}
|
|
7751
|
+
case "missing_start":
|
|
7752
|
+
case "missing_end":
|
|
7753
|
+
case "multiple_pairs":
|
|
7754
|
+
case "wrong_order":
|
|
7755
|
+
throw new Error(`Markers mismatched in ${fileLabel}`);
|
|
7756
|
+
}
|
|
7757
|
+
}
|
|
7548
7758
|
function removeMarkerSection(existing, fileLabel, markers = DEFAULT_MARKERS) {
|
|
7549
7759
|
const section = parseMarkers(existing, markers);
|
|
7550
7760
|
switch (section.kind) {
|
|
@@ -8113,11 +8323,13 @@ export {
|
|
|
8113
8323
|
reimportPreservingId,
|
|
8114
8324
|
removeMarkerSection,
|
|
8115
8325
|
removeStopHook,
|
|
8326
|
+
renderAnchorStarter,
|
|
8116
8327
|
renderDecisions,
|
|
8117
8328
|
renderHandoff,
|
|
8118
8329
|
renderOrientation,
|
|
8119
8330
|
renderPresetBlock,
|
|
8120
8331
|
renderReport,
|
|
8332
|
+
renderViewPresetBlock,
|
|
8121
8333
|
renderWithMarkers,
|
|
8122
8334
|
replayEvents,
|
|
8123
8335
|
resolveBasouRepositoryRoot,
|
|
@@ -8130,6 +8342,7 @@ export {
|
|
|
8130
8342
|
sanitizePath,
|
|
8131
8343
|
sanitizeRelatedFiles,
|
|
8132
8344
|
sanitizeWorkingDirectory,
|
|
8345
|
+
seedMarkers,
|
|
8133
8346
|
serializeEventLine,
|
|
8134
8347
|
serializeJsonSchema,
|
|
8135
8348
|
sessionWorkStatsFromEvents,
|
|
@@ -8139,6 +8352,7 @@ export {
|
|
|
8139
8352
|
summarizeRosterDrift,
|
|
8140
8353
|
summarizeSymlinkPlan,
|
|
8141
8354
|
summarizeWiring,
|
|
8355
|
+
summarizeWiringDrift,
|
|
8142
8356
|
tryRemoteUrl,
|
|
8143
8357
|
ulid,
|
|
8144
8358
|
unknownManifestKeys,
|