chore(vault): track .obsidian plugin configs (incl. obsidian-git settings)
This commit is contained in:
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
# Change: Add Default View Location Setting
|
||||
|
||||
## Why
|
||||
Users may prefer to have the OpenCode panel open in the main editor area instead of the sidebar, depending on their workflow and screen size. Currently, the view always opens in the right sidebar with no option to change this behavior.
|
||||
|
||||
## What Changes
|
||||
- Add a new `defaultViewLocation` setting with options: `"sidebar"` or `"main"`
|
||||
- Update view activation logic to respect this setting when opening the panel
|
||||
- Sidebar opens in the right leaf (current behavior)
|
||||
- Main opens in a new tab in the main editor area
|
||||
|
||||
## Impact
|
||||
- Affected specs: `001-mvp-opencode-embed` (Settings Configuration, Sidebar View Registration, Ribbon Icon)
|
||||
- Affected code: `src/types.ts`, `src/main.ts`, `src/SettingsTab.ts`
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Settings Configuration
|
||||
The plugin SHALL provide configurable settings for server port, hostname, executable path, project directory, auto-start behavior, and default view location.
|
||||
|
||||
#### Scenario: Settings persistence
|
||||
- **WHEN** the user modifies settings
|
||||
- **THEN** changes are persisted to plugin data
|
||||
- **AND** the process manager is updated with new settings
|
||||
|
||||
#### Scenario: Default view location options
|
||||
- **WHEN** the user configures default view location
|
||||
- **THEN** the options available are "sidebar" and "main"
|
||||
- **AND** the default value is "sidebar"
|
||||
|
||||
### Requirement: Sidebar View Registration
|
||||
The plugin SHALL register an ItemView that displays in either the Obsidian sidebar or main editor area based on user settings.
|
||||
|
||||
#### Scenario: View activation in sidebar
|
||||
- **WHEN** the user clicks the ribbon icon or runs the toggle command
|
||||
- **AND** the default view location is set to "sidebar"
|
||||
- **THEN** the OpenCode view opens in the right sidebar
|
||||
- **AND** if the view already exists, it is revealed
|
||||
|
||||
#### Scenario: View activation in main area
|
||||
- **WHEN** the user clicks the ribbon icon or runs the toggle command
|
||||
- **AND** the default view location is set to "main"
|
||||
- **THEN** the OpenCode view opens as a new tab in the main editor area
|
||||
- **AND** if the view already exists in any location, it is revealed
|
||||
|
||||
### Requirement: Ribbon Icon
|
||||
The plugin SHALL add a ribbon icon that activates the OpenCode view in the configured default location.
|
||||
|
||||
#### Scenario: Ribbon icon click
|
||||
- **WHEN** the user clicks the OpenCode ribbon icon
|
||||
- **THEN** the OpenCode view is activated in the location specified by the default view location setting
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
## 1. Implementation
|
||||
|
||||
- [ ] 1.1 Add `defaultViewLocation` type and setting to `src/types.ts`
|
||||
- Add type: `"sidebar" | "main"`
|
||||
- Add to `OpenCodeSettings` interface
|
||||
- Add default value `"sidebar"` to `DEFAULT_SETTINGS`
|
||||
|
||||
- [ ] 1.2 Update `src/main.ts` view activation logic
|
||||
- Modify `activateView()` method to check `defaultViewLocation` setting
|
||||
- For "sidebar": use `getLeaf("right")` (existing behavior)
|
||||
- For "main": use `getLeaf("tab")` to open in main editor area
|
||||
- Ensure existing view detection works for both locations
|
||||
|
||||
- [ ] 1.3 Add setting UI to `src/SettingsTab.ts`
|
||||
- Add dropdown setting for "Default view location"
|
||||
- Options: "Sidebar" and "Main window"
|
||||
- Description explaining the behavior difference
|
||||
|
||||
- [ ] 1.4 Test the feature
|
||||
- Verify sidebar mode opens in right sidebar
|
||||
- Verify main mode opens as a tab in editor area
|
||||
- Verify toggling reveals existing view regardless of location
|
||||
- Verify setting persists across plugin reload
|
||||
Vendored
+121
@@ -0,0 +1,121 @@
|
||||
## Context
|
||||
|
||||
This plugin embeds the OpenCode AI assistant into Obsidian by spawning a local server process and displaying its web UI in an iframe within the Obsidian sidebar. The design prioritizes simplicity and reliability for the MVP.
|
||||
|
||||
**Constraints:**
|
||||
- Desktop-only (requires Node.js child_process APIs)
|
||||
- Must work within Obsidian's plugin sandbox
|
||||
- OpenCode CLI must be installed separately by the user
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Seamless embedding of OpenCode UI in Obsidian sidebar
|
||||
- Reliable server process lifecycle management
|
||||
- Configurable server and project settings
|
||||
- Quick access via ribbon icon and keyboard shortcut
|
||||
|
||||
**Non-Goals:**
|
||||
- Mobile support (not possible due to Node.js dependencies)
|
||||
- Native UI rendering (OpenCode provides its own web UI)
|
||||
- Multiple simultaneous OpenCode instances
|
||||
- Deep Obsidian integration (file linking, note references)
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Iframe Embedding vs Native Rendering
|
||||
**Decision:** Embed OpenCode's web UI via iframe rather than building native Obsidian UI.
|
||||
|
||||
**Rationale:**
|
||||
- Can be up and running quickly
|
||||
- OpenCode already provides a full-featured web interface
|
||||
- Reduces maintenance burden - UI updates come from OpenCode automatically
|
||||
- Allows feature parity with standalone OpenCode web experience
|
||||
|
||||
**Trade-offs:**
|
||||
- Limited ability to customize UI appearance
|
||||
- Requires CORS configuration (`--cors app://obsidian.md`)
|
||||
- Iframe isolation limits some interactions
|
||||
|
||||
### 2. Process State Machine
|
||||
**Decision:** Use a 4-state machine: `stopped` → `starting` → `running` | `error`
|
||||
|
||||
**Rationale:**
|
||||
- Clear, predictable state transitions
|
||||
- Enables reactive UI that shows appropriate content for each state
|
||||
- Prevents race conditions (can't start while starting)
|
||||
|
||||
**States:**
|
||||
- `stopped`: Server not running, show start button
|
||||
- `starting`: Spawn initiated, polling health endpoint, show spinner
|
||||
- `running`: Health check passed, show iframe
|
||||
- `error`: Spawn failed or health check timeout, show retry option
|
||||
|
||||
### 3. Lazy Start Strategy
|
||||
**Decision:** Start server when view opens, not when plugin loads.
|
||||
|
||||
**Rationale:**
|
||||
- Faster Obsidian startup (server spawn is ~2-5 seconds)
|
||||
- User may not need OpenCode every session
|
||||
- Auto-start available as opt-in setting for users who prefer it
|
||||
|
||||
**Implementation:** `OpenCodeView.onOpen()` calls `plugin.startServer()` if state is `stopped`.
|
||||
|
||||
### 4. Health Check Polling
|
||||
**Decision:** Poll `/global/health` endpoint every 500ms during startup, with 15-second timeout.
|
||||
|
||||
**Rationale:**
|
||||
- Server needs time to initialize before accepting connections
|
||||
- Polling is simple and reliable
|
||||
- 15 seconds accommodates slow systems without waiting too long
|
||||
|
||||
**Trade-offs:**
|
||||
- Slight delay before iframe loads (typically 1-3 seconds)
|
||||
- Could use server stdout parsing instead, but health endpoint is more reliable
|
||||
|
||||
### 5. Graceful Shutdown
|
||||
**Decision:** SIGTERM first, SIGKILL after 2-second timeout.
|
||||
|
||||
**Rationale:**
|
||||
- Allows server to clean up resources gracefully
|
||||
- SIGKILL fallback ensures process doesn't hang
|
||||
- 2 seconds is sufficient for typical cleanup
|
||||
|
||||
### 6. Project Directory Encoding
|
||||
**Decision:** Encode project directory as base64 in URL path (e.g., `http://127.0.0.1:14096/{base64-path}`).
|
||||
|
||||
**Rationale:**
|
||||
- OpenCode server supports multiple projects via URL routing
|
||||
- Base64 handles special characters in paths safely
|
||||
- Allows future support for switching projects without server restart
|
||||
|
||||
### 7. Callback-Based State Subscriptions
|
||||
**Decision:** Use callback array pattern for state change notifications.
|
||||
|
||||
**Rationale:**
|
||||
- Simpler than event emitters or observables for this scale
|
||||
- View subscribes to plugin state changes in `onOpen()`
|
||||
- Immediate notification ensures UI stays in sync
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
plugin.onProcessStateChange((state) => {
|
||||
this.currentState = state;
|
||||
this.updateView();
|
||||
});
|
||||
```
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| OpenCode CLI not installed | Clear error message with settings link |
|
||||
| Port already in use | Health check detects existing server, reuses it |
|
||||
| Server crash during use | View shows error state, user can retry |
|
||||
| Slow server startup | 15-second timeout with spinner feedback |
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should we support multiple project directories (tabs/switcher)?
|
||||
- Should settings changes hot-reload the iframe without full restart?
|
||||
- Should we add connection status indicator in header?
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
# Change: Document MVP Capabilities
|
||||
|
||||
## Why
|
||||
The Obsidian OpenCode plugin MVP has been implemented but lacks formal specification. This change retroactively documents the existing functionality to establish a baseline specification that can be expanded as the MVP is polished.
|
||||
|
||||
## What Changes
|
||||
- **ADDED** `001-mvp-opencode-embed` capability spec covering:
|
||||
- Server process management (spawn, health check, shutdown, state machine)
|
||||
- Sidebar view with iframe embedding and state-reactive UI
|
||||
- Plugin settings with validation
|
||||
- Commands and ribbon icon integration
|
||||
|
||||
## Impact
|
||||
- Affected specs: None (new spec)
|
||||
- Affected code: None (documentation only)
|
||||
- This is a retroactive documentation effort with no code changes
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Server Process Spawning
|
||||
The plugin SHALL spawn the OpenCode server process using the configured executable path, port, and hostname when the user initiates server start.
|
||||
|
||||
#### Scenario: Successful server spawn
|
||||
- **WHEN** the user starts the server
|
||||
- **THEN** the plugin spawns `opencode serve --port <port> --hostname <hostname> --cors app://obsidian.md`
|
||||
- **AND** the process runs with the vault directory as the working directory
|
||||
|
||||
### Requirement: Server Health Checking
|
||||
The plugin SHALL verify server availability by polling a health endpoint during startup.
|
||||
|
||||
#### Scenario: Health check during startup
|
||||
- **WHEN** the server process is spawned
|
||||
- **THEN** the plugin polls `GET /global/health` every 500ms
|
||||
- **AND** transitions to running state when the endpoint returns HTTP 200
|
||||
- **AND** transitions to error state if 15 seconds elapse without success
|
||||
|
||||
#### Scenario: Existing server detected
|
||||
- **WHEN** the user starts the server
|
||||
- **AND** a server is already running on the configured port
|
||||
- **THEN** the plugin reuses the existing server
|
||||
- **AND** transitions directly to running state
|
||||
|
||||
### Requirement: Server Shutdown
|
||||
The plugin SHALL gracefully terminate the server process when stopping.
|
||||
|
||||
#### Scenario: Graceful shutdown
|
||||
- **WHEN** the user stops the server
|
||||
- **THEN** the plugin sends SIGTERM to the process
|
||||
- **AND** sends SIGKILL after 2 seconds if the process is still running
|
||||
|
||||
### Requirement: Process State Management
|
||||
The plugin SHALL maintain a state machine with states: stopped, starting, running, and error.
|
||||
|
||||
#### Scenario: State transitions
|
||||
- **WHEN** the server is not running
|
||||
- **THEN** the state is `stopped`
|
||||
- **WHEN** spawn is initiated
|
||||
- **THEN** the state transitions to `starting`
|
||||
- **WHEN** health check succeeds
|
||||
- **THEN** the state transitions to `running`
|
||||
- **WHEN** spawn fails or health check times out
|
||||
- **THEN** the state transitions to `error`
|
||||
|
||||
### Requirement: Sidebar View Registration
|
||||
The plugin SHALL register an ItemView that displays in the Obsidian sidebar.
|
||||
|
||||
#### Scenario: View activation
|
||||
- **WHEN** the user clicks the ribbon icon or runs the toggle command
|
||||
- **THEN** the OpenCode view opens in the right sidebar
|
||||
- **AND** if the view already exists, it is revealed
|
||||
|
||||
### Requirement: View State Rendering
|
||||
The plugin SHALL render different UI content based on the current process state.
|
||||
|
||||
#### Scenario: Stopped state UI
|
||||
- **WHEN** the process state is `stopped`
|
||||
- **THEN** the view displays a "Start OpenCode" button
|
||||
|
||||
#### Scenario: Starting state UI
|
||||
- **WHEN** the process state is `starting`
|
||||
- **THEN** the view displays a loading spinner with "Starting OpenCode..." message
|
||||
|
||||
#### Scenario: Running state UI
|
||||
- **WHEN** the process state is `running`
|
||||
- **THEN** the view displays a header with controls and an iframe loading the server URL
|
||||
|
||||
#### Scenario: Error state UI
|
||||
- **WHEN** the process state is `error`
|
||||
- **THEN** the view displays an error message with "Retry" and "Open Settings" buttons
|
||||
|
||||
### Requirement: Iframe Controls
|
||||
The plugin SHALL provide controls in the view header when the server is running.
|
||||
|
||||
#### Scenario: Header controls available
|
||||
- **WHEN** the server is running
|
||||
- **THEN** the header displays reload and stop buttons
|
||||
- **AND** clicking reload refreshes the iframe
|
||||
- **AND** clicking stop terminates the server
|
||||
|
||||
### Requirement: Lazy Server Start
|
||||
The plugin SHALL start the server automatically when the view is opened if not already running.
|
||||
|
||||
#### Scenario: Auto-start on view open
|
||||
- **WHEN** the user opens the OpenCode view
|
||||
- **AND** the server is in `stopped` state
|
||||
- **THEN** the plugin initiates server start
|
||||
|
||||
### Requirement: Settings Configuration
|
||||
The plugin SHALL provide configurable settings for server port, hostname, executable path, project directory, and auto-start behavior.
|
||||
|
||||
#### Scenario: Settings persistence
|
||||
- **WHEN** the user modifies settings
|
||||
- **THEN** changes are persisted to plugin data
|
||||
- **AND** the process manager is updated with new settings
|
||||
|
||||
### Requirement: Project Directory Validation
|
||||
The plugin SHALL validate the project directory setting and support tilde expansion.
|
||||
|
||||
#### Scenario: Valid absolute path
|
||||
- **WHEN** the user enters an absolute path or path starting with ~
|
||||
- **AND** the path exists and is a directory
|
||||
- **THEN** the setting is saved with the expanded path
|
||||
|
||||
#### Scenario: Invalid path rejection
|
||||
- **WHEN** the user enters a relative path or non-existent path
|
||||
- **THEN** a notice is displayed explaining the error
|
||||
- **AND** the setting is not saved
|
||||
|
||||
### Requirement: Project Directory Auto-Restart
|
||||
The plugin SHALL restart the server when the project directory setting changes while running.
|
||||
|
||||
#### Scenario: Restart on directory change
|
||||
- **WHEN** the user changes the project directory
|
||||
- **AND** the server is currently running
|
||||
- **THEN** the plugin stops and restarts the server with the new directory
|
||||
|
||||
### Requirement: Commands Registration
|
||||
The plugin SHALL register commands for toggling the view and controlling the server.
|
||||
|
||||
#### Scenario: Toggle command
|
||||
- **WHEN** the user runs "Toggle OpenCode panel" command or presses Mod+Shift+O
|
||||
- **THEN** the view opens if closed, or closes if open
|
||||
|
||||
#### Scenario: Start and stop commands
|
||||
- **WHEN** the user runs "Start OpenCode server" command
|
||||
- **THEN** the server starts
|
||||
- **WHEN** the user runs "Stop OpenCode server" command
|
||||
- **THEN** the server stops
|
||||
|
||||
### Requirement: Ribbon Icon
|
||||
The plugin SHALL add a ribbon icon that activates the OpenCode view.
|
||||
|
||||
#### Scenario: Ribbon icon click
|
||||
- **WHEN** the user clicks the OpenCode ribbon icon
|
||||
- **THEN** the OpenCode view is activated in the right sidebar
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
## 1. Documentation
|
||||
- [x] 1.1 Create proposal.md
|
||||
- [x] 1.2 Create design.md with architectural decisions
|
||||
- [x] 1.3 Create specs/001-mvp-opencode-embed/spec.md with requirements and scenarios
|
||||
- [x] 1.4 Validate with `openspec validate document-mvp-capabilities --strict`
|
||||
Reference in New Issue
Block a user