feat: Deployment Sets, Color/Icon Management, and Multi-Model Integration#99
feat: Deployment Sets, Color/Icon Management, and Multi-Model Integration#99
Conversation
…depth limit Implement DeploymentSetService.resolve() with BFS pre-fetch for member data (avoids N+1) and pure DFS resolution with depth-20 limit, deduplication by artifact_uuid (first-seen order), and group expansion. Add domain exceptions module with DeploymentSetResolutionError and DeploymentSetCycleError. 20 unit tests covering nesting, dedup, groups, depth limits, and edge cases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hability Implement _check_cycle() using BFS descendant reachability to prevent circular references when adding set members. Self-references rejected immediately, transitive cycles detected with full path reporting. add_member_with_cycle_check() gates set-type members through cycle check before delegating to repository. 12 new tests covering direct, transitive, DAG, and self-reference scenarios. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…or handling Implement batch_deploy() that resolves a set to artifact UUIDs, maps each to name/type via CollectionArtifact JOIN query, resolves project_id to project_path, and deploys each artifact via DeploymentManager. Per- artifact exceptions caught without aborting loop. Structured logging with warning-level messages for missing UUIDs. 9 new tests covering partial failure, unknown UUID, project lookup, and log assertions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
12 schemas covering CRUD, member management, resolution, and batch deploy operations. MemberCreate includes model_validator enforcing exactly one reference field (artifact_uuid/group_id/nested_set_id). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…feature flag Router at /api/v1/deployment-sets with full CRUD, member management, recursive resolution, clone, and batch deploy endpoints. Cycle detection maps to HTTP 422. 34 integration tests covering happy paths and error cases. Feature flag deployment_sets_enabled added to APISettings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both DS-007 (schemas) and DS-008 (endpoints) completed with 34 passing integration tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… Query hooks Types mirror all Pydantic response/request DTOs. Hooks cover full CRUD for sets and members, resolution, cloning, and batch deploy with proper cache invalidation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dit dialogs Card grid shows name, description, member count, color accent, and action menu. Search filters client-side by name/description/tags. Create and edit dialogs with color presets and tag input. Nav entry added under Collections section. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and members endpoint Detail page shows set metadata with inline-editable name/description, color accent, resolved artifact count, and member list with type badges. Added GET members endpoint to API router and corresponding hook/API client function. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ef error handling Dialog supports adding Artifacts, Groups, or other Sets as members. Each tab has search filtering, loading skeletons, empty states, and just-added feedback. 422 circular reference errors show toast. Wired to detail page Add Member button. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…deploy flow
Adds batchDeploySetByProjectId API function and useBatchDeploySet React Query
hook that POSTs to /deployment-sets/{id}/deploy. Invalidates deployments cache
on success without touching deployment-sets cache.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lectors and result table Two-step modal: select target project + optional profile, then view per-artifact deploy results with status badges (success/skipped/error) and summary line. Wired to detail page Deploy Set button and list card deploy action. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…deploy, delete, clone 14 tests covering: circular reference detection (422 on A→B→A), batch deploy adapter with 3-level nested resolution, FR-10 delete semantics (inbound parent refs removed), clone isolation, and observability warning logs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tion 5 tests verifying resolution of 320-member 5-level nested sets completes within 500ms SLA. Tests both in-memory DFS and DB-backed paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tchDeployModal 57 Jest/RTL tests covering: 3-tab member picker, circular-ref error toasts, batch deploy input form, result table with status badges, summary line counts, and accessibility attributes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d nav gating Adds GET /config/feature-flags endpoint, useFeatureFlags React Query hook with graceful fallback, deployment-sets page client with flag gating (disabled state shows empty state), and conditional nav item visibility. Fixes hook count in index.ts (13 deployment-sets hooks). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…acker Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tory Running run_migrations() on every repository instantiation caused a race condition under concurrent API requests — Alembic's global script state was mutated by multiple threads simultaneously, producing KeyError: 'script' on the deployment-sets deploy endpoint. Migrations are already run once at startup via CacheManager.__init__(). The redundant per-request call is removed; create_tables() is kept for backward-compat safety (idempotent via checkfirst=True). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… and context for UI enhancement Frontend-only v2 enhancing deployment sets with modal-based detail view, clickable cards, ArtifactBrowseCard-variant member cards, and redesigned AddMemberDialog with MiniArtifactCard grid and filtering. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… (DSv2-001, DSv2-002) Create DeploymentSetDetailsModal with tabbed layout (Overview/Members) following ArtifactDetailsModal pattern. Refactor DeploymentSetCard for full-card click with keyboard accessibility while preserving action menu functionality. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ist page (DSv2-003, DSv2-004) Implement Overview tab with set metadata (color swatch, tags, member counts, timestamps). Wire DeploymentSetDetailsModal into deployment-sets-page-client with selectedSetId state. Thread onOpen prop through DeploymentSetList to cards. Replace [id] detail page with permanentRedirect to /deployment-sets. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…erDialog (DSv2-005, DSv2-007) Create DeploymentSetMemberCard with rich artifact layout (type borders, badges) and summary layout for groups/sets. Redesign AddMemberDialog with MiniArtifactCard grid, real-time search filtering, and artifact type toggle filters. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ation (DSv2-006) Add DeploymentSetMembersTab with responsive grid of DeploymentSetMemberCard components. Artifact members open ArtifactDetailsModal, set members open nested DeploymentSetDetailsModal, group members show info popover. Includes loading skeletons and empty state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 7 tasks (14 pts) across 3 phases completed successfully. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ng, and colored tags - Expand modal to max-w-5xl for better card visibility - Add Deploy button and kebab menu (Edit/Delete) to modal header - Make name, description, and tags editable inline in Overview tab - Add DeploymentSetTagEditor with tag search, toggle, and create - Fix MiniArtifactCard min-width in AddMemberDialog (min-w-[180px]) - Add colored tags with getTagColor + inline tag popover on set cards Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s button Redesign Members tab with type-grouped collapsible sections (Artifacts, Groups, Sets) with independent scrolling per section. Add "Add Members" button at tab top that opens AddMemberDialog. Sections show count in header and collapse with chevron toggle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace raw fetch('/api/v1/groups') (missing required collection_id param)
with useGroups(collectionId) hook. Thread collectionId as configurable prop
through AddMemberDialog → GroupTab, falling back to the first collection
via useCollections when not provided.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add DeploymentSetTag junction model and migration for many-to-many relationship between deployment sets and shared tags. Extend TagService and TagRepository with deployment_set_count support. Update create/edit-deployment-set-dialog to use the unified tag system. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The tags API has a max limit of 100, but useTags(200) was being called which caused a 422 validation error when opening the tag picker. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract DeploymentSetTagEditor from modal into shared component used by both the card and modal (identical tag editing UX) - Card now shows all available tags from API instead of only current tags - useUpdateDeploymentSet uses setQueryData for instant detail cache update (no refetch delay) - All DS mutations (create/update/delete) invalidate tag queries so deployment_set_count stays fresh Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…llback
Thread collectionId from page → modal → AddMemberDialog so the Groups
tab loads groups from the correct collection. Replace naive
useCollections({ limit: 1 }) fallback with priority-ordered selection:
explicit prop > name match (default/main/personal) > highest artifact
count > first item.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d state - Add MiniGroupCard with dynamic group icon/color from group-constants - Add MiniDeploymentSetCard with set color accent and member tooltip - Add Member dialog: Groups/Sets tabs now use mini card grids with "Already Selected" disabled overlay for existing members - Members tab in details modal: replaced DeploymentSetMemberCard with mini cards (artifact/group/set) using hover remove overlay - member-list.tsx: replaced row list with mini card grid layout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hestration docs Implement the foundation layer of multi-model SDLC integration based on the architecture report. All external model integrations are opt-in by default; Claude remains the sole orchestrator. Phase 1 changes: - codex skill: default GPT-5.3-Codex, model line separation (Codex vs General), effort policy table, escalation rules, Codex-Spark fast option - gemini-cli skill: Gemini 3.1 Pro (~1M/65K context), Flash option, image/SVG workflows, output chunking discipline, creative prompt templates - sora skill: Sora 2 naming alignment, synced audio capability - multi-model.toml: unified model routing config with effort policies, checkpoints, thresholds, and asset pipeline provenance tracking - model-selection-guide: decision tree for model routing with interaction patterns and unique capabilities map - agent-assignments: external model task assignments with reliability hazards - quality-gates: optional cross-model validation gate and disagreement protocol - gemini-orchestrator agent: updated to Gemini 3.1 Pro with new capabilities Remaining phases: 2 (checkpoint workflows), 3 (creative workflows), 4 (advanced integration — Teams, local LLM, consensus). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eative integration Phase 2 — Checkpoint Workflows: - cross-model-review.md: plan review (Codex read-only) and PR cross-validation (Gemini Pro/Flash) workflow specs with prompt templates and model selection logic - escalation-protocols.md: debug escalation to Codex after failed cycles, thinking/effort escalation rules (adaptive-first, artifact-gated), review escalation thresholds - disagreement-protocol.md: CI-as-referee when models conflict — tests decide, "prove it" rule for missing tests, reversibility-based design disagreement handling Phase 3 — Creative Workflows: - creative-workflows.md: unified routing for image/SVG/UI mockup/video tasks with step-by-step workflows and model selection decision tree - nano-banana-pro SKILL.md: asset pipeline integration with provenance tracking (meta.json schema), batch generation, model routing context (NBP vs Gemini) - sora SKILL.md: SDLC integration section with orchestration pattern and asset pipeline storage Remaining: Phase 4 (Teams, local LLM, effort auto-tuning, consensus, cost tracking) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create .claude/specs/multi-model-usage-spec.md: comprehensive rules and patterns for using the multi-model system — config reading, checkpoint behavior, effort policy, decision tree, workflow patterns, disagreement protocol, asset provenance, and reference map - Update CLAUDE.md: add Multi-Model Integration subsection under Agent Delegation with capability routing table, effort policy summary, disagreement protocol pointer, and key reference paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… & icon management 5-phase plan covering backend (CustomColor model, colors API, icon packs config), shared frontend components (ColorSelector, IconPicker with shadcn-iconpicker), deployment set integration, settings appearance tab, and validation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ment Progress tracker with 26 tasks across 5 phases (47 story points), 8 parallelization batches. Context file maps all affected files and technical decisions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lor/icon persistence - Add CustomColor ORM model, Alembic migrations (custom_colors table + deployment_sets color/icon columns) - Add CustomColorRepository with hex validation and CustomColorService - Add /api/v1/colors CRUD router and /api/v1/settings/icon-packs config router - Wire deployment_sets POST/PUT/GET to persist and return color + icon fields - Fix Alembic env.py to auto-resolve DB URL from skillmeat config - Add icon-packs.config.json with default Lucide pack Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ings tabs, and refactor dialogs - Install shadcn-iconpicker and upgrade lucide-react to 0.575.0 for dynamic import support - Add color-constants.ts and icon-constants.ts with shared types and preset definitions - Add React Query hooks for custom colors and icon packs (use-colors.ts, use-icon-packs.ts) - Create shared ColorSelector and IconPicker components in components/shared/ - Refactor GroupMetadataEditor to use shared components (removes ~220 lines of inline logic) - Add Appearance tab to Settings page with Colors and Icons sub-tabs (CRUD + toggle UI) - Update CreateDeploymentSetDialog and EditDeploymentSetDialog with shared components Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…torage migration - Add 22 integration tests covering all /api/v1/colors and /api/v1/settings/icon-packs endpoints - Add one-time localStorage migration banner to Colors settings tab (migrates legacy custom colors) - Deployment set cards already correctly display stored color/icon — no change needed - Icon-picker lazy bundle confirmed: 6KB chunk via next/dynamic with ssr:false Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…test - Fix 3 TS2532 errors in shadcn-iconpicker primitive (non-null assertions on guarded index accesses) - ColorSelector and IconPicker verified WCAG 2.1 AA compliant (aria-labels, aria-pressed, role=group) - Add E2E Playwright smoke test for custom color create → verify in dialogs → delete flow - Mark all 26 tasks completed (100%); implementation plan status → completed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…edit dialog
API icon pack response only contains {id, name, enabled} — no icons array.
Add `?? []` null-coalesce so the loop is a no-op and the picker falls back
to showing all Lucide icons (iconsList=undefined).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ash on Icons tab Same root cause as icon-picker fix — API response omits icons array. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ialog - Fix "0 icons" by reading count from local iconsData (~1400+ Lucide icons) instead of API - Add IconPackViewerDialog: max-w-5xl, 80vh, sidebar category tabs + 8-12 col icon grid - Search filters by name/tags within active category; live result count shown - Clicking pack row opens viewer; Switch stopPropagation to avoid accidental open - DynamicIcon renders each icon live from lucide-react/dynamic Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…racking New feature planning for Similar Artifacts — detection, comparison, and consolidation across collection and marketplace. Includes: - PRD with 6-phase breakdown (42 story points) - Implementation plan with 3 phase files - Progress tracking (3 phase files + context worknotes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…le upload
- POST /settings/icon-packs/install accepts URL or multipart file upload;
validates JSON structure, guards against duplicate IDs, stores metadata only
- DELETE /settings/icon-packs/{pack_id} removes user-installed packs
(lucide-default is protected)
- AddIconPackDialog with tabbed URL/file-upload interface, loading spinner,
success alert, and per-tab error clearing
- IconPackRow gains trash button for non-default packs wired to useDeleteIconPack
- Three new frontend hooks: useInstallIconPackFromUrl, useInstallIconPackFromFile,
useDeleteIconPack — all invalidate iconPackKeys.all on success
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…packs Replace the fixed GROUP_ICON_OPTIONS set and _normalize_and_validate_choice calls with simple string/length validation (max 32 chars) so any Lucide or custom icon-pack token is accepted without a schema change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CHANGELOG.md (+109 lines) - Site-Wide Color & Icon Management (2026-02-25) — Custom colors API, shared ColorSelector/IconPicker, settings tabs, icon pack management, localStorage migration - Deployment Sets v2 — UI Enhancement (2026-02-24) — Clickable cards, detail modal with tabs, inline editing, minified member cards, colored tags, tag unification - Deployment Sets v1 — Full Feature (2026-02-23) — Resolution service, circular-ref detection, batch deploy, 11 REST endpoints, frontend pages, testing - Multi-Model SDLC Integration (2026-02-22) — Multi-model orchestration, routing config, checkpoints, creative workflows - Bug Fixes — Alembic per-request migration removal, icon picker null guards README.md (+19 lines) - New Deployment Sets feature section with 5 features - Updated endpoint count to 160+ and web pages to 25 features.json (+56 lines) - New deployment-sets category with 5 features driving the README build User Docs - web-ui-guide.md (+85 lines) — Deployment Sets usage guide, Color & Icon Customization guide, Settings tab updates - feature-flags.md (+10 lines) — SKILLMEAT_DEPLOYMENT_SETS_ENABLED flag documentation Agent Context Files - component-patterns.md (+198 lines) — Shared components (ColorSelector, IconPicker), Deployment Sets component patterns - data-flow-patterns.md (+9 lines) — Stale times and cache invalidation for deployment sets - deployment-data-flows.md (+63 lines) — Resolution flow, batch deploy flow, cache invalidation graph - api-endpoint-mapping.md (+59 lines) — 11 deployment set endpoints, 4 custom color endpoints
| * an X dismiss button with aria-label="Close", so we target the one whose | ||
| * direct text content is "Close" (not wrapped in a sr-only span). | ||
| */ | ||
| function getFooterCloseButton() { |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
In general, unused functions should be removed or, if they represent intended behavior, they should be used in the code. Here, getFooterCloseButton is a test helper that is not actually used. The safest fix without changing behavior is to delete the unused helper function entirely, rather than adding artificial calls just to silence the warning.
Concretely, in skillmeat/web/__tests__/deployment-sets/batch-deploy-modal.test.tsx, remove the entire getFooterCloseButton function definition and its associated comment block (lines 107–120 in the snippet). No additional imports, variables, or methods are needed, and no other parts of the file need to be updated.
| @@ -104,21 +104,6 @@ | ||
| return { ...utils, onOpenChange }; | ||
| } | ||
|
|
||
| /** | ||
| * Find the footer "Close" button specifically — the Radix Dialog also renders | ||
| * an X dismiss button with aria-label="Close", so we target the one whose | ||
| * direct text content is "Close" (not wrapped in a sr-only span). | ||
| */ | ||
| function getFooterCloseButton() { | ||
| const allClose = screen.getAllByRole('button', { name: /close/i }); | ||
| // The footer button renders with visible text "Close"; the dialog X button | ||
| // renders its label as sr-only text. We find the one whose textContent | ||
| // (trimmed) is exactly "Close" without child elements hiding it. | ||
| const footer = allClose.find((btn) => btn.textContent?.trim() === 'Close'); | ||
| if (!footer) throw new Error('Could not find footer Close button'); | ||
| return footer; | ||
| } | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // Mock data | ||
| // --------------------------------------------------------------------------- |
Summary
Major feature branch introducing Deployment Sets (v1 + v2), site-wide Color & Icon Management, and Multi-Model SDLC Integration.
Deployment Sets v1 — Full Feature
/api/v1/deployment-sets/SKILLMEAT_DEPLOYMENT_SETS_ENABLED)Deployment Sets v2 — UI Enhancement
Color & Icon Management
/api/v1/custom-colors/) with DB persistenceMulti-Model SDLC Integration
.claude/config/multi-model.toml)Documentation
Bug Fixes
pack.iconsTest plan
pytestfor backend testspnpm testfor frontend tests🤖 Generated with Claude Code