Dedicated Features and Assets pages; project overview dashboard#117
Merged
Conversation
…a dashboard
- Add features.index page (project/{project}/features) with the full
feature list, create, and drag-reorder UI moved out of project.show
- Add assets.index page (project/{project}/assets) wrapping the existing
project-assets-panel component
- Rewrite project.show as a true overview: project header + 6-card nav
grid linking to Features, Stories, Plans, Approvals, Runs, Assets
- Fix project description to render via <x-markdown> instead of {{ }}
- Add Assets and Features sidebar links; Features now points to the
dedicated features.index route instead of the buried #features anchor
- Update ProjectShowTest to call features-related actions on the
features.index component
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MCP tools (text/link, no binary):
- add-project-asset: create text/link asset on a project
- add-story-asset: create text/link asset on a story (auto-includes,
reopens approval per ADR-0015)
- list-context-items: list project or story assets by id
- update-context-item: update title/body of an existing asset
- delete-context-item: delete by id (story scope reopens approval)
File upload API (POST /api/v1/assets/upload):
- Accepts multipart/form-data with file + project_id or story_id
- Authenticated via `Authorization: Bearer {SPECIFY_API_KEY}`
- Acting user resolved from MCP_USER_EMAIL (same config as MCP server)
- Delegates to AssetUploader so all ADR-0015 contracts are upheld
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR restructures project navigation by introducing dedicated Features and Assets pages, updates navigation routes/sidebar to match, and adds API/MCP surfaces for managing and uploading context assets.
Changes:
- Added new Livewire routes for
/projects/{project}/featuresand/projects/{project}/assets, and updated sidebar navigation accordingly. - Introduced a versioned HTTP API endpoint (
/api/v1/assets/upload) protected by an API key middleware. - Added MCP tools for listing/creating/updating/deleting context items (project/story assets) and registered them on the MCP server.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Feature/ProjectShowTest.php | Updates Livewire tests to create/reorder features via the new Features index page component. |
| routes/web.php | Adds Livewire route for features.index and assets.index under projects. |
| routes/api.php | Introduces authenticated API route for uploading context assets. |
| resources/views/layouts/app/sidebar.blade.php | Updates Features link to the new index route and adds an Assets sidebar link. |
| config/specify.php | Adds specify.mcp.api_key config value (from SPECIFY_API_KEY) used by API-key auth. |
| bootstrap/app.php | Enables API routing with an api/v1 prefix. |
| app/Mcp/Tools/UpdateContextItemTool.php | Adds MCP tool to update context item title/body (text-only body). |
| app/Mcp/Tools/ListContextItemsTool.php | Adds MCP tool to list project-level or story-scoped context items. |
| app/Mcp/Tools/DeleteContextItemTool.php | Adds MCP tool to delete a context item by ID. |
| app/Mcp/Tools/AddStoryAssetTool.php | Adds MCP tool to create story-scoped text/link context assets. |
| app/Mcp/Tools/AddProjectAssetTool.php | Adds MCP tool to create project-level text/link context assets. |
| app/Mcp/Servers/SpecifyServer.php | Registers new context-asset MCP tools on the Specify MCP server. |
| app/Http/Middleware/AuthenticateApiKey.php | Adds Bearer-token API key authentication and acting-user selection. |
| app/Http/Controllers/Api/ContextAssetUploadController.php | Adds API controller for uploading file-backed context assets to a project or story. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+15
to
+16
|
|
||
| if (! $configured || $request->bearerToken() !== $configured) { |
Comment on lines
+21
to
+22
| 'project_id' => ['required_without:story_id', 'nullable', 'integer'], | ||
| 'story_id' => ['required_without:project_id', 'nullable', 'integer'], |
Comment on lines
+29
to
+35
| $validated = $request->validate([ | ||
| 'project_id' => ['required', 'integer'], | ||
| 'type' => ['required', 'string', 'in:text,link'], | ||
| 'title' => ['required', 'string', 'max:255'], | ||
| 'body' => ['nullable', 'string', 'max:10000'], | ||
| 'url' => ['nullable', 'string', 'url', 'max:2048'], | ||
| ]); |
Comment on lines
+29
to
+35
| $validated = $request->validate([ | ||
| 'story_id' => ['required', 'integer'], | ||
| 'type' => ['required', 'string', 'in:text,link'], | ||
| 'title' => ['required', 'string', 'max:255'], | ||
| 'body' => ['nullable', 'string', 'max:10000'], | ||
| 'url' => ['nullable', 'string', 'url', 'max:2048'], | ||
| ]); |
| 'project_id' => ['nullable', 'integer'], | ||
| 'story_id' => ['nullable', 'integer'], | ||
| ]); | ||
|
|
Comment on lines
+16
to
+17
| #[Description('Update the title or body of an existing text or link context asset. File assets can only have their title changed.')] | ||
| class UpdateContextItemTool extends Tool |
Comment on lines
8
to
13
| ->withRouting( | ||
| web: __DIR__.'/../routes/web.php', | ||
| api: __DIR__.'/../routes/api.php', | ||
| apiPrefix: 'api/v1', | ||
| commands: __DIR__.'/../routes/console.php', | ||
| health: '/up', |
Comment on lines
+139
to
+143
| ListContextItemsTool::class, | ||
| AddProjectAssetTool::class, | ||
| AddStoryAssetTool::class, | ||
| UpdateContextItemTool::class, | ||
| DeleteContextItemTool::class, |
- Install laravel/sanctum and run personal_access_tokens migration - Add HasApiTokens to User model - API upload route now uses auth:sanctum (Bearer token per user) - Remove AuthenticateApiKey middleware and SPECIFY_API_KEY config key Agents call POST /api/v1/assets/upload with a Sanctum token created via php artisan sanctum:token or the user's profile settings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- AddProjectAssetTool / AddStoryAssetTool: add required_if validation for body (text) and url (link); catch ValidationException and return Response::error so callers get a clean error instead of an exception - ListContextItemsTool: reject requests that supply both project_id and story_id at once instead of silently preferring story_id - UpdateContextItemTool: add url field support for link assets; fix description to match actual behaviour - ContextAssetUploadController: add prohibited_with to prevent both project_id and story_id being supplied simultaneously - Add ContextItemMcpToolsTest covering list/add/update/delete including access control and ADR-0015 story-approval-reopen semantics Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
/projects/{id}/features): moves the feature list, create, and drag-reorder UI off the project overview onto its own page; sidebar link updated to point here/projects/{id}/assets): dedicated page wrapping the project-assets-panel; sidebar link added/projects/{id}): stripped down to a true dashboard — project header + 6-card nav grid linking to Features, Stories, Plans, Approvals, Runs, Assets<x-markdown>instead of plain{{ }}Test plan
/projects/{id}— see dashboard with 6 nav cards, no embedded feature list/projects/{id}/featureswith full list + create + reorder/projects/{id}/assetswith the assets panelcomposer testpasses (570/570)🤖 Generated with Claude Code