Add specify artifact JSON introspection for composed artifact stacks - #4300
Closed
nicolehaugen with Copilot wants to merge 3 commits into
Closed
Add specify artifact JSON introspection for composed artifact stacks#4300nicolehaugen with Copilot wants to merge 3 commits into
specify artifact JSON introspection for composed artifact stacks#4300nicolehaugen with Copilot wants to merge 3 commits into
Conversation
Co-authored-by: nicolehaugen <10600161+nicolehaugen@users.noreply.github.com>
Co-authored-by: nicolehaugen <10600161+nicolehaugen@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add
Add Aug 24, 2026
specify artifact command exposing composition stacks as JSONspecify artifact JSON introspection for composed artifact stacks
Contributor
There was a problem hiding this comment.
Review details
Suppressed comments (1)
src/specify_cli/artifacts/_commands.py:148
- The
infopath has the same JSON-envelope gap aslist: catalog directory reads can raiseOSError, which bypasses both handlers and produces a traceback/non-JSON stderr response. Map it toArtifactResolutionErrorhere too.
except PresetError:
_emit_error_and_exit(ArtifactResolutionError())
return # pragma: no cover
- Files reviewed: 8/8 changed files
- Comments generated: 4
- Review effort level: Balanced
Comment on lines
+655
to
+658
| def _get_baseline(self) -> CoreBaseline: | ||
| if self._baseline is None: | ||
| self._baseline = CoreBaseline.load() | ||
| return self._baseline |
Comment on lines
+62
to
+66
| manifest = { | ||
| "id": pack_id, | ||
| "version": "1.0.0", | ||
| "metadata": {"name": f"Test preset {pack_id}"}, | ||
| "provides": provides, |
Comment on lines
+23
to
+27
| manifest = { | ||
| "id": pack_id, | ||
| "version": "1.0.0", | ||
| "metadata": {"name": f"Test preset {pack_id}"}, | ||
| "provides": provides, |
Comment on lines
+104
to
+106
| except PresetError: | ||
| _emit_error_and_exit(ArtifactResolutionError()) | ||
| return # pragma: no cover — _emit_error_and_exit raises |
Contributor
There was a problem hiding this comment.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
src/specify_cli/artifacts/init.py:365
- An enclosing manifest is not necessarily the manifest that declared this layer. When a valid preset or extension manifest omits an artifact and the resolver uses convention fallback, this walk still returns that manifest as
manifestPath, falsely attributing the contribution to it. Carry declaration provenance from the resolver or verify that the manifest contains the matching kind/name before exposing its path.
manifest = _find_enclosing_manifest(source)
src/specify_cli/artifacts/init.py:607
- Descriptions do not follow the effective resolver layer. Core rows are inserted first, so this condition preserves a non-empty core description even when a preset actively replaces that artifact; for non-core collisions, alphabetic directory order wins instead of preset/extension priority. Select the description associated with the highest active resolver layer so the flat inventory represents the effective artifact.
elif description and not seen[key].description:
- Files reviewed: 8/8 changed files
- Comments generated: 3
- Review effort level: Balanced
| for entry in sorted(overrides_dir.iterdir(), key=lambda p: p.name): | ||
| if not entry.is_file() or entry.suffix != _TEMPLATE_SUFFIX: | ||
| continue | ||
| name = entry.stem |
Comment on lines
+780
to
+782
| for entry in sorted(scripts_dir.iterdir(), key=lambda p: p.name): | ||
| if entry.is_file() and entry.suffix in (".sh", ".ps1", ".py"): | ||
| name = canonical_script_name(entry) |
Comment on lines
+818
to
+824
| if entry.suffix not in (".sh", ".ps1", ".py"): | ||
| continue | ||
| name = canonical_script_name(entry) | ||
| if name is None: | ||
| name = entry.stem.replace("_", "-") if entry.suffix == ".py" else entry.stem | ||
| if ":" not in name: | ||
| yield kind, name |
|
This is being closed because the issues are being addressed in PR #4267 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This introduces a new
specify artifactcommand surface to expose the effective artifact inventory and per-artifact composition stack as machine-readable JSON. It closes the gap between resolver behavior and external tooling by making layer provenance, active/hidden state, and lookup IDs queryable.CLI surface
specify artifactcommand group registration at the root CLI.specify artifact list --json→ flat inventory (id,name,kind,description)specify artifact info <name> --json→ resolved artifact + ordered stack metadataArtifact catalog + stack model
command/template/scriptlayer,presetId,presetName,strategyactive,hidden,manifestPath,lookupIdDeterministic IDs and lookup parity
lookupIdconsistently across project/preset/extension/core layers.Script runtime variant normalization
.sh,.ps1,.py(including Python underscore→hyphen mapping).Behavioral contract coverage
active/hidden)manifestPathposix/relative)specify artifactcommand exposing composition stacks as JSON #4267