bmad-method 6.12.1-next.0 → 6.12.1-next.2
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/.claude-plugin/marketplace.json +1 -1
- package/bmad-modules.yaml +5 -0
- package/package.json +1 -1
- package/src/bmm-skills/agents/bmad-agent-analyst/SKILL.md +1 -1
- package/src/bmm-skills/agents/bmad-agent-architect/SKILL.md +1 -1
- package/src/bmm-skills/agents/bmad-agent-dev/SKILL.md +1 -1
- package/src/bmm-skills/agents/bmad-agent-pm/SKILL.md +1 -1
- package/src/bmm-skills/agents/bmad-agent-ux-designer/SKILL.md +1 -1
- package/src/bmm-skills/plan/bmad-architecture/scripts/lint_spine.py +4 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/SKILL.md +1 -1
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-04-final-validation.md +6 -8
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/templates/epics-template.md +1 -0
- package/src/bmm-skills/plan/bmad-prd/SKILL.md +1 -1
- package/src/bmm-skills/plan/bmad-prfaq/SKILL.md +1 -1
- package/src/bmm-skills/plan/bmad-product-brief/SKILL.md +1 -1
- package/src/bmm-skills/plan/bmad-sprint-planning/SKILL.md +1 -1
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/sprint_plan.py +4 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/plan/bmad-ux/SKILL.md +1 -1
- package/src/bmm-skills/ship/bmad-code-review/SKILL.md +1 -1
- package/src/bmm-skills/ship/bmad-correct-course/SKILL.md +1 -1
- package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/SKILL.md +1 -1
- package/src/bmm-skills/ship/bmad-retrospective/SKILL.md +1 -1
- package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/git_evidence.py +4 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/sprint_status.py +4 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-walkthrough/SKILL.md +1 -1
- package/src/bmm-skills/v6-shims/bmad-create-architecture/SKILL.md +1 -1
- package/src/bmm-skills/v6-shims/bmad-create-prd/SKILL.md +1 -1
- package/src/bmm-skills/v6-shims/bmad-create-story/SKILL.md +1 -1
- package/src/bmm-skills/v6-shims/bmad-dev-story/SKILL.md +1 -1
- package/src/bmm-skills/v6-shims/bmad-edit-prd/SKILL.md +1 -1
- package/src/bmm-skills/v6-shims/bmad-sprint-status/SKILL.md +1 -1
- package/src/bmm-skills/v6-shims/bmad-validate-prd/SKILL.md +1 -1
- package/src/core-skills/bmad-customize/scripts/list_customizable_skills.py +4 -0
- package/src/core-skills/bmad-deep-recon/scripts/recon_kit.py +4 -0
- package/src/core-skills/bmad-party-mode/references/create-party.md +1 -1
- package/src/core-skills/bmad-party-mode/scripts/resolve_party.py +16 -0
- package/src/core-skills/bmad-party-mode/scripts/tests/test_resolve_party.py +15 -0
- package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
- package/src/scripts/memlog.py +4 -0
- package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
- package/tools/installer/core/installer.js +3 -0
- package/tools/installer/core/manifest-generator.js +18 -0
- package/tools/installer/install-messages.yaml +13 -6
- package/tools/installer/modules/channel-plan.js +6 -1
- package/tools/installer/modules/external-manager.js +2 -0
- package/tools/installer/ui.js +13 -3
- package/tools/tests/__pycache__/test_validate_skills.cpython-311.pyc +0 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"displayName": "BMad Method Analyze Plan Build",
|
|
15
15
|
"source": "./",
|
|
16
16
|
"description": "Full-lifecycle AI development framework — agents and workflows for product analysis, planning, architecture, and implementation.",
|
|
17
|
-
"version": "6.12.
|
|
17
|
+
"version": "6.12.2",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "Brian (BMad) Madison"
|
|
20
20
|
},
|
package/bmad-modules.yaml
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
# override with --channel/--pin/--next. Valid values: stable | next.
|
|
9
9
|
# Omit to inherit the installer's hardcoded default (stable).
|
|
10
10
|
#
|
|
11
|
+
# pin (optional) — a git tag to install instead of the channel. Use it when
|
|
12
|
+
# newer releases no longer work with this installer. Only --pin overrides it.
|
|
13
|
+
#
|
|
11
14
|
# deprecated (optional, default false) — when true, the module is hidden from
|
|
12
15
|
# the installer picker UNLESS it is already installed (so existing users can
|
|
13
16
|
# still see/manage it, but new users are not offered it).
|
|
@@ -55,6 +58,7 @@ modules:
|
|
|
55
58
|
type: bmad-org
|
|
56
59
|
npmPackage: bmad-creative-intelligence-suite
|
|
57
60
|
default_channel: stable
|
|
61
|
+
pin: v0.3.2
|
|
58
62
|
|
|
59
63
|
bmad-method-test-architecture-enterprise:
|
|
60
64
|
url: https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise
|
|
@@ -66,6 +70,7 @@ modules:
|
|
|
66
70
|
type: bmad-org
|
|
67
71
|
npmPackage: bmad-method-test-architecture-enterprise
|
|
68
72
|
default_channel: stable
|
|
73
|
+
pin: v1.27.2
|
|
69
74
|
|
|
70
75
|
bmad-loop:
|
|
71
76
|
url: https://github.com/bmad-code-org/bmad-loop
|
package/package.json
CHANGED
|
@@ -46,7 +46,7 @@ Treat every entry in `{agent.persistent_facts}` as foundational context you carr
|
|
|
46
46
|
|
|
47
47
|
### Step 5: Load Config
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and use:
|
|
50
50
|
- Use `{user_name}` for greeting
|
|
51
51
|
- Use `{communication_language}` for all communications
|
|
52
52
|
- Use `{document_output_language}` for output documents
|
|
@@ -46,7 +46,7 @@ Treat every entry in `{agent.persistent_facts}` as foundational context you carr
|
|
|
46
46
|
|
|
47
47
|
### Step 5: Load Config
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and use:
|
|
50
50
|
- Use `{user_name}` for greeting
|
|
51
51
|
- Use `{communication_language}` for all communications
|
|
52
52
|
- Use `{document_output_language}` for output documents
|
|
@@ -46,7 +46,7 @@ Treat every entry in `{agent.persistent_facts}` as foundational context you carr
|
|
|
46
46
|
|
|
47
47
|
### Step 5: Load Config
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and use:
|
|
50
50
|
- Use `{user_name}` for greeting
|
|
51
51
|
- Use `{communication_language}` for all communications
|
|
52
52
|
- Use `{document_output_language}` for output documents
|
|
@@ -46,7 +46,7 @@ Treat every entry in `{agent.persistent_facts}` as foundational context you carr
|
|
|
46
46
|
|
|
47
47
|
### Step 5: Load Config
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and use:
|
|
50
50
|
- Use `{user_name}` for greeting
|
|
51
51
|
- Use `{communication_language}` for all communications
|
|
52
52
|
- Use `{document_output_language}` for output documents
|
|
@@ -46,7 +46,7 @@ Treat every entry in `{agent.persistent_facts}` as foundational context you carr
|
|
|
46
46
|
|
|
47
47
|
### Step 5: Load Config
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and use:
|
|
50
50
|
- Use `{user_name}` for greeting
|
|
51
51
|
- Use `{communication_language}` for all communications
|
|
52
52
|
- Use `{document_output_language}` for output documents
|
|
@@ -254,4 +254,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
254
254
|
|
|
255
255
|
|
|
256
256
|
if __name__ == "__main__":
|
|
257
|
+
if sys.platform == "win32":
|
|
258
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
259
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
260
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
257
261
|
sys.exit(main())
|
|
@@ -71,7 +71,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
71
71
|
|
|
72
72
|
### Step 4: Load Config
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and use:
|
|
75
75
|
- Use `{user_name}` for greeting
|
|
76
76
|
- Use `{communication_language}` for all communications
|
|
77
77
|
- Use `{document_output_language}` for output documents
|
|
@@ -119,22 +119,20 @@ For each epic, review stories in order:
|
|
|
119
119
|
|
|
120
120
|
### 6. Complete and Save
|
|
121
121
|
|
|
122
|
-
If all validations pass:
|
|
123
|
-
|
|
124
122
|
- Update any remaining placeholders in the document
|
|
125
123
|
- Ensure proper formatting
|
|
126
|
-
- Save
|
|
124
|
+
- Save epics.md with frontmatter `status: draft`
|
|
125
|
+
|
|
126
|
+
If any validation failed, list each failed check with what is missing, keep `status: draft`, and tell the user "epics.md saved as draft, N checks open". Offer to fix the open checks now and re-run this validation; if the user declines, end the workflow with the document still a draft. Do not offer [C].
|
|
127
|
+
|
|
128
|
+
If all validations pass:
|
|
127
129
|
|
|
128
130
|
**Present Final Menu:**
|
|
129
131
|
**All validations complete!** [C] Complete Workflow
|
|
130
132
|
|
|
131
133
|
HALT — wait for user input before proceeding.
|
|
132
134
|
|
|
133
|
-
When C is selected,
|
|
134
|
-
|
|
135
|
-
Epics and Stories complete. Invoke the `bmad-help` skill.
|
|
136
|
-
|
|
137
|
-
Upon Completion of task output: offer to answer any questions about the Epics and Stories.
|
|
135
|
+
When C is selected, set epics.md frontmatter `status: final`, tell the user the epics.md is complete and ready for development, invoke the `bmad-help` skill, and offer to answer any questions about the Epics and Stories.
|
|
138
136
|
|
|
139
137
|
## On Complete
|
|
140
138
|
|
|
@@ -19,7 +19,7 @@ You are a master facilitator and coach helping the user create, edit, or validat
|
|
|
19
19
|
|
|
20
20
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
|
21
21
|
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (entries prefixed `file:` are loaded). `{workflow.external_sources}` is an org-configured registry of internal tools (knowledge bases, MCP tools); consult them alongside generic web research on the same triggers, org tools preferred when their directive matches. Research itself fires during Discovery — see **Research subagents**.
|
|
22
|
-
3.
|
|
22
|
+
3. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{project_name}`, `{planning_artifacts}`, and `{date}`. Missing keys → neutral defaults; never block.
|
|
23
23
|
4. If headless, follow `references/headless.md` for the whole run. Otherwise greet the user **by name** using `{user_name}` and **in their language** using `{communication_language}` — and stay in `{communication_language}` for every turn for the entire run, not just the greeting. In the greeting, let the user know that at any point they can invoke `bmad-party-mode` for multi-agent perspectives or `bmad-advanced-elicitation` for deeper exploration on a specific section. Then scan for misroute on the first message: if the signal points elsewhere (game → BMad GDS; express build → `bmad-build`; one-pager → `bmad-product-brief`; vet product idea → `bmad-prfaq`; agent skill or custom agent → `bmad-workflow-builder`), suggest they might want the other options before continuing.
|
|
24
24
|
5. Detect intent: **Create** (no PRD), **Update** (existing PRD), **Validate** (critique only). If ambiguous, ask. For Create intent, before binding a fresh workspace, scan `{workflow.prd_output_path}` for prior in-progress runs (folders matching `{workflow.run_folder_pattern}` whose `prd.md` frontmatter `status` is not `final`); if any exist, offer to resume rather than starting over.
|
|
25
25
|
|
|
@@ -50,7 +50,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
50
50
|
|
|
51
51
|
### Step 4: Load Config
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and use:
|
|
54
54
|
- Use `{user_name}` for greeting
|
|
55
55
|
- Use `{communication_language}` for all communications
|
|
56
56
|
- Use `{document_output_language}` for output documents
|
|
@@ -19,7 +19,7 @@ At the opening greeting, let the user know they can invoke `bmad-party-mode` for
|
|
|
19
19
|
2. Execute each entry in `{workflow.activation_steps_prepend}` in order.
|
|
20
20
|
3. Treat every entry in `{workflow.persistent_facts}` as foundational context for the rest of the run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
|
|
21
21
|
4. `{workflow.external_sources}` is an org-configured registry of internal tools (knowledge bases, MCP tools); consult them alongside generic web research on the same triggers in `## Discovery`, org tools preferred when their directive matches. If a named tool is unavailable at runtime, fall back to standard behavior and note the gap when relevant.
|
|
22
|
-
5.
|
|
22
|
+
5. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{project_name}`, `{planning_artifacts}`, and `{date}`.
|
|
23
23
|
6. Greet `{user_name}` in `{communication_language}` — and stay in `{communication_language}` for every turn for the entire run, not just the greeting. Detect intent (create / update / validate). If interactive and intent is unclear, ask; for headless behavior see `## Headless Mode`.
|
|
24
24
|
|
|
25
25
|
Execute each entry in `{workflow.activation_steps_append}` in order.
|
|
@@ -12,7 +12,7 @@ You are a senior developer about to commit to this plan. Two moves, in order: fi
|
|
|
12
12
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
|
13
13
|
2. Execute each entry in `{workflow.activation_steps_prepend}` in order.
|
|
14
14
|
3. Treat every entry in `{workflow.persistent_facts}` as foundational context for the rest of the run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
|
|
15
|
-
4.
|
|
15
|
+
4. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{project_name}`, `{planning_artifacts}`, `{implementation_artifacts}`, `{project_knowledge}` (skip gracefully if unset), and `{date}`. Stay in `{communication_language}` for every turn, not just the greeting.
|
|
16
16
|
5. Greet `{user_name}`, detect intent, and load only what that intent needs:
|
|
17
17
|
- **readiness** — check implementation readiness only: load `references/readiness-gate.md`, run the gate, report, stop
|
|
18
18
|
- **sprint-planning** — the full flow (also the refresh path for an existing `sprint-status.yaml`): load `references/readiness-gate.md`, then on PASS `references/generate-tracking.md`
|
package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc
CHANGED
|
Binary file
|
|
@@ -694,4 +694,8 @@ def main(argv=None):
|
|
|
694
694
|
|
|
695
695
|
|
|
696
696
|
if __name__ == "__main__":
|
|
697
|
+
if sys.platform == "win32":
|
|
698
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
699
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
700
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
697
701
|
main()
|
|
Binary file
|
|
@@ -32,7 +32,7 @@ UX may lead, follow, or stand alone. Inherit `sources:` by reference; the spines
|
|
|
32
32
|
|
|
33
33
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
|
34
34
|
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (entries prefixed `file:` are loaded). `{workflow.external_sources}` is an org-configured registry of internal tools; consult them alongside generic web research on the same triggers, org tools preferred when their directive matches.
|
|
35
|
-
3.
|
|
35
|
+
3. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{project_name}`, `{planning_artifacts}`, and `{date}`. Missing keys → neutral defaults; never block.
|
|
36
36
|
4. If headless, follow `references/headless.md` for the whole run. Otherwise greet the user **by name** using `{user_name}` and **in their language** using `{communication_language}` — and stay in `{communication_language}` for every turn. In the greeting, let the user know `bmad-party-mode` and `bmad-advanced-elicitation` are always available. Then scan for misroute on the first message: PRD → `bmad-prd`; architecture → `bmad-architecture`; game UX → BMad GDS; agent/skill → `bmad-workflow-builder`; brief → `bmad-product-brief`.
|
|
37
37
|
5. Detect intent: **Create**, **Update**, **Validate**. For Create, before binding a fresh workspace, scan `{workflow.ux_output_path}` for prior in-progress runs (folders matching `{workflow.run_folder_pattern}` whose `DESIGN.md` frontmatter `status` is not `final`) and offer to resume rather than starting over.
|
|
38
38
|
|
|
@@ -41,7 +41,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
41
41
|
|
|
42
42
|
### Step 4: Load Config
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve:
|
|
45
45
|
|
|
46
46
|
- `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name`
|
|
47
47
|
- `communication_language`, `document_output_language`, `user_skill_level`
|
|
@@ -40,7 +40,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
40
40
|
|
|
41
41
|
### Step 4: Load Config
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve:
|
|
44
44
|
|
|
45
45
|
- `project_name`, `user_name`
|
|
46
46
|
- `communication_language`, `document_output_language`
|
|
@@ -40,7 +40,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
40
40
|
|
|
41
41
|
### Step 4: Load Config
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve:
|
|
44
44
|
|
|
45
45
|
- `project_name`, `user_name`
|
|
46
46
|
- `communication_language`, `document_output_language`
|
|
@@ -28,7 +28,7 @@ Run these in order before the retrospective begins:
|
|
|
28
28
|
1. **Resolve the workflow block.** Run `uv run --no-cache {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. If it fails, resolve `{workflow.*}` yourself by reading `{skill-root}/customize.toml`, then `{project-root}/_bmad/custom/{skill-name}.toml`, then `.user.toml` in that order, merging base → team → user (scalars override, keyed arrays-of-tables merge by `code`/`id`, other arrays append).
|
|
29
29
|
2. **Run prepend steps** — execute each entry in `{workflow.activation_steps_prepend}` in order.
|
|
30
30
|
3. **Load persistent facts** — treat every `{workflow.persistent_facts}` entry as standing context. `file:` entries are paths/globs under `{project-root}` whose contents load as facts; all others are literal facts.
|
|
31
|
-
4. **Load config**
|
|
31
|
+
4. **Load config** with `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}`: `project_name`, `user_name`, `communication_language`, `document_output_language`, `output_folder`, `user_skill_level`, `planning_artifacts`, `implementation_artifacts`, and `date` (system datetime). Speak all output in `{communication_language}`; write all documents in `{document_output_language}`. Never state time estimates — AI has changed development speed, so hour/day/week predictions are noise.
|
|
32
32
|
5. **Greet and orient** (interactive only). Greet `{user_name}`, name the epic you are about to retro, and optionally invite their going-in concerns ("anything you want weighted — a story that felt rushed, a risky interaction between two stories?"). Use any answer to focus the Phase 1–2 analysis; it directs attention but never becomes a finding without a source.
|
|
33
33
|
6. **Run append steps** — execute each entry in `{workflow.activation_steps_append}` in order.
|
|
34
34
|
|
package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc
CHANGED
|
Binary file
|
|
@@ -301,4 +301,8 @@ def main(argv=None):
|
|
|
301
301
|
|
|
302
302
|
|
|
303
303
|
if __name__ == "__main__":
|
|
304
|
+
if sys.platform == "win32":
|
|
305
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
306
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
307
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
304
308
|
main()
|
|
@@ -743,4 +743,8 @@ def main(argv=None):
|
|
|
743
743
|
|
|
744
744
|
|
|
745
745
|
if __name__ == "__main__":
|
|
746
|
+
if sys.platform == "win32":
|
|
747
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
748
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
749
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
746
750
|
main()
|
|
Binary file
|
|
Binary file
|
|
@@ -40,7 +40,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
40
40
|
|
|
41
41
|
### Step 4: Load Config
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve:
|
|
44
44
|
|
|
45
45
|
- `implementation_artifacts`
|
|
46
46
|
- `planning_artifacts`
|
|
@@ -13,7 +13,7 @@ This skill was consolidated into `bmad-architecture`. It is retained as a thin c
|
|
|
13
13
|
|
|
14
14
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-create-architecture.toml` and `bmad-create-architecture.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
|
|
15
15
|
|
|
16
|
-
2.
|
|
16
|
+
2. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}` and `{communication_language}`.
|
|
17
17
|
|
|
18
18
|
3. Emit a deprecation notice to the user in `{communication_language}`:
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ This skill was consolidated into `bmad-prd`. It is retained as a thin compatibil
|
|
|
13
13
|
|
|
14
14
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-create-prd.toml` and `bmad-create-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
|
|
15
15
|
|
|
16
|
-
2.
|
|
16
|
+
2. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}` and `{communication_language}`.
|
|
17
17
|
|
|
18
18
|
3. Emit a deprecation notice to the user in `{communication_language}`:
|
|
19
19
|
|
|
@@ -52,7 +52,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
52
52
|
|
|
53
53
|
### Step 4: Load Config
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve:
|
|
56
56
|
|
|
57
57
|
- `project_name`, `user_name`
|
|
58
58
|
- `communication_language`, `document_output_language`
|
|
@@ -49,7 +49,7 @@ Treat every entry in `{workflow.persistent_facts}` as foundational context you c
|
|
|
49
49
|
|
|
50
50
|
### Step 4: Load Config
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve:
|
|
53
53
|
|
|
54
54
|
- `project_name`, `user_name`
|
|
55
55
|
- `communication_language`, `document_output_language`
|
|
@@ -13,7 +13,7 @@ This skill was consolidated into `bmad-prd`. It is retained as a thin compatibil
|
|
|
13
13
|
|
|
14
14
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-edit-prd.toml` and `bmad-edit-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
|
|
15
15
|
|
|
16
|
-
2.
|
|
16
|
+
2. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}` and `{communication_language}`.
|
|
17
17
|
|
|
18
18
|
3. Emit a deprecation notice to the user in `{communication_language}`:
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ This skill was consolidated into `bmad-sprint-planning`, which now owns the whol
|
|
|
13
13
|
|
|
14
14
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-sprint-status.toml` and `bmad-sprint-status.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
|
|
15
15
|
|
|
16
|
-
2.
|
|
16
|
+
2. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}` and `{communication_language}`.
|
|
17
17
|
|
|
18
18
|
3. Emit a deprecation notice to the user in `{communication_language}`:
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ This skill was consolidated into `bmad-prd`. It is retained as a thin compatibil
|
|
|
13
13
|
|
|
14
14
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-validate-prd.toml` and `bmad-validate-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
|
|
15
15
|
|
|
16
|
-
2.
|
|
16
|
+
2. Run `uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root}` and resolve `{user_name}` and `{communication_language}`.
|
|
17
17
|
|
|
18
18
|
3. Emit a deprecation notice to the user in `{communication_language}`:
|
|
19
19
|
|
|
@@ -228,4 +228,8 @@ def main(argv: list[str]) -> int:
|
|
|
228
228
|
|
|
229
229
|
|
|
230
230
|
if __name__ == "__main__":
|
|
231
|
+
if sys.platform == "win32":
|
|
232
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
233
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
234
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
231
235
|
sys.exit(main(sys.argv[1:]))
|
|
@@ -319,4 +319,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
319
319
|
|
|
320
320
|
|
|
321
321
|
if __name__ == "__main__":
|
|
322
|
+
if sys.platform == "win32":
|
|
323
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
324
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
325
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
322
326
|
sys.exit(main())
|
|
@@ -63,7 +63,7 @@ Keep pushing for specificity. "Skeptical CFO" is a placeholder; "won't approve a
|
|
|
63
63
|
|
|
64
64
|
## Write via bmad-customize
|
|
65
65
|
|
|
66
|
-
**First, check for code collisions.** A custom member whose `code` matches an
|
|
66
|
+
**First, check for code collisions.** A custom member whose `code` matches an existing member's code, alias, or name silently *overrides* that member in the collective. Before composing, list every taken token once — `uv run {skill-root}/scripts/resolve_party.py --project-root {project-root} --skill {skill-root} --list-codes` — and look up each new member's `code`, lower-cased, in the returned `codes` map. On a hit, name the member it maps to ("`analyst` would override Mary (`bmad-agent-analyst`) — intended, or pick a different code?") and let the user confirm or rename. One check, not a gate.
|
|
67
67
|
|
|
68
68
|
Compose the sparse override and hand it to `bmad-customize` to place, confirm, and write — target skill `bmad-party-mode`, `[workflow]` surface. Default to the **user** override (`bmad-party-mode.user.toml`); offer the **team** file when the party is meant to be shared. Hand it the exact entries: the `party_members` tables, any `party_groups` table (including its `memory` flag), and `default_party` if the user opted in. Keep it sparse — only the new entries, never a copy of the base customize.toml. `bmad-customize` shows the TOML, waits for an explicit yes, writes, and verifies the merge; don't write the file yourself.
|
|
69
69
|
|
|
@@ -16,6 +16,9 @@ into one collective, then projects only what the moment needs:
|
|
|
16
16
|
* --party <id> — full member detail for one chosen group, on demand
|
|
17
17
|
(e.g. when the user switches rooms). Unknown id returns the available
|
|
18
18
|
names instead of an error wall.
|
|
19
|
+
* --list-codes — every token that resolves to a member (code, alias,
|
|
20
|
+
lower-cased name, custom-only codes) mapped to that member's code and
|
|
21
|
+
name. The collision check before adding custom members.
|
|
19
22
|
|
|
20
23
|
The merge is deterministic (a keyed union; a custom member whose code
|
|
21
24
|
matches an installed agent overrides it), so the orchestrator consumes a
|
|
@@ -28,6 +31,7 @@ customize.toml directly if the customization resolver is unavailable.
|
|
|
28
31
|
resolve_party.py --project-root P --skill S
|
|
29
32
|
resolve_party.py --project-root P --skill S --list-groups
|
|
30
33
|
resolve_party.py --project-root P --skill S --party writers-room
|
|
34
|
+
resolve_party.py --project-root P --skill S --list-codes
|
|
31
35
|
"""
|
|
32
36
|
|
|
33
37
|
import argparse
|
|
@@ -172,6 +176,12 @@ def resolve_members(member_tokens, collective, index):
|
|
|
172
176
|
return resolved, unresolved
|
|
173
177
|
|
|
174
178
|
|
|
179
|
+
def code_map(collective, index):
|
|
180
|
+
"""Every resolvable token -> the member it resolves to (code + name)."""
|
|
181
|
+
return {token: {"code": code, "name": collective[code].get("name", code)}
|
|
182
|
+
for token, code in sorted(index.items()) if code in collective}
|
|
183
|
+
|
|
184
|
+
|
|
175
185
|
def group_menu(groups):
|
|
176
186
|
"""Names only — the cheap menu. Open-cast groups (no roster) are flagged."""
|
|
177
187
|
out = []
|
|
@@ -224,6 +234,8 @@ def main():
|
|
|
224
234
|
ap.add_argument("--skill", required=True, help="Path to the bmad-party-mode skill dir")
|
|
225
235
|
ap.add_argument("--party", help="Resolve full detail for this group id")
|
|
226
236
|
ap.add_argument("--list-groups", action="store_true", help="Group names only")
|
|
237
|
+
ap.add_argument("--list-codes", action="store_true",
|
|
238
|
+
help="Every code, alias and name in the collective, for collision checks")
|
|
227
239
|
args = ap.parse_args()
|
|
228
240
|
|
|
229
241
|
project_root = Path(args.project_root).resolve()
|
|
@@ -249,6 +261,10 @@ def main():
|
|
|
249
261
|
agents, agents_ok = load_agents(project_root)
|
|
250
262
|
collective, index, installed_codes = build_collective(agents, workflow.get("party_members", []))
|
|
251
263
|
|
|
264
|
+
if args.list_codes:
|
|
265
|
+
_emit({"installed_agents_resolved": agents_ok, "codes": code_map(collective, index)})
|
|
266
|
+
return
|
|
267
|
+
|
|
252
268
|
if args.party:
|
|
253
269
|
g = find_group(groups, args.party)
|
|
254
270
|
if g is None:
|
|
@@ -67,6 +67,21 @@ class TestResolveMembers(unittest.TestCase):
|
|
|
67
67
|
self.assertEqual(rp.resolve_members([], self.col, self.idx), ([], []))
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
class TestCodeMap(unittest.TestCase):
|
|
71
|
+
def test_maps_aliases_names_and_custom_only_codes_to_their_member(self):
|
|
72
|
+
col, idx, _ = rp.build_collective(AGENTS, [{"code": "morpheus", "name": "Morpheus"}])
|
|
73
|
+
codes = rp.code_map(col, idx)
|
|
74
|
+
self.assertEqual(codes["analyst"], {"code": "bmad-agent-analyst", "name": "Mary"})
|
|
75
|
+
self.assertEqual(codes["mary"]["code"], "bmad-agent-analyst")
|
|
76
|
+
self.assertEqual(codes["bmad-agent-pm"]["code"], "bmad-agent-pm")
|
|
77
|
+
self.assertEqual(codes["morpheus"], {"code": "morpheus", "name": "Morpheus"})
|
|
78
|
+
|
|
79
|
+
def test_override_reports_the_overriding_name(self):
|
|
80
|
+
col, idx, _ = rp.build_collective(AGENTS, [{"code": "analyst", "name": "Mary-Custom"}])
|
|
81
|
+
self.assertEqual(rp.code_map(col, idx)["analyst"],
|
|
82
|
+
{"code": "bmad-agent-analyst", "name": "Mary-Custom"})
|
|
83
|
+
|
|
84
|
+
|
|
70
85
|
class TestGroups(unittest.TestCase):
|
|
71
86
|
GROUPS = [
|
|
72
87
|
{"id": "wr", "name": "Writers", "members": ["analyst", "morpheus"]},
|
|
Binary file
|
package/src/scripts/memlog.py
CHANGED
|
@@ -221,4 +221,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
221
221
|
|
|
222
222
|
|
|
223
223
|
if __name__ == "__main__":
|
|
224
|
+
if sys.platform == "win32":
|
|
225
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
226
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
227
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
224
228
|
sys.exit(main())
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -427,6 +427,8 @@ class ManifestGenerator {
|
|
|
427
427
|
/**
|
|
428
428
|
* Write central _bmad/config.toml with [core], [modules.<code>], [agents.<code>] tables.
|
|
429
429
|
* Install-owned. Team-scope answers → config.toml; user-scope answers → config.user.toml.
|
|
430
|
+
* User-scope keys also get their module.yaml default in config.toml, so a
|
|
431
|
+
* clone without config.user.toml still resolves them.
|
|
430
432
|
* Both files are regenerated on every install. User overrides live in
|
|
431
433
|
* _bmad/custom/config.toml and _bmad/custom/config.user.toml (never touched by installer).
|
|
432
434
|
* @returns {string[]} Paths to the written config files
|
|
@@ -444,6 +446,9 @@ class ManifestGenerator {
|
|
|
444
446
|
// Maps installer moduleName (may be full display name) → module code field
|
|
445
447
|
// from module.yaml, so TOML sections use [modules.<code>] not [modules.<name>].
|
|
446
448
|
const codeByModuleName = {};
|
|
449
|
+
// Module.yaml defaults for user-scope keys, written to config.toml as the
|
|
450
|
+
// team fallback; config.user.toml overrides them.
|
|
451
|
+
const userDefaultsByModule = {};
|
|
447
452
|
for (const moduleName of this.updatedModules) {
|
|
448
453
|
const moduleYamlPath = await resolveInstalledModuleYaml(moduleName);
|
|
449
454
|
if (!moduleYamlPath) {
|
|
@@ -458,9 +463,19 @@ class ManifestGenerator {
|
|
|
458
463
|
if (!parsed || typeof parsed !== 'object') continue;
|
|
459
464
|
if (parsed.code) codeByModuleName[moduleName] = parsed.code;
|
|
460
465
|
scopeByModuleKey[moduleName] = {};
|
|
466
|
+
userDefaultsByModule[moduleName] = {};
|
|
461
467
|
for (const [key, value] of Object.entries(parsed)) {
|
|
462
468
|
if (value && typeof value === 'object' && 'prompt' in value) {
|
|
463
469
|
scopeByModuleKey[moduleName][key] = value.scope === 'user' ? 'user' : 'team';
|
|
470
|
+
// Only plain defaults: no placeholders like {directory_name}, no result transform.
|
|
471
|
+
if (
|
|
472
|
+
value.scope === 'user' &&
|
|
473
|
+
value.default !== undefined &&
|
|
474
|
+
!String(value.default).includes('{') &&
|
|
475
|
+
(value.result === undefined || value.result === '{value}')
|
|
476
|
+
) {
|
|
477
|
+
userDefaultsByModule[moduleName][key] = value.default;
|
|
478
|
+
}
|
|
464
479
|
}
|
|
465
480
|
}
|
|
466
481
|
} catch (error) {
|
|
@@ -488,6 +503,9 @@ class ManifestGenerator {
|
|
|
488
503
|
const user = {};
|
|
489
504
|
const scopes = scopeByModuleKey[moduleName] || {};
|
|
490
505
|
const isCore = moduleName === 'core';
|
|
506
|
+
for (const [key, value] of Object.entries(userDefaultsByModule[moduleName] || {})) {
|
|
507
|
+
if (isCore || !coreKeys.has(key)) team[key] = value;
|
|
508
|
+
}
|
|
491
509
|
for (const [key, value] of Object.entries(cfg || {})) {
|
|
492
510
|
if (!isCore && coreKeys.has(key)) continue;
|
|
493
511
|
if (onlyDeclaredKeys && !(key in scopes)) continue;
|
|
@@ -6,16 +6,19 @@
|
|
|
6
6
|
startMessage: |
|
|
7
7
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
8
8
|
|
|
9
|
-
Agile AI-Driven Development. Powered by BMad Core and a growing module ecosystem.
|
|
9
|
+
The Breakthrough Method of Agile AI-Driven Development - the original and best AI SDLC. Powered by BMad Core and a growing module ecosystem.
|
|
10
10
|
Install official and community modules during setup to customize your experience.
|
|
11
11
|
|
|
12
12
|
🌟 100% free. 100% open source. Always.
|
|
13
13
|
No paywalls. No gated content. Knowledge shared, not sold.
|
|
14
14
|
|
|
15
|
+
🚀 BMad v7 is close, and you can preview and test it now:
|
|
16
|
+
npx skills add bmad-code-org/BMAD-METHOD
|
|
17
|
+
then ask your agent for `bmad setup`. After setup, `bmad migrate`
|
|
18
|
+
tests the v6 to v7 migration (still in beta).
|
|
19
|
+
|
|
15
20
|
🐍 REQUIRED: uv (https://docs.astral.sh/uv/) runs the Python scripts BMAD
|
|
16
|
-
skills rely on
|
|
17
|
-
Without it, bmad-build and bmad-build-auto halt on activation.
|
|
18
|
-
If it's not set up yet, ask your AI agent to "install and set up uv for me".
|
|
21
|
+
skills rely on. If it's not set up yet, ask your AI agent to "install and set up uv for me".
|
|
19
22
|
|
|
20
23
|
🌐 CONNECT:
|
|
21
24
|
Website: https://bmadcode.com/
|
|
@@ -33,5 +36,9 @@ startMessage: |
|
|
|
33
36
|
|
|
34
37
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
35
38
|
|
|
36
|
-
#
|
|
37
|
-
endMessage:
|
|
39
|
+
# Display at the END of installation (after the install summary)
|
|
40
|
+
endMessage: |
|
|
41
|
+
🚀 BMad v7 is close, and you can preview and test it now:
|
|
42
|
+
npx skills add bmad-code-org/BMAD-METHOD
|
|
43
|
+
then ask your agent for `bmad setup`. After setup, `bmad migrate`
|
|
44
|
+
tests the v6 to v7 migration (still in beta).
|
|
@@ -104,15 +104,19 @@ function parsePinSpec(spec) {
|
|
|
104
104
|
* @param {string} args.code
|
|
105
105
|
* @param {Object} args.channelOptions - from parseChannelOptions
|
|
106
106
|
* @param {string} [args.registryDefault] - module's default_channel, if any
|
|
107
|
+
* @param {string} [args.registryPin] - module's registry pin, if any
|
|
107
108
|
* @returns {{channel: 'stable'|'next'|'pinned', pin?: string, source: string}}
|
|
108
109
|
* source describes where the decision came from, for logging / debugging.
|
|
109
110
|
*/
|
|
110
|
-
function decideChannelForModule({ code, channelOptions, registryDefault }) {
|
|
111
|
+
function decideChannelForModule({ code, channelOptions, registryDefault, registryPin }) {
|
|
111
112
|
const { global, nextSet, pins } = channelOptions || { nextSet: new Set(), pins: new Map() };
|
|
112
113
|
|
|
113
114
|
if (pins && pins.has(code)) {
|
|
114
115
|
return { channel: 'pinned', pin: pins.get(code), source: 'flag:--pin' };
|
|
115
116
|
}
|
|
117
|
+
if (registryPin) {
|
|
118
|
+
return { channel: 'pinned', pin: registryPin, source: 'registry:pin' };
|
|
119
|
+
}
|
|
116
120
|
if (nextSet && nextSet.has(code)) {
|
|
117
121
|
return { channel: 'next', source: 'flag:--next' };
|
|
118
122
|
}
|
|
@@ -144,6 +148,7 @@ function buildPlan({ modules, channelOptions }) {
|
|
|
144
148
|
code: mod.code,
|
|
145
149
|
channelOptions,
|
|
146
150
|
registryDefault: mod.defaultChannel,
|
|
151
|
+
registryPin: mod.pin,
|
|
147
152
|
}),
|
|
148
153
|
);
|
|
149
154
|
}
|
|
@@ -130,6 +130,7 @@ class ExternalModuleManager {
|
|
|
130
130
|
npmPackage: mod.npm_package || mod.npmPackage || null,
|
|
131
131
|
pluginName: mod.plugin_name || mod.pluginName || null,
|
|
132
132
|
defaultChannel: normalizeChannelName(mod.default_channel || mod.defaultChannel) || 'stable',
|
|
133
|
+
pin: mod.pin || null,
|
|
133
134
|
deprecated: mod.deprecated === true,
|
|
134
135
|
deprecationMessage: mod.deprecation_message || mod['deprecation-message'] || mod.deprecationMessage || null,
|
|
135
136
|
marketplacePlugin: mod.marketplace_plugin === true || mod['marketplace-plugin'] === true || mod.marketplacePlugin === true,
|
|
@@ -273,6 +274,7 @@ class ExternalModuleManager {
|
|
|
273
274
|
code: moduleCode,
|
|
274
275
|
channelOptions: options.channelOptions,
|
|
275
276
|
registryDefault: moduleInfo.defaultChannel,
|
|
277
|
+
registryPin: moduleInfo.pin,
|
|
276
278
|
});
|
|
277
279
|
|
|
278
280
|
// Same-plan short-circuit: a single install calls cloneExternalModule
|
package/tools/installer/ui.js
CHANGED
|
@@ -70,15 +70,17 @@ function buildModuleLabel(name, latestVersion, installedVersion = '') {
|
|
|
70
70
|
* @param {Object} options
|
|
71
71
|
* @param {string|null} [options.repoUrl] - Module repository URL for tag resolution
|
|
72
72
|
* @param {string|null} [options.registryDefault] - Registry default channel
|
|
73
|
+
* @param {string|null} [options.registryPin] - Registry pinned tag
|
|
73
74
|
* @param {Object|null} [options.channelOptions] - Parsed installer channel options
|
|
74
75
|
* @returns {Promise<{version: string, lookupAttempted: boolean, lookupSucceeded: boolean}>}
|
|
75
76
|
*/
|
|
76
|
-
async function getModuleVersion(moduleCode, { repoUrl = null, registryDefault = null, channelOptions = null } = {}) {
|
|
77
|
+
async function getModuleVersion(moduleCode, { repoUrl = null, registryDefault = null, registryPin = null, channelOptions = null } = {}) {
|
|
77
78
|
if (repoUrl) {
|
|
78
79
|
const plan = decideChannelForModule({
|
|
79
80
|
code: moduleCode,
|
|
80
81
|
channelOptions,
|
|
81
82
|
registryDefault,
|
|
83
|
+
registryPin,
|
|
82
84
|
});
|
|
83
85
|
|
|
84
86
|
try {
|
|
@@ -291,6 +293,13 @@ class UI {
|
|
|
291
293
|
}
|
|
292
294
|
confirmedDirectory = expandedDir;
|
|
293
295
|
await prompts.log.info(`Using directory from command-line: ${confirmedDirectory}`);
|
|
296
|
+
} else if (options.yes) {
|
|
297
|
+
confirmedDirectory = process.cwd();
|
|
298
|
+
const validation = this.validateDirectorySync(confirmedDirectory);
|
|
299
|
+
if (validation) {
|
|
300
|
+
throw new Error(`Invalid directory: ${validation}`);
|
|
301
|
+
}
|
|
302
|
+
await prompts.log.info(`Using current directory: ${confirmedDirectory}`);
|
|
294
303
|
} else {
|
|
295
304
|
confirmedDirectory = await this.getConfirmedDirectory();
|
|
296
305
|
}
|
|
@@ -1058,10 +1067,10 @@ class UI {
|
|
|
1058
1067
|
const allOptions = [];
|
|
1059
1068
|
const initialValues = [];
|
|
1060
1069
|
|
|
1061
|
-
const buildModuleEntry = async (code, name, description, isDefault, repoUrl = null, registryDefault = null) => {
|
|
1070
|
+
const buildModuleEntry = async (code, name, description, isDefault, repoUrl = null, registryDefault = null, registryPin = null) => {
|
|
1062
1071
|
const isInstalled = installedModuleIds.has(code);
|
|
1063
1072
|
const installedVersion = installedModuleVersions.get(code) || '';
|
|
1064
|
-
const versionState = await getModuleVersion(code, { repoUrl, registryDefault, channelOptions });
|
|
1073
|
+
const versionState = await getModuleVersion(code, { repoUrl, registryDefault, registryPin, channelOptions });
|
|
1065
1074
|
const label = buildModuleLabel(name, versionState.version, installedVersion);
|
|
1066
1075
|
return {
|
|
1067
1076
|
label,
|
|
@@ -1109,6 +1118,7 @@ class UI {
|
|
|
1109
1118
|
mod.defaultSelected,
|
|
1110
1119
|
mod.url || null,
|
|
1111
1120
|
mod.defaultChannel || null,
|
|
1121
|
+
mod.pin || null,
|
|
1112
1122
|
);
|
|
1113
1123
|
if (mod.deprecated && mod.deprecationMessage) {
|
|
1114
1124
|
entry.hint = entry.hint ? `${entry.hint} — ${mod.deprecationMessage}` : mod.deprecationMessage;
|
|
Binary file
|