yadflow 4.0.1 → 4.2.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/CHANGELOG.md +35 -0
- package/README.md +6 -2
- package/bin/commands.mjs +2 -0
- package/bin/yad.mjs +74 -4
- package/cli/detect.mjs +642 -0
- package/cli/doctor.mjs +24 -0
- package/cli/errors.mjs +1 -0
- package/cli/manifest.mjs +3 -0
- package/cli/toolbox.mjs +814 -0
- package/package.json +4 -3
package/cli/doctor.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import { soloTeamHint, TEAM_CMD } from './people.mjs';
|
|
|
25
25
|
import { indexFreshness, INDEX_FILE } from './product-index.mjs';
|
|
26
26
|
import { productGit, resolveDefaultBranch } from './productcommit.mjs';
|
|
27
27
|
import { readOwners } from './owners.mjs';
|
|
28
|
+
import { loadChoices, readToolboxFile } from './toolbox.mjs';
|
|
28
29
|
|
|
29
30
|
// A registered path doctor may run git in (E81): a checkout the judgement accepts — never a refused
|
|
30
31
|
// entry (git run in a folder the Product shaped as a repo reads its `config`, which can run a command),
|
|
@@ -446,6 +447,7 @@ export function projectChecks(checks, root, { headCount = null } = {}) {
|
|
|
446
447
|
// inside the `project` block. The renderer prints a header every time the section CHANGES, so a
|
|
447
448
|
// `project` check added after the `shape` section prints the word "project" a second time.
|
|
448
449
|
skillBindingChecks(checks, root);
|
|
450
|
+
toolboxFileChecks(checks, root);
|
|
449
451
|
|
|
450
452
|
// repos.json: parse + every entry is a live git repo; staleness vs syncedHead
|
|
451
453
|
let registry = { repos: [] };
|
|
@@ -2107,6 +2109,28 @@ export function skillBindingChecks(checks, root) {
|
|
|
2107
2109
|
}
|
|
2108
2110
|
}
|
|
2109
2111
|
|
|
2112
|
+
// `.sdlc/toolbox.json`: which toolbox tools this Product uses or skips, and its own tools (E86). Absent is
|
|
2113
|
+
// the normal case. THE FILE ONLY: whether a tool is installed is `yad toolbox check`'s answer, and a
|
|
2114
|
+
// missing tool is never a doctor line (decided with E86 — no tool is required). A broken file fails, as
|
|
2115
|
+
// skills.json does; a line that does nothing warns, because `yad toolbox list` quietly shows the default.
|
|
2116
|
+
export function toolboxFileChecks(checks, root) {
|
|
2117
|
+
const rel = PROJECT_FILES.toolboxConfig;
|
|
2118
|
+
if (!exists(path.join(root, rel))) return;
|
|
2119
|
+
const { error } = readToolboxFile(root);
|
|
2120
|
+
if (error) {
|
|
2121
|
+
check(checks, 'toolbox', 'project', 'fail', `${rel} ${error}`, 'fix the JSON or restore it from git — `yad toolbox list` shows the defaults until then');
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
const { problems, unreachable, shipped, custom } = loadChoices(root);
|
|
2125
|
+
if (problems.length) {
|
|
2126
|
+
// An entry with no id (or an empty one) is out of `remove`'s reach; only hand-editing fixes it.
|
|
2127
|
+
check(checks, 'toolbox', 'project', 'warn', `${rel}: ${problems.length} line(s) do nothing — ${problems.map((p) => p.replace(`${rel}: `, '')).join('; ')} [YAD-CFG-007]`,
|
|
2128
|
+
`fix them by hand, or \`yad toolbox remove <id>\` — it clears whatever the file holds under that id — and add the tool again${unreachable ? ' (an entry with no id, or an empty one: fix it by hand)' : ''}`);
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
check(checks, 'toolbox', 'project', 'ok', `toolbox: ${shipped.size} shipped tool choice(s), ${custom.length} tool(s) of this project's own`);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2110
2134
|
// A step this release does not recognise. Every step the engine can run has a row in the step
|
|
2111
2135
|
// catalogue (E4), and that row is what gives it both a phase and a skill. So an id no phase claims is
|
|
2112
2136
|
// an id with no row at all: one `yad next` cannot guide, `yad gate` has no artifact rule for, and no
|
package/cli/errors.mjs
CHANGED
|
@@ -30,6 +30,7 @@ export const CODES = {
|
|
|
30
30
|
'YAD-CFG-004': 'learning.json names an unknown learning tool (expected one of config.yaml learning.tools, or none)',
|
|
31
31
|
'YAD-CFG-005': 'the Product settings (product.json, or hub.json on a Product that has only that name) set a platform but are missing git_url (required to scope auth + open PRs)',
|
|
32
32
|
'YAD-CFG-006': 'skills.json binds a step to something that is not a skill name (expected a string, or a non-empty list of strings)',
|
|
33
|
+
'YAD-CFG-007': 'toolbox.json has a line that does nothing — a tool this yadflow does not ship, a choice other than use or skip, or a custom tool that is incomplete, malformed, listed twice or uses a shipped tool\'s id',
|
|
33
34
|
'YAD-CLI-001': 'a --json run needed an answer that only a prompt could give',
|
|
34
35
|
};
|
|
35
36
|
|
package/cli/manifest.mjs
CHANGED
|
@@ -275,6 +275,9 @@ export const PROJECT_FILES = {
|
|
|
275
275
|
// the normal case and means "every step uses the skill the catalogue names" — like design.json,
|
|
276
276
|
// which is absent on a markdown-only project.
|
|
277
277
|
skillsConfig: '.sdlc/skills.json',
|
|
278
|
+
// Which toolbox tools this project uses or skips, and its own tools (E86). Absent is the normal case:
|
|
279
|
+
// the core tools and the connected design, testing and learning tools are the ones in use.
|
|
280
|
+
toolboxConfig: '.sdlc/toolbox.json',
|
|
278
281
|
// The kill switch and the Shape steps a team has set to `advance: auto` (E34). Absent is the normal
|
|
279
282
|
// case: the switch is off and every Shape step is `human`. A project file, not the module config the
|
|
280
283
|
// switch lived in before (`_bmad/sdlc/config.yaml` then, `.sdlc/config.yaml` since E3) — that one is
|