7.3 KiB
ADDED Requirements
Requirement: Workspace Context Collection
The plugin SHALL collect the file paths of all currently open markdown notes in the Obsidian workspace.
Scenario: Collect open note paths
- WHEN the plugin needs to gather workspace context
- THEN it retrieves all leaves of type "markdown" from the workspace
- AND extracts the file path from each leaf's view
- AND deduplicates paths (same file may be open in multiple panes)
Requirement: Selected Text Collection
The plugin SHALL collect the currently selected text from the active editor, if any selection exists.
Scenario: Collect selected text with source
- WHEN the plugin needs to gather workspace context
- AND text is selected in the active editor
- THEN it retrieves the selected text content
- AND identifies the source file path of the selection
Scenario: No selection present
- WHEN the plugin needs to gather workspace context
- AND no text is selected in the active editor
- THEN the selected text portion of the context is omitted
Scenario: Selection truncation
- WHEN the selected text exceeds
maxSelectionLengthcharacters - THEN the selection is truncated to the configured limit
- AND an indicator is added showing truncation occurred
Requirement: Context Injection to OpenCode
The plugin SHALL inject the workspace context (open notes and selected text) into the OpenCode session currently displayed in the embedded iframe.
Scenario: Inject context on workspace change
- WHEN the user opens, closes, or switches between notes
- AND the setting "Inject workspace context" is enabled
- AND the OpenCode server is running
- AND a
sessionIDcan be resolved from the current iframe URL - THEN the plugin sends the workspace context to that session
- AND the context is injected using
session.prompt({ noReply: true })(no AI response triggered)
Scenario: Inject context on selection change
- WHEN the user changes their text selection in an editor
- AND the setting is enabled
- AND the OpenCode server is running
- THEN the plugin updates the workspace context (debounced)
Scenario: Initial context injection
- WHEN the OpenCode server transitions to running state
- AND the setting is enabled
- AND a tracked session exists (created on first open)
- THEN the plugin injects the current workspace context
Requirement: Context Replacement (Non-Destructive)
The plugin SHALL replace previous context injections rather than accumulating them.
Scenario: Update previous context part
- WHEN the plugin injects new context
- AND a previous context part exists for the session
- THEN the plugin updates the previous context part in-place to match the new context
- AND no new context message is added to the session history
Scenario: Ignore previous context part and re-inject
- WHEN in-place update is not available
- AND a previous context part exists for the session
- THEN the plugin marks the previous context part as
ignored: true - AND injects new context with
noReply: true - AND stores the new message/part IDs for future updates
Scenario: Replacement failure handling
- WHEN a previous context part cannot be updated or ignored (already removed, invalid IDs)
- THEN the plugin continues with fresh context injection
- AND logs the error to console for debugging
Scenario: Never revert
- WHEN updating context
- THEN the plugin MUST NOT call
session.revert()as part of this feature
Requirement: Debounced Context Updates
The plugin SHALL debounce workspace change events to prevent excessive API calls.
Requirement: Session Tracking and URL Persistence
The plugin SHALL create and track an OpenCode session and preserve the iframe URL for the duration of the Obsidian process.
Scenario: Create session on first view open
- WHEN the OpenCode view is opened for the first time in the current Obsidian run
- AND the OpenCode server is running
- THEN the plugin creates a new OpenCode session
- AND updates the iframe URL to the session route
- AND stores that URL for later restores
Scenario: Restore last URL on reopen
- WHEN the OpenCode view is closed and reopened
- AND a previous iframe URL was stored in memory
- THEN the iframe is loaded with the stored URL
Scenario: Adopt user-changed session
- WHEN the user navigates to a different session within the iframe UI
- AND the plugin is about to inject context
- THEN the plugin reads the iframe
srcURL - AND resolves the session ID from that URL
- AND updates the tracked session and stored URL to match
Scenario: No session route
- WHEN the iframe URL does not contain a session route
- AND the plugin is about to inject context
- THEN the plugin does not inject any context
Scenario: Invalidate stored URL when base changes
- WHEN hostname, port, or project directory changes
- THEN the plugin clears the stored URL and tracked session
- AND a new session is created on the next first open
Scenario: Rapid file switching
- WHEN the user rapidly opens or closes multiple files
- THEN the plugin waits 2 seconds after the last change before sending context update
- AND only one API call is made for the batch of changes
Scenario: Rapid selection changes
- WHEN the user is actively selecting text (dragging)
- THEN the plugin waits 2 seconds after selection stabilizes before updating context
Requirement: Context Injection Settings
The plugin SHALL provide settings to control workspace context injection behavior.
Scenario: Enable/disable toggle
- WHEN the user disables "Inject workspace context"
- THEN the plugin does not register workspace event listeners
- AND no context is injected into OpenCode sessions
Scenario: Enabled by default
- WHEN the plugin is installed fresh
- THEN the "Inject workspace context" setting defaults to enabled
Scenario: Limit number of notes
- WHEN more than
maxNotesInContextnotes are open - THEN the plugin includes only the first N paths
- AND the default limit is 20 notes
Scenario: Limit selection length
- WHEN the selected text exceeds
maxSelectionLengthcharacters - THEN the plugin truncates the selection
- AND the default limit is 2000 characters
Requirement: Context Format
The plugin SHALL format the context as a system reminder containing file paths and optional selected text.
Scenario: Context message format with selection
- WHEN context is injected
- AND text is selected
- THEN the message is wrapped in
<system-reminder>tags - AND includes a header "Currently open notes in Obsidian:"
- AND lists each file path as a bullet point
- AND includes a "Selected text (from ):" section
- AND wraps the selected text in triple quotes
Scenario: Context message format without selection
- WHEN context is injected
- AND no text is selected
- THEN the message contains only the open notes section
- AND the selected text section is omitted
Scenario: Empty context
- WHEN no markdown files are open
- AND no text is selected
- THEN no context message is injected
- AND any previous injected context part is marked as
ignored: true