feat(packs): remote packs and app level default_tags#27
Merged
Conversation
Install is now an eager operation for all pack types. The overloaded `name` field is removed from the install flow; a pack's identity comes from its own manifest instead. - Remote resolution goes through the GitHub Releases API: empty version resolves the latest release, otherwise the tag is looked up trying both `v<version>` and `<version>` so the `v` prefix and tag convention are handled transparently. The platform asset is selected by matching `*_<os>_<arch>.tar.gz`, checksum-verified, and the resolved tag is pinned. - The in-tarball binary name is derived from the asset prefix, falling back to the single executable in the archive. - Install downloads/writes to a staging dir, runs the pack `manifest` command to derive name+version, then relocates and upserts. Failures (bad repo, no asset, checksum mismatch, manifest error, missing local path) surface at install time with no DB row created. - Runtime resolution is unchanged: the cached binary is located by scanning the version dir, so the install-time cache is a hit. - Frontend: drop the name input, remote = source + optional version, upload = file picker; surface install errors as a toast so they are visible while the dialog stays open. Adds resolver and install-handler tests covering latest/pinned/prefix resolution, asset matching, checksum mismatch, not-found, binary-name fallback, manifest-derived identity, and no-row-on-failure.
Remote packs stored their source as github.com/org/repo and rendered it truncated, clipping long slugs with no recovery. Display the org/repo slug (host dropped) as a link to the repo with a hover external-link affordance and a tooltip carrying the full source; keep uploaded/local sources tooltip-backed so they no longer clip silently.
Org-wide default_tags in app config are now merged beneath each pack's own default_tags (pack-level keys win) when parameters are loaded from the DB, with server-side validation and read-only inheritance display in the pack parameters dialog. Also archives the completed manifest-derived-pack-install change and adds the settings-page-redesign proposal that depends on this one.
There was a problem hiding this comment.
Pull request overview
This PR updates the pack install lifecycle to be manifest-driven (name/version derived from the pack binary rather than operator input), adds GitHub Releases API–based remote resolution (including “latest” when version is omitted), and introduces org-wide default_tags stored in app settings and merged into pack execution while being displayed read-only in the pack parameters UI.
Changes:
- Remove operator-supplied pack
namefrom install/upload flows; derive identity from manifest and make install eager (download/validate at install time). - Resolve remote packs via GitHub Releases API (tag-based or latest), selecting platform assets and verifying checksums.
- Add app-level
default_tags, merge them under pack-level tags for execution, and display inherited tags in the pack parameters editor.
Reviewed changes
Copilot reviewed 43 out of 44 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| web/frontend/src/routes/packs/+page.svelte | Removes pack-name input; updates install/upload UX and uses toasts for install feedback. |
| web/frontend/src/lib/components/SchemaForm.svelte | Adds read-only display of inherited org default tags inside default_tags. |
| web/frontend/src/lib/components/PackParametersDialog.svelte | Fetches app config to supply inherited default_tags to the schema form. |
| web/frontend/src/lib/components/PackCard.svelte | Improves remote pack source display by linking to GitHub repo slug when applicable. |
| web/frontend/src/lib/api/client.ts | Updates upload API to no longer send a name field. |
| web/frontend/package-lock.json | Bumps js-yaml dependency metadata. |
| openspec/specs/packs/spec.md | Updates pack install requirements to reflect manifest-derived identity and GitHub Releases resolution. |
| openspec/specs/pack-execution/spec.md | Specifies org default_tags merge precedence beneath pack-level tags. |
| openspec/specs/app-settings/spec.md | Adds specification for app-level default_tags storage/validation and UI inheritance display. |
| openspec/changes/settings-page-redesign/tasks.md | Adds tasks for upcoming settings page redesign and shared KV editor extraction. |
| openspec/changes/settings-page-redesign/specs/settings-page/spec.md | Adds requirements for tabbed settings layout and shared string-map editor. |
| openspec/changes/settings-page-redesign/proposal.md | Documents motivation and scope of the settings page redesign. |
| openspec/changes/settings-page-redesign/design.md | Design decisions for the settings page redesign and shared editor extraction. |
| openspec/changes/settings-page-redesign/.openspec.yaml | Declares spec-driven change metadata for settings redesign. |
| openspec/changes/archive/2026-07-06-org-default-tags/tasks.md | Archives tasks for org-wide default tags implementation. |
| openspec/changes/archive/2026-07-06-org-default-tags/specs/pack-execution/spec.md | Archives pack-execution delta for org default tags. |
| openspec/changes/archive/2026-07-06-org-default-tags/specs/app-settings/spec.md | Archives app-settings delta for org default tags. |
| openspec/changes/archive/2026-07-06-org-default-tags/proposal.md | Archives org default tags proposal. |
| openspec/changes/archive/2026-07-06-org-default-tags/design.md | Archives org default tags design. |
| openspec/changes/archive/2026-07-06-org-default-tags/.openspec.yaml | Archives org default tags change metadata. |
| openspec/changes/archive/2026-07-01-manifest-derived-pack-install/tasks.md | Archives tasks for manifest-derived install lifecycle. |
| openspec/changes/archive/2026-07-01-manifest-derived-pack-install/specs/packs/spec.md | Archives packs spec delta for manifest-derived installs. |
| openspec/changes/archive/2026-07-01-manifest-derived-pack-install/proposal.md | Archives manifest-derived install proposal. |
| openspec/changes/archive/2026-07-01-manifest-derived-pack-install/design.md | Archives manifest-derived install design. |
| openspec/changes/archive/2026-07-01-manifest-derived-pack-install/.openspec.yaml | Archives manifest-derived install change metadata. |
| internal/web/types.go | Marks install request name as optional/ignored for backward compatibility. |
| internal/web/scenarios.go | Merges org default tags beneath pack default_tags when building pack configs from DB. |
| internal/web/scenarios_test.go | Adds tests for org tag merge semantics and non-mutation guarantees. |
| internal/web/packs_handler.go | Reworks install/upload handlers to eagerly validate binaries and derive identity from manifest. |
| internal/web/handlers.go | Adds default_tags validation branch to config update handler. |
| internal/web/api_packs_test.go | Updates pack install/list test to match eager local install and manifest-derived name. |
| internal/web/api_packs_install_test.go | Adds install handler tests for remote/latest, manifest name derivation, and failure cases. |
| internal/web/api_config_test.go | Adds tests ensuring default_tags validation rejects invalid shapes and persists valid maps. |
| internal/testutil/fakes/fakes.go | Extends fake config store to round-trip default_tags. |
| internal/packs/resolver/resolver.go | Adds GitHub Releases API resolution, asset selection, checksum verification, and extraction logic. |
| internal/packs/resolver/resolver_test.go | Adds resolver tests for latest/tag resolution, asset selection edge cases, and extraction fallbacks. |
| internal/packs/resolver/resolver_concurrency_test.go | Updates concurrency test to use API base URL and JSON release responses. |
| internal/detonators/simrun_detonator_test.go | Ensures map[string]string tag maps still JSON-encode correctly for TF_VAR env. |
| internal/db/migrations/018_default_tags_appconfig.up.sql | Backfills default_tags key in app_config. |
| internal/db/migrations/018_default_tags_appconfig.down.sql | Removes default_tags key on rollback. |
| internal/db/config.go | Maps default_tags in typed app config parsing/serialization. |
| internal/db/config_test.go | Adds coverage for parsing/marshaling default_tags in app config. |
| internal/config/appconfig.go | Adds DefaultTags field and default value to AppConfig. |
| internal/config/appconfig_test.go | Updates default app config test for new DefaultTags field. |
Files not reviewed (1)
- web/frontend/package-lock.json: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
120
to
126
| // validatePackConfig validates the pack configuration. | ||
| func (r *Resolver) validatePackConfig(cfg PackConfig) error { | ||
| if cfg.Source == "" { | ||
| return fmt.Errorf("pack %s: source is required", cfg.Name) | ||
| } | ||
| if cfg.Version == "" { | ||
| return fmt.Errorf("pack %s: version is required for remote packs", cfg.Name) | ||
| } | ||
| return nil | ||
| } |
Comment on lines
+75
to
+83
| var pack *db.Pack | ||
| if config.PackType(req.Type) == config.PackTypeRemote { | ||
| pack, err = h.installRemote(r.Context(), res, req) | ||
| } else { | ||
| pack, err = h.installLocal(r.Context(), res, req) | ||
| } | ||
| if err != nil { | ||
| writeError(w, http.StatusBadRequest, err.Error()) | ||
| return |
Comment on lines
+358
to
365
| // HandleUploadPack handles POST /api/packs/upload. | ||
| // | ||
| // The uploaded binary is written to a staging location, its manifest command is | ||
| // run to derive the pack's identity, then it is relocated to | ||
| // <DataDir>/packs/<name>/upload/<name>. The request's `name` form field is | ||
| // ignored. A manifest failure aborts the install with no DB record. | ||
| func (h *PackHandlers) HandleUploadPack(w http.ResponseWriter, r *http.Request) { | ||
| r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize) |
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.
Summary
Reworks pack installation to be an eager, manifest-driven operation for all pack types, adds GitHub Releases-based remote pack resolution, and introduces org-wide
default_tagsin app config that are merged beneath each pack's owndefault_tags.Manifest-derived pack install
manifestcommand derives its name and version, then the pack is relocated and upserted. The overloadednamefield is removed from the install flow.Remote pack resolution via GitHub Releases
v<version>and<version>, so thevprefix convention is handled transparently. The resolved tag is pinned.*_<os>_<arch>.tar.gzand checksum-verified; the in-tarball binary name is derived from the asset prefix, falling back to the single executable in the archive.Org-wide default_tags
default_tagsapp-config setting (migration018), merged beneath each pack's owndefault_tagswhen parameters are loaded from the DB — pack-level keys win.Frontend
org/reposlug linked to the repo (tooltip carries the full source); uploaded/local sources are tooltip-backed instead of clipping silently.Tests & specs
default_tagsmerge in scenario runs, config API, and detonator env.manifest-derived-pack-installandorg-default-tagsOpenSpec changes; adds thesettings-page-redesignproposal.