feat(settings): unify prompt editors (#2855)
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
# ADR-2026-08-20-settings-prompt-editor-provider-ownership: Settings Prompt Editors Own Monaco Completion Providers
|
||||
|
||||
**Status:** accepted
|
||||
**Date:** 2026-08-20
|
||||
**Area:** frontend
|
||||
|
||||
## Context
|
||||
|
||||
Monaco registers completion providers by language, but Settings can mount more
|
||||
than one prompt editor with different placeholder and saved-prompt catalogs.
|
||||
The previous language-wide singleton allowed the last mounted editor to replace
|
||||
the provider used by another open editor. Saved-prompt catalogs also load
|
||||
asynchronously, so registration must handle data arriving before or after
|
||||
Monaco mounts.
|
||||
|
||||
## Decision
|
||||
|
||||
Each `ScriptEditor` instance owns its primary and saved-prompt completion
|
||||
registrations. The registrations wrap their providers with a model-identity
|
||||
check and return no suggestions for another model. Provider disposables are
|
||||
updated and cleaned up per instance. The shared `SettingsPromptEditor` enables
|
||||
saved-prompt registration only for fields whose runtime expands `@name`
|
||||
references, and its completion widget is layered above the mobile Settings Save
|
||||
bar.
|
||||
|
||||
## Consequences
|
||||
|
||||
Open editors no longer share mutable provider state, so placeholder and saved-
|
||||
prompt suggestions remain local to the editor that requested them. Each editor
|
||||
performs its own registration and disposal work, and provider changes replace
|
||||
only that editor's registration. The shared prompt editor must retain the
|
||||
latest registration callback because prompt data may load before Monaco's
|
||||
one-shot mount callback.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
- Keep one language-wide provider per slot. This is simpler, but it reintroduces
|
||||
cross-editor catalog leakage and makes unmount order observable.
|
||||
- Keep a global provider and route requests through the active editor. This
|
||||
requires focus and model bookkeeping outside Monaco and is fragile when
|
||||
several editors are mounted or a completion request races a focus change.
|
||||
- Give every editor a distinct Monaco language identifier. This avoids some
|
||||
collisions, but multiplies language registrations and does not improve the
|
||||
provider lifecycle or async catalog handling.
|
||||
@@ -179,5 +179,6 @@ Read individual ADRs for full context. Create new ones via `/record decision` or
|
||||
| 2026-08-17-separate-task-activity-from-summary-freshness | [Separate Task Activity From Summary Freshness](2026-08-17-separate-task-activity-from-summary-freshness.md) | accepted | backend, frontend, protocol | 2026-08-17 |
|
||||
| 2026-08-17-release-pr-ruleset-bypass | [Give Stable Release PRs an Administrator Token Bypass](2026-08-17-release-pr-ruleset-bypass.md) | accepted | infra, workflow, security | 2026-08-17 |
|
||||
| 2026-08-18-never-started-agent-stall-terminal | [Treat Never-Started Agent Stalls as Terminal](2026-08-18-never-started-agent-stall-terminal.md) | accepted | backend, frontend, protocol | 2026-08-18 |
|
||||
| 2026-08-20-settings-prompt-editor-provider-ownership | [Settings Prompt Editors Own Monaco Completion Providers](2026-08-20-settings-prompt-editor-provider-ownership.md) | accepted | frontend | 2026-08-20 |
|
||||
| 2026-08-14-kandev-native-agent-rich-output | [Keep Agent Rich Output Host Native](2026-08-14-kandev-native-agent-rich-output.md) | accepted | backend, frontend, protocol, security | 2026-08-14 |
|
||||
| 2026-08-20-acp-client-non-underscore-extension-methods | [Route Non-Underscore Inbound Client Methods to the Extension Handler](2026-08-20-acp-client-non-underscore-extension-methods.md) | accepted | backend, protocol | 2026-08-20 |
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
spec: docs/specs/ui/settings-prompt-editor.md
|
||||
created: 2026-08-20
|
||||
status: done
|
||||
---
|
||||
|
||||
# Fix Plan: Settings Prompt Completion Regressions
|
||||
|
||||
## Overview
|
||||
|
||||
Correct completion metadata and loading races in the shared Monaco prompt
|
||||
editor. Placeholder completion must account for an unfinished name suffix
|
||||
before existing closing braces. Saved-prompt completion must expose the prompt
|
||||
name as its filtering value, keep the `@name` display label, and continue
|
||||
filtering across spaces in valid multi-word names. Multiple mounted editors
|
||||
must share one in-flight prompt request. The repair remains frontend-only and
|
||||
preserves the existing plain-text and save contracts.
|
||||
|
||||
## Confirmed Root Cause
|
||||
|
||||
- For `{{|}}`, the placeholder provider uses the cursor-only replacement range
|
||||
and always inserts `${key}}}`. The existing `}}` remains after the cursor,
|
||||
so selection produces `{{key}}}}`. The same range bug leaves a suffix such
|
||||
as `_prompt}}` behind when the cursor is inside `{{ta_prompt}}`.
|
||||
- For `@c`, the saved-prompt provider uses an `@name` label but its
|
||||
replacement range starts after `@`. Monaco filters the typed name prefix
|
||||
against the label when `filterText` is absent, so a valid prefix such as
|
||||
`c` does not match the label's first character, `@`.
|
||||
- The `[\w-]*` mention-prefix pattern stops at a space. A valid prompt named
|
||||
`Daily Summary` therefore loses its mention start when the user types
|
||||
`@Daily `.
|
||||
- Every mounted editor can observe `loading=false` in the same render and
|
||||
start its own request. A late failure can then overwrite the shared prompt
|
||||
list with an empty result.
|
||||
|
||||
## Frontend
|
||||
|
||||
### Completion provider behavior
|
||||
|
||||
Update `apps/web/components/settings/profile-edit/script-editor-completions.ts`:
|
||||
|
||||
- Make placeholder completion insert only the placeholder name when the text
|
||||
after the cursor contains the remaining placeholder name followed by `}}`.
|
||||
Extend the replacement range across that suffix.
|
||||
- Keep the existing insertion of one closing pair for an unfinished token.
|
||||
- Set each saved-prompt completion item's `filterText` to `prompt.name` while
|
||||
retaining the `@${prompt.name}` display label and the existing insertion
|
||||
value.
|
||||
- Find the whitespace-bounded mention start directly, use the complete
|
||||
substring after `@` as the active prefix, and retrigger completion after a
|
||||
space.
|
||||
- Share an in-flight `listPrompts` request across mounted hook instances while
|
||||
applying the settled result to each subscribing store consumer.
|
||||
|
||||
No component API, backend contract, persistence format, or mobile composition
|
||||
changes are required.
|
||||
|
||||
## Tests
|
||||
|
||||
- **What:** Placeholder selection does not duplicate an existing closing pair
|
||||
and still closes an unfinished token.
|
||||
**File:** `apps/web/components/settings/profile-edit/script-editor-completions.test.ts`.
|
||||
**How:** Call the provider with `{{}}` and the cursor between the pairs, then
|
||||
with `{{` at the end, and assert the exact `insertText` values.
|
||||
- **What:** Saved-prompt suggestions remain filterable by the typed name.
|
||||
**File:** `apps/web/components/settings/profile-edit/script-editor-completions.test.ts`.
|
||||
**How:** Assert each suggestion exposes the prompt name as `filterText` while
|
||||
its label remains prefixed with `@`.
|
||||
|
||||
## E2E Tests
|
||||
|
||||
- **Scenario:** **GIVEN** a saved prompt named `changes-walkthrough`, **WHEN**
|
||||
the user types `@c` in a shared Settings prompt editor, **THEN** the matching
|
||||
suggestion remains visible and can be selected.
|
||||
**Files:** `apps/web/e2e/tests/workflow/workflow-step-autocomplete.spec.ts`
|
||||
and the existing GitHub quick-action autocomplete coverage if needed.
|
||||
- **Scenario:** **GIVEN** the editor contains `{{}}` with the cursor inside,
|
||||
**WHEN** the user selects a placeholder, **THEN** the persisted draft contains
|
||||
one balanced token rather than duplicated closing braces.
|
||||
**Files:** `apps/web/e2e/tests/integrations/github-quick-action-prompt-autocomplete.spec.ts`
|
||||
and its mobile counterpart.
|
||||
|
||||
## Review fixup scope
|
||||
|
||||
The review follow-up extends the original repair with these cases:
|
||||
|
||||
- A partially typed `{{ta_prompt}}` replaces the remaining name suffix before
|
||||
existing `}}` and inserts only the selected key.
|
||||
- A whitespace-bounded mention such as `@Daily ` keeps a valid multi-word
|
||||
prompt name available. Space retriggers use the full text after `@` as the
|
||||
active replacement range.
|
||||
- Two mounted prompt editors share one in-flight `listPrompts` request, and
|
||||
each consumer receives the settled result.
|
||||
- Desktop and mobile fixtures use unique prompt names. The GitHub quick-action
|
||||
fixture resets action presets in `finally` after it saves a draft.
|
||||
|
||||
The focused provider suite and hook suite cover the first three cases. The
|
||||
existing desktop and mobile completion scenarios cover browser filtering and
|
||||
cleanup.
|
||||
|
||||
## Verification Results
|
||||
|
||||
- RED: `pnpm --filter @kandev/web test -- --run components/settings/profile-edit/script-editor-completions.test.ts` failed as expected with 2 regression failures: duplicated placeholder braces and missing saved-prompt `filterText`.
|
||||
- GREEN: the same focused provider suite passed 10/10 tests.
|
||||
- `make build-backend build-web-e2e build-e2e-plugin-package` completed successfully; only existing build warnings were emitted.
|
||||
- `pnpm e2e:raw --project=chromium e2e/tests/workflow/workflow-step-autocomplete.spec.ts e2e/tests/integrations/github-quick-action-prompt-autocomplete.spec.ts` passed 5/5.
|
||||
- `pnpm e2e:raw --project=mobile-chrome e2e/tests/integrations/mobile-github-quick-action-prompt-autocomplete.spec.ts` passed 1/1.
|
||||
- `pnpm run typecheck` passed.
|
||||
- Focused ESLint passed for the changed completion source and unit test.
|
||||
- `git diff --check` passed. No temporary source or browser fixture files remain.
|
||||
- Review fixup RED: provider regressions failed for the partial placeholder and
|
||||
multi-word mention, while the two-editor hook regression observed two prompt
|
||||
requests.
|
||||
- Review fixup GREEN: focused provider, hook, shared-editor, and Monaco suites
|
||||
passed 21 tests; web typecheck and focused ESLint passed.
|
||||
- Review fixup GREEN: `make build-backend build-web-e2e
|
||||
build-e2e-plugin-package` passed; Chromium coverage passed 5/5 and mobile
|
||||
coverage passed 1/1. The GitHub test completed its prompt and preset cleanup.
|
||||
- Review fixup GREEN: `git diff --check` passed.
|
||||
|
||||
## Implementation Waves And Parallel Candidates
|
||||
|
||||
Wave 1:
|
||||
|
||||
- [x] [task-01-completion-provider-regressions](task-01-completion-provider-regressions.md)
|
||||
|
||||
The task is sequential because it changes one shared provider and its unit and
|
||||
browser regression coverage.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- Changes to saved-prompt expansion, placeholder interpolation, or backend APIs.
|
||||
- Changes to Monaco theme, layout, mobile composition, or completion contents.
|
||||
- New public documentation, because this repair restores the behavior already
|
||||
promised by the shipped prompt-editor spec.
|
||||
|
||||
## Risks
|
||||
|
||||
- Completion insertion must distinguish a cursor before existing `}}` from an
|
||||
unfinished token without changing replacement ranges for typed names.
|
||||
- `filterText` must affect Monaco's filtering only; the visible `@name` label
|
||||
and inserted `name` value must remain unchanged.
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
---
|
||||
id: "01-completion-provider-regressions"
|
||||
title: "Fix prompt completion insertion and filtering"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/ui/settings-prompt-editor.md"
|
||||
---
|
||||
|
||||
# Task 01: Fix prompt completion insertion and filtering
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Selecting a placeholder at `{{|}}` produces exactly `{{key}}` and does not
|
||||
duplicate the existing closing braces.
|
||||
- Selecting a placeholder after `ta` in `{{ta_prompt}}` replaces the full
|
||||
partial token name and produces exactly `{{key}}`.
|
||||
- Selecting a placeholder at an unfinished `{{|` still produces exactly
|
||||
`{{key}}`.
|
||||
- Saved-prompt completion labels remain `@name`, while typing a name prefix
|
||||
keeps matching suggestions available and selection still inserts `@name`.
|
||||
- Saved prompts with spaces remain filterable after typing a prefix such as
|
||||
`@Daily `.
|
||||
- Two mounted prompt editors share one in-flight saved-prompt request.
|
||||
- Desktop and mobile shared prompt-editor flows retain the same behavior.
|
||||
|
||||
## Verification
|
||||
|
||||
Follow TDD. Add the provider regression tests first and confirm they fail for
|
||||
the current insertion metadata and missing `filterText`.
|
||||
|
||||
From `apps`:
|
||||
|
||||
```bash
|
||||
pnpm --filter @kandev/web test -- --run components/settings/profile-edit/script-editor-completions.test.ts
|
||||
pnpm --filter @kandev/web test -- --run hooks/domains/settings/use-custom-prompts.test.tsx
|
||||
```
|
||||
|
||||
After the unit fix, rebuild the production web/backend artifacts required by
|
||||
the E2E fixture and run the focused desktop and mobile scenarios:
|
||||
|
||||
```bash
|
||||
make build-backend build-web-e2e build-e2e-plugin-package
|
||||
cd apps/web && pnpm e2e:raw --project=chromium e2e/tests/workflow/workflow-step-autocomplete.spec.ts e2e/tests/integrations/github-quick-action-prompt-autocomplete.spec.ts
|
||||
cd apps/web && pnpm e2e:raw --project=mobile-chrome e2e/tests/integrations/mobile-github-quick-action-prompt-autocomplete.spec.ts
|
||||
```
|
||||
|
||||
Also run `cd apps/web && pnpm run typecheck`, the focused ESLint command for
|
||||
the changed files, and `git diff --check` before marking the task done.
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/components/settings/profile-edit/script-editor-completions.ts`
|
||||
- `apps/web/components/settings/profile-edit/script-editor-completions.test.ts`
|
||||
- `apps/web/e2e/tests/workflow/workflow-step-autocomplete.spec.ts`
|
||||
- `apps/web/e2e/tests/integrations/github-quick-action-prompt-autocomplete.spec.ts`
|
||||
- `apps/web/e2e/tests/integrations/mobile-github-quick-action-prompt-autocomplete.spec.ts`
|
||||
- `docs/specs/ui/settings-prompt-editor.md`
|
||||
- `docs/plans/settings-prompt-completion-regressions/plan.md`
|
||||
- `docs/plans/settings-prompt-completion-regressions/task-01-completion-provider-regressions.md`
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential. The provider and all regression tests share the same completion
|
||||
contract.
|
||||
|
||||
## Inputs
|
||||
|
||||
- The repaired behavior and scenarios in `docs/specs/ui/settings-prompt-editor.md`.
|
||||
- The confirmed root causes and exact source files in `plan.md`.
|
||||
- Existing Monaco provider tests and the shared prompt-editor E2E helpers.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the RED failures, implementation result, files changed, exact commands
|
||||
and outcomes, any browser screenshot or cleanup evidence, and synchronized task
|
||||
and plan status.
|
||||
|
||||
## Review fixup scope
|
||||
|
||||
- Cover the partial `{{ta_prompt}}` replacement range and multi-word `@Daily `
|
||||
filtering contract.
|
||||
- Deduplicate prompt loading for two mounted editors and deliver one settled
|
||||
result to both consumers.
|
||||
- Use unique prompt fixtures and restore GitHub action presets in `finally`.
|
||||
|
||||
## Results
|
||||
|
||||
- RED: `pnpm --filter @kandev/web test -- --run components/settings/profile-edit/script-editor-completions.test.ts` failed with the expected two assertions: `filterText` was undefined and `{{}}` completion returned `task_prompt}}`.
|
||||
- `apps/web/components/settings/profile-edit/script-editor-completions.ts` now preserves an existing trailing `}}` and sets saved-prompt `filterText` to the prompt name.
|
||||
- Added unit regressions for balanced and unfinished placeholder tokens and `@` name filtering.
|
||||
- Updated desktop workflow E2E coverage to complete inside `{{}}` and type `@c`; prompt fixtures use unique `c-` names to avoid seeded-data collisions.
|
||||
- Updated the mobile GitHub quick-action E2E flow to type `@c` and verify touch filtering.
|
||||
- GREEN: focused provider suite passed 10/10.
|
||||
- `make build-backend build-web-e2e build-e2e-plugin-package` completed successfully.
|
||||
- Desktop Playwright command passed 5/5; mobile Playwright command passed 1/1.
|
||||
- `pnpm run typecheck`, focused ESLint, and `git diff --check` passed.
|
||||
- No temporary browser artifacts were added; generated E2E failure artifacts were produced only under the existing ignored test-results directory.
|
||||
- Review fixup GREEN: the partial placeholder, multi-word mention, and
|
||||
two-editor request regressions passed. Chromium passed 5/5 and mobile passed
|
||||
1/1 after the fixture cleanup changes.
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
spec: docs/specs/ui/settings-prompt-editor.md
|
||||
created: 2026-08-20
|
||||
status: done
|
||||
---
|
||||
|
||||
# Implementation Plan: Settings Prompt Editor
|
||||
|
||||
## Overview
|
||||
|
||||
Add a prompt-specific Settings editor above the existing Monaco `ScriptEditor`. First, scope completion providers to each Monaco model.
|
||||
|
||||
Then migrate all prompt-authoring settings fields to the shared editor.
|
||||
|
||||
The change preserves all stored strings and current save APIs. It adds frontend behavior, focused tests, desktop and mobile E2E coverage, and public documentation.
|
||||
|
||||
## Audit
|
||||
|
||||
The current prompt editors have four different states:
|
||||
|
||||
- Workflow step and GitHub review-watch prompts support placeholders and saved-prompt references.
|
||||
- GitHub, Jira, and Azure DevOps quick actions support placeholders only.
|
||||
- Several watcher, workflow, automation, and utility prompts use Monaco with only part of the available completion contract.
|
||||
- GitLab quick actions, GitLab watches, Azure DevOps watches, workflow prompts, and custom prompts use plain textareas.
|
||||
|
||||
`ScriptEditor` registers one completion provider per language and slot. The last mounted editor can replace the provider for another mounted editor.
|
||||
|
||||
## Backend
|
||||
|
||||
No backend, database, API, or interpolation change is required.
|
||||
|
||||
Task descriptions already resolve saved-prompt references during workflow prompt assembly. Utility prompts use a separate sessionless template engine and do not resolve these references.
|
||||
|
||||
## Frontend
|
||||
|
||||
### Shared prompt editor
|
||||
|
||||
Create `apps/web/components/settings/settings-prompt-editor.tsx` with a controlled plain-text contract:
|
||||
|
||||
- `value` and `onChange`
|
||||
- `placeholders?: ScriptPlaceholder[]`
|
||||
- `promptReferences?: boolean`
|
||||
- `excludedPromptIds?: string[]`
|
||||
- `language?: "markdown" | "plaintext"`
|
||||
- `height`, `minLines`, `readOnly`, `ariaLabel`, `testId`, and dirty-state props
|
||||
- optional supplemental help content
|
||||
|
||||
The component reads saved prompts through `useCustomPrompts` when prompt references are enabled. It filters excluded prompts before it passes them to `ScriptEditor`.
|
||||
|
||||
The component owns the border, completion hint, loading-safe prompt list, and content-based default height. Consumers keep field labels and context-specific placeholder descriptions.
|
||||
|
||||
Add localized completion hints to the `settings` catalogs. Use one hint for placeholders, one for prompt references, and one for both completion types.
|
||||
|
||||
### Monaco completion ownership
|
||||
|
||||
Update `apps/web/components/settings/profile-edit/script-editor.tsx`. Replace the language-wide singleton registrations with per-instance disposables.
|
||||
|
||||
Wrap each completion provider with a model identity check. A provider returns no items when Monaco calls it for a different model.
|
||||
|
||||
Dispose both providers when the editor unmounts. Re-register only the changed provider when placeholders or saved prompts change.
|
||||
|
||||
Expose stable accessibility and test attributes from `ScriptEditor`. Keep the existing script-editor consumers compatible.
|
||||
|
||||
### Quick actions
|
||||
|
||||
Use `SettingsPromptEditor` in these files:
|
||||
|
||||
- `apps/web/components/github/action-presets-section.tsx`
|
||||
- `apps/web/components/gitlab/action-presets-section.tsx`
|
||||
- `apps/web/components/jira/task-presets-section.tsx`
|
||||
- `apps/web/components/azure-devops/azure-devops-quick-actions.tsx`
|
||||
|
||||
Enable saved-prompt references for every quick action. Keep each provider's current `{{...}}` tokens.
|
||||
|
||||
Add GitLab `{{url}}` and `{{title}}` definitions. Keep the current quick-action data model and shared save contributor.
|
||||
|
||||
### Watch prompts
|
||||
|
||||
Use `SettingsPromptEditor` for GitHub, GitLab, Jira, Linear, Sentry, and Azure DevOps watch prompts. Enable saved-prompt references for all watch prompts.
|
||||
|
||||
Reuse existing placeholder definitions for GitHub, GitLab, Jira, Linear, and Sentry. Add typed Azure DevOps definitions for work-item and pull-request watch tokens.
|
||||
|
||||
Do not migrate provider query fields such as WIQL or JQL. These fields are not agent prompts.
|
||||
|
||||
### Other Settings prompts
|
||||
|
||||
Use `SettingsPromptEditor` for these settings fields:
|
||||
|
||||
- workflow-level prompts
|
||||
- workflow step prompts
|
||||
- automation instructions
|
||||
- custom prompt content
|
||||
- utility agent prompt templates
|
||||
|
||||
Enable saved-prompt references for workflow, automation, and custom prompt fields. Exclude the current custom prompt from its own completion list.
|
||||
|
||||
Disable saved-prompt references for utility prompts. Keep utility template variables enabled.
|
||||
|
||||
Update existing tests that assume a native textarea. Use the stable editor test ID and controlled-value assertions instead.
|
||||
|
||||
### Mobile design contract
|
||||
|
||||
- **Desktop outcome and mobile entry:** both viewports use the existing Settings routes and existing quick-action expansion control.
|
||||
- **Nearest mobile exemplars:** `mobile-github-integration-layout.spec.ts` and `mobile-workflow-settings.spec.ts` define the settings-page composition and overflow rules.
|
||||
- **Hierarchy:** the field label and completion hint remain above and below the inline editor. The route-level Save changes control remains primary.
|
||||
- **Presentation:** keep the editor inline. A drawer adds no value because prompt editing is the primary content of the expanded settings row.
|
||||
- **Scroll owner:** the Settings page remains the page scroll owner. Monaco owns vertical editor scroll after the content-height cap.
|
||||
- **Touch and geometry:** completion items support touch selection. The editor and suggestion widget must stay inside the phone viewport.
|
||||
- **Shared logic:** editor value, completion providers, dirty state, and save behavior are identical across viewports.
|
||||
|
||||
## Tests
|
||||
|
||||
- **What:** two mounted editors keep separate placeholder and saved-prompt providers.
|
||||
**Files:** `apps/web/components/settings/profile-edit/script-editor.test.tsx` and `script-editor-completions.test.ts`.
|
||||
**How:** use Monaco stubs with distinct models. Make sure that each provider rejects the other model and disposes on unmount.
|
||||
- **What:** the shared editor selects the correct completion modes and excludes the open custom prompt.
|
||||
**File:** `apps/web/components/settings/settings-prompt-editor.test.tsx`.
|
||||
**How:** mock `ScriptEditor` and `useCustomPrompts`. Assert props, dynamic prompt updates, dirty state, help text, and no prompt fetch error effect.
|
||||
- **What:** quick actions preserve drafts, placeholders, reset behavior, and save coordination while enabling prompt references.
|
||||
**Files:** focused tests beside the four quick-action sections.
|
||||
**How:** mock the shared editor and assert provider tokens, prompt-reference mode, and unchanged save payloads.
|
||||
- **What:** watcher and core Settings prompts use the shared editor with the correct completion contract.
|
||||
**Files:** existing watcher, workflow, and custom-prompt component tests. Add focused tests where no consumer test exists.
|
||||
**How:** assert component props and controlled updates. Keep persistence tests on the existing save coordinator.
|
||||
|
||||
## E2E Tests
|
||||
|
||||
- **Scenario:** **GIVEN** a saved prompt and GitHub quick action, **WHEN** the user selects `@name` and `{{title}}`, **THEN** both references persist after reload.
|
||||
**File:** `apps/web/e2e/tests/integrations/github-quick-action-prompt-autocomplete.spec.ts`.
|
||||
**What to verify:** both Monaco menus, keyboard or pointer selection, route save, reload persistence, and no automatic save on selection.
|
||||
- **Scenario:** **GIVEN** GitHub settings on a phone, **WHEN** the user selects both completion types, **THEN** the editor remains usable without page overflow.
|
||||
**File:** `apps/web/e2e/tests/integrations/mobile-github-quick-action-prompt-autocomplete.spec.ts`.
|
||||
**What to verify:** touch entry, suggestion selection, viewport containment, internal editor scrolling, and no document horizontal overflow.
|
||||
- **Scenario:** **GIVEN** a custom prompt editor, **WHEN** the user types `@`, **THEN** other prompts appear and the current prompt is absent.
|
||||
**File:** `apps/web/e2e/tests/settings/prompts-settings.spec.ts`.
|
||||
**What to verify:** create and edit paths, selection, save, and reload persistence.
|
||||
- **Scenario:** existing workflow step completion behavior remains available through the shared editor.
|
||||
**File:** `apps/web/e2e/tests/workflow/workflow-step-autocomplete.spec.ts`.
|
||||
**What to verify:** existing placeholder and saved-prompt cases remain green.
|
||||
|
||||
## Public documentation
|
||||
|
||||
Update these user guides:
|
||||
|
||||
- `docs/public/integrations.md` for quick-action and watch prompt completion.
|
||||
- `docs/public/workflow-tips.md` for workflow-level and step prompt completion.
|
||||
- `docs/public/developer-tools.md` for nested saved prompts and the utility prompt exception.
|
||||
|
||||
These pages remain how-to or explanation pages. No new navigation entry is required.
|
||||
|
||||
## Verification Results
|
||||
|
||||
- Focused unit/component suites pass for the shared editor, Monaco ownership, quick actions, watch prompts, and core Settings prompts.
|
||||
- `pnpm run typecheck` and `pnpm exec tsc --noEmit --incremental false` pass.
|
||||
- `pnpm run i18n:check` and `pnpm run i18n:ratchet` pass.
|
||||
- `node --test scripts/validate-public-docs.test.mjs` passes (61 tests), and `node scripts/validate-public-docs.mjs` validates 41 published pages.
|
||||
- Desktop and mobile managed Playwright runs pass for the new completion flows, custom-prompt exclusion, and existing workflow autocomplete.
|
||||
- `git diff --check` passes.
|
||||
|
||||
## Implementation Waves And Parallel Candidates
|
||||
|
||||
Wave 1:
|
||||
|
||||
- [x] [task-01-shared-editor](task-01-shared-editor.md)
|
||||
|
||||
Wave 2:
|
||||
|
||||
- [x] [task-02-quick-actions](task-02-quick-actions.md)
|
||||
|
||||
Wave 3:
|
||||
|
||||
- [x] [task-03-watch-prompts](task-03-watch-prompts.md)
|
||||
- [x] [task-04-core-settings-prompts](task-04-core-settings-prompts.md)
|
||||
|
||||
Wave 4:
|
||||
|
||||
- [x] [task-05-browser-coverage](task-05-browser-coverage.md)
|
||||
- [x] [task-06-public-documentation](task-06-public-documentation.md)
|
||||
|
||||
Tasks 03 and 04 are parallel-safe after Task 01 because their production files are disjoint.
|
||||
|
||||
Tasks 05 and 06 are parallel-safe after Tasks 02 through 04.
|
||||
|
||||
The primary conversation runs tasks sequentially by default. These labels do not authorize subagents.
|
||||
|
||||
## Risks
|
||||
|
||||
- Monaco completion providers are language-global. Model scoping must prevent cross-editor suggestions without breaking existing script completions.
|
||||
- Migrated native textareas change E2E input mechanics. Tests must focus Monaco's `native-edit-context` before they type.
|
||||
- GitLab and Azure DevOps watcher placeholders exist in backend interpolators. Frontend lists must match those exact tokens.
|
||||
- A saved-prompt suggestion is valid only when the runtime expands references. Utility prompts must not enable that completion mode.
|
||||
- Several settings routes can mount more than one editor. The component must avoid repeated prompt requests and provider churn.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: "01-shared-editor"
|
||||
title: "Build shared prompt editor"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/ui/settings-prompt-editor.md"
|
||||
---
|
||||
|
||||
# Task 01: Build shared prompt editor
|
||||
|
||||
## Acceptance
|
||||
|
||||
- `SettingsPromptEditor` provides controlled plain text, configured placeholders, optional saved-prompt references, exclusions, accessibility, dirty state, and localized hints.
|
||||
- Two mounted Monaco editors return completion items only for their own model.
|
||||
- Provider updates and unmounts dispose the correct Monaco registrations without changing existing script-editor behavior.
|
||||
|
||||
## Verification
|
||||
|
||||
Follow TDD. Add the model-isolation and shared-component tests first. Make sure that they fail against the language-wide provider ownership.
|
||||
|
||||
```bash
|
||||
cd apps && pnpm install --frozen-lockfile && pnpm --filter @kandev/web test -- --run components/settings/settings-prompt-editor.test.tsx components/settings/profile-edit/script-editor.test.tsx components/settings/profile-edit/script-editor-completions.test.ts && cd web && pnpm run typecheck && pnpm run i18n:check && pnpm run i18n:ratchet && pnpm exec eslint components/settings/settings-prompt-editor.tsx components/settings/settings-prompt-editor.test.tsx components/settings/profile-edit/script-editor.tsx components/settings/profile-edit/script-editor.test.tsx components/settings/profile-edit/script-editor-completions.ts components/settings/profile-edit/script-editor-completions.test.ts
|
||||
```
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/components/settings/settings-prompt-editor.tsx`
|
||||
- `apps/web/components/settings/settings-prompt-editor.test.tsx`
|
||||
- `apps/web/components/settings/profile-edit/script-editor.tsx`
|
||||
- `apps/web/components/settings/profile-edit/script-editor.test.tsx`
|
||||
- `apps/web/components/settings/profile-edit/script-editor-completions.ts`
|
||||
- `apps/web/components/settings/profile-edit/script-editor-completions.test.ts`
|
||||
- `apps/web/src/locales/en/settings.json`
|
||||
- `apps/web/src/locales/pt-pt/settings.json`
|
||||
- `apps/web/src/locales/zh-cn/settings.json`
|
||||
- `apps/web/src/locales/zh-hk/settings.json`
|
||||
- `apps/web/src/locales/zh-tw/settings.json`
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential. All later tasks depend on this component and its provider ownership contract.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec: `What`, `Failure modes`, and the model-isolation scenarios.
|
||||
- Plan: `Shared prompt editor`, `Monaco completion ownership`, and `Risks`.
|
||||
- Existing patterns: `ScriptEditor`, `useCustomPrompts`, and `script-editor-completions.test.ts`.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the RED error, final API, model-isolation method, files changed, exact command results, blockers, risks, and synchronized task and plan status.
|
||||
|
||||
## Results
|
||||
|
||||
- The initial browser run exposed a lifecycle race: saved prompts loaded before Monaco mounted, but the one-shot `onMount` callback still held an empty prompt list. The editor now keeps the latest registration callbacks in refs and registers per-model providers.
|
||||
- `ScriptEditor` owns one primary and one saved-prompt registration per mounted model, scopes both through `scopeCompletionProviderToModel`, and disposes them independently.
|
||||
- `SettingsPromptEditor` owns the controlled plain-text contract, localized completion hints, dirty attributes, stable editor attributes, prompt loading, and current-prompt exclusions.
|
||||
- Focused shared-editor/component/completion tests pass: 3 files, 13 tests; the regression test covers prompt data loading before Monaco mount.
|
||||
- `pnpm run typecheck` and `pnpm exec tsc --noEmit --incremental false` pass.
|
||||
- `pnpm run i18n:check` and `pnpm run i18n:ratchet` pass.
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: "02-quick-actions"
|
||||
title: "Migrate quick action prompts"
|
||||
status: done
|
||||
wave: 2
|
||||
depends_on: ["01-shared-editor"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/ui/settings-prompt-editor.md"
|
||||
---
|
||||
|
||||
# Task 02: Migrate quick action prompts
|
||||
|
||||
## Acceptance
|
||||
|
||||
- GitHub, GitLab, Jira, and Azure DevOps quick actions use `SettingsPromptEditor`.
|
||||
- Each provider offers its exact placeholders and saved-prompt references.
|
||||
- Draft, reset, dirty-state, validation, and shared Save changes behavior remain unchanged.
|
||||
|
||||
## Verification
|
||||
|
||||
Follow TDD. Add consumer assertions for completion modes and tokens before each migration.
|
||||
|
||||
```bash
|
||||
cd apps && pnpm install --frozen-lockfile && pnpm --filter @kandev/web test -- --run components/github/action-presets-section.test.tsx components/gitlab/action-presets-section.test.tsx components/jira/task-presets-section.test.tsx components/azure-devops/azure-devops-quick-actions.test.tsx && cd web && pnpm run i18n:ratchet && pnpm exec eslint components/github/action-presets-section.tsx components/github/action-presets-section.test.tsx components/gitlab/action-presets-section.tsx components/gitlab/action-presets-section.test.tsx components/jira/task-presets-section.tsx components/jira/task-presets-section.test.tsx components/azure-devops/azure-devops-quick-actions.tsx components/azure-devops/azure-devops-quick-actions.test.tsx
|
||||
```
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/components/github/action-presets-section.tsx`
|
||||
- `apps/web/components/github/action-presets-section.test.tsx`
|
||||
- `apps/web/components/gitlab/action-presets-section.tsx`
|
||||
- `apps/web/components/gitlab/action-presets-section.test.tsx`
|
||||
- `apps/web/components/jira/task-presets-section.tsx`
|
||||
- `apps/web/components/jira/task-presets-section.test.tsx`
|
||||
- `apps/web/components/azure-devops/azure-devops-quick-actions.tsx`
|
||||
- `apps/web/components/azure-devops/azure-devops-quick-actions.test.tsx`
|
||||
- GitLab locale catalogs only if new provider-specific placeholder descriptions are required
|
||||
|
||||
## Dependencies
|
||||
|
||||
Task 01.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential. All four consumers share the new component contract and quick-action E2E surface.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec: `Settings surfaces` and the GitHub quick-action scenarios.
|
||||
- Plan: `Quick actions` and `Shared prompt editor`.
|
||||
- Existing patterns: GitHub and Azure DevOps expandable prompt rows, Jira placeholder definitions, and each save contributor.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the RED error, provider token lists, save-payload evidence, files changed, exact command results, blockers, risks, and synchronized task and plan status.
|
||||
|
||||
## Results
|
||||
|
||||
- GitHub, GitLab, Jira, and Azure DevOps quick-action prompt fields use `SettingsPromptEditor` with saved-prompt references and their provider-specific placeholder maps.
|
||||
- GitLab now exposes localized `{{url}}` and `{{title}}` descriptions. Existing draft, reset, dirty-state, and save-contributor paths remain unchanged.
|
||||
- Focused consumer tests pass: 7 tests across 4 files.
|
||||
- `pnpm run i18n:ratchet` passes with no new hardcoded-copy violations.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: "03-watch-prompts"
|
||||
title: "Migrate watch prompts"
|
||||
status: done
|
||||
wave: 3
|
||||
depends_on: ["01-shared-editor"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/ui/settings-prompt-editor.md"
|
||||
---
|
||||
|
||||
# Task 03: Migrate watch prompts
|
||||
|
||||
## Acceptance
|
||||
|
||||
- GitHub, GitLab, Jira, Linear, Sentry, and Azure DevOps watch prompts use `SettingsPromptEditor`.
|
||||
- Each watch offers backend-supported placeholders and saved-prompt references.
|
||||
- Query fields, watcher validation, responsive dialog composition, and persistence remain unchanged.
|
||||
|
||||
## Verification
|
||||
|
||||
Follow TDD. Add focused assertions for GitLab and Azure DevOps token lists before the textarea migrations.
|
||||
|
||||
```bash
|
||||
cd apps && pnpm install --frozen-lockfile && pnpm --filter @kandev/web test -- --run components/github/review-watch-dialog.test.tsx components/gitlab/review-watch-dialog.test.tsx components/gitlab/issue-watch-dialog.test.tsx components/azure-devops/azure-devops-watch-settings.test.tsx components/sentry/sentry-issue-watch-dialog.test.tsx && cd web && pnpm run i18n:ratchet && pnpm exec eslint components/github/issue-watch-dialog.tsx components/github/review-watch-prompt-field.tsx components/gitlab/watch-dialog.tsx components/gitlab/review-watch-placeholders.ts components/gitlab/issue-watch-placeholders.ts components/jira/jira-issue-watch-dialog.tsx components/linear/linear-issue-watch-dialog.tsx components/sentry/sentry-issue-watch-dialog.tsx components/azure-devops/azure-devops-watch-settings.tsx
|
||||
```
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/components/github/issue-watch-dialog.tsx`
|
||||
- `apps/web/components/github/review-watch-prompt-field.tsx`
|
||||
- `apps/web/components/github/review-watch-dialog.test.tsx`
|
||||
- `apps/web/components/gitlab/watch-dialog.tsx`
|
||||
- `apps/web/components/gitlab/review-watch-placeholders.ts`
|
||||
- `apps/web/components/gitlab/issue-watch-placeholders.ts`
|
||||
- `apps/web/components/gitlab/review-watch-dialog.test.tsx`
|
||||
- `apps/web/components/gitlab/issue-watch-dialog.test.tsx`
|
||||
- `apps/web/components/jira/jira-issue-watch-dialog.tsx`
|
||||
- `apps/web/components/linear/linear-issue-watch-dialog.tsx`
|
||||
- `apps/web/components/sentry/sentry-issue-watch-dialog.tsx`
|
||||
- `apps/web/components/sentry/sentry-issue-watch-dialog.test.tsx`
|
||||
- `apps/web/components/azure-devops/azure-devops-watch-settings.tsx`
|
||||
- `apps/web/components/azure-devops/azure-devops-watch-placeholders.ts`
|
||||
- `apps/web/components/azure-devops/azure-devops-watch-settings.test.tsx`
|
||||
- Provider locale catalogs for new placeholder descriptions and completion help
|
||||
|
||||
## Dependencies
|
||||
|
||||
Task 01.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Parallel-safe with Task 04 after Task 01. The tasks use disjoint production and test files.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec: the watch-prompt row in `Settings surfaces` and the saved-prompt failure scenario.
|
||||
- Plan: `Watch prompts` and `Mobile design contract`.
|
||||
- Backend token authority: `source_gitlab.go`, `source_azuredevops.go`, and existing provider placeholder modules.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the RED error, exact token maps, responsive behavior, files changed, command results, blockers, risks, and synchronized task and plan status.
|
||||
|
||||
## Results
|
||||
|
||||
- GitHub, GitLab, Jira, Linear, Sentry, and Azure DevOps watch prompt fields use `SettingsPromptEditor`; query fields such as WIQL and JQL remain native query inputs.
|
||||
- GitLab placeholder descriptions are localized and Azure DevOps work-item and pull-request token maps are typed against the backend-supported fields.
|
||||
- Focused watch tests pass: 13 tests across 7 files, plus 5 Azure DevOps watch-settings tests.
|
||||
- No watcher save, validation, dialog, or persistence contract changed.
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
id: "04-core-settings-prompts"
|
||||
title: "Migrate core settings prompts"
|
||||
status: done
|
||||
wave: 3
|
||||
depends_on: ["01-shared-editor"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/ui/settings-prompt-editor.md"
|
||||
---
|
||||
|
||||
# Task 04: Migrate core settings prompts
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Workflow, automation, custom-prompt, and utility-agent fields use `SettingsPromptEditor`.
|
||||
- Workflow, automation, and custom prompts offer saved-prompt references. The open custom prompt is excluded.
|
||||
- Utility prompts offer only utility variables. Existing dirty, save, reset, read-only, and cross-tab behavior remains unchanged.
|
||||
|
||||
## Verification
|
||||
|
||||
Follow TDD. Update native-textarea assumptions only after the shared-editor assertions fail.
|
||||
|
||||
```bash
|
||||
cd apps && pnpm install --frozen-lockfile && pnpm --filter @kandev/web test -- --run components/settings/workflow-prompt-section.test.tsx components/settings/workflow-step-prompt-section.test.tsx components/settings/prompts-settings.test.tsx components/settings/utility-agent-dialog.test.tsx components/automations/prompt-section.test.tsx && cd web && pnpm run typecheck && pnpm run i18n:check && pnpm run i18n:ratchet && pnpm exec eslint components/settings/workflow-prompt-section.tsx components/settings/workflow-prompt-section.test.tsx components/settings/workflow-step-prompt-section.tsx components/settings/workflow-step-prompt-section.test.tsx components/settings/prompts-settings.tsx components/settings/prompts-settings.test.tsx components/settings/utility-agent-dialog.tsx components/settings/utility-agent-dialog.test.tsx components/automations/prompt-section.tsx components/automations/prompt-section.test.tsx
|
||||
```
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/components/settings/workflow-prompt-section.tsx`
|
||||
- `apps/web/components/settings/workflow-prompt-section.test.tsx`
|
||||
- `apps/web/components/settings/workflow-step-prompt-section.tsx`
|
||||
- `apps/web/components/settings/workflow-step-prompt-section.test.tsx`
|
||||
- `apps/web/components/settings/prompts-settings.tsx`
|
||||
- `apps/web/components/settings/prompts-settings.test.tsx`
|
||||
- `apps/web/components/settings/utility-agent-dialog.tsx`
|
||||
- `apps/web/components/settings/utility-agent-dialog.test.tsx`
|
||||
- `apps/web/components/automations/prompt-section.tsx`
|
||||
- `apps/web/components/automations/prompt-section.test.tsx`
|
||||
- Relevant locale catalogs when existing help text changes
|
||||
|
||||
## Dependencies
|
||||
|
||||
Task 01.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Parallel-safe with Task 03 after Task 01. The tasks use disjoint production and test files.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec: `Settings surfaces`, `Failure modes`, and the custom-prompt and utility scenarios.
|
||||
- Plan: `Other Settings prompts` and `Shared prompt editor`.
|
||||
- Existing patterns: workflow step prompt references, prompt save coordination, automation placeholders, and utility variables.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report the RED error, enabled completion modes, textarea-test migrations, files changed, command results, blockers, risks, and synchronized task and plan status.
|
||||
|
||||
## Results
|
||||
|
||||
- Workflow, workflow-step, automation, custom-prompt, and utility-agent fields use `SettingsPromptEditor`.
|
||||
- Workflow, automation, and custom prompts enable saved-prompt references; the open custom prompt is excluded. Utility prompts keep only their template-variable completion mode.
|
||||
- Focused core tests pass: 10 tests across 5 files.
|
||||
- Existing save, reset, read-only, dirty-state, and controlled-value behavior remains owned by each consumer.
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
id: "05-browser-coverage"
|
||||
title: "Add browser coverage"
|
||||
status: done
|
||||
wave: 4
|
||||
depends_on: ["02-quick-actions", "03-watch-prompts", "04-core-settings-prompts"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/ui/settings-prompt-editor.md"
|
||||
---
|
||||
|
||||
# Task 05: Add browser coverage
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Desktop E2E proves GitHub quick-action placeholder and saved-prompt completion, save coordination, and reload persistence.
|
||||
- Custom-prompt E2E proves that an editor offers other prompts but omits itself.
|
||||
- Mobile E2E proves the same GitHub completion value with touch selection and no viewport overflow.
|
||||
|
||||
## Verification
|
||||
|
||||
Follow E2E TDD. Run each new scenario before the production migration and record the missing-menu or textarea failure.
|
||||
|
||||
```bash
|
||||
cd apps && pnpm install --frozen-lockfile && cd web && pnpm e2e:run tests/integrations/github-quick-action-prompt-autocomplete.spec.ts tests/settings/prompts-settings.spec.ts tests/workflow/workflow-step-autocomplete.spec.ts && pnpm e2e:run --project mobile-chrome tests/integrations/mobile-github-quick-action-prompt-autocomplete.spec.ts
|
||||
```
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/web/e2e/helpers/settings-prompt-editor.ts`
|
||||
- `apps/web/e2e/tests/integrations/github-quick-action-prompt-autocomplete.spec.ts`
|
||||
- `apps/web/e2e/tests/integrations/mobile-github-quick-action-prompt-autocomplete.spec.ts`
|
||||
- `apps/web/e2e/tests/settings/prompts-settings.spec.ts`
|
||||
- `apps/web/e2e/tests/workflow/workflow-step-autocomplete.spec.ts`
|
||||
- `apps/web/e2e/tests/workflow/workflow-settings.spec.ts`
|
||||
- `apps/web/e2e/tests/workflow/workflow-duplication.spec.ts`
|
||||
- `apps/web/e2e/pages/workflow-settings-page.ts` only if a reusable editor locator belongs there
|
||||
|
||||
## Dependencies
|
||||
|
||||
Tasks 02, 03, and 04.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Parallel-safe with Task 06 after Tasks 02 through 04. This task owns only browser helpers and E2E files.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec: all Scenarios, with emphasis on quick actions, custom prompts, persistence, and phone behavior.
|
||||
- Plan: `E2E Tests` and `Mobile design contract`.
|
||||
- Existing patterns: `workflow-step-autocomplete.spec.ts`, `mobile-github-integration-layout.spec.ts`, and Monaco's `native-edit-context` focus target.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report RED failures, discovered test counts, desktop and mobile results, screenshots or traces, cleanup evidence, overflow measurements, blockers, risks, and synchronized task and plan status.
|
||||
|
||||
## Results
|
||||
|
||||
- The first desktop run failed because the saved-prompt provider was not registered when prompt data loaded before Monaco's one-shot mount callback. The fix added latest-callback registration and a focused regression test.
|
||||
- A mobile run then exposed Monaco's default `z-index: 40` competing with the mobile floating Save bar. The Settings prompt editor raises its suggestion widget to `z-index: 50`, allowing real touch selection.
|
||||
- Desktop GitHub quick-action completion and reload persistence pass: 1 test.
|
||||
- Mobile GitHub quick-action completion passes with touch editor entry, touch completion selection, viewport containment, and no document horizontal overflow: 1 test.
|
||||
- Existing workflow completion coverage passes: 3 tests. Custom-prompt exclusion and existing prompt settings coverage passes: 4 tests.
|
||||
- Fresh desktop and mobile PR asset captures were generated and visually inspected for the migrated GitHub quick-action editor.
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: "06-public-documentation"
|
||||
title: "Update public documentation"
|
||||
status: done
|
||||
wave: 4
|
||||
depends_on: ["02-quick-actions", "03-watch-prompts", "04-core-settings-prompts"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/ui/settings-prompt-editor.md"
|
||||
---
|
||||
|
||||
# Task 06: Update public documentation
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Integration documentation explains placeholder and saved-prompt completion for quick actions and watch prompts.
|
||||
- Workflow and developer-tool documentation explain the shared completion behavior and utility-agent exception.
|
||||
- Public documentation validation passes without a new navigation entry.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rg -n "quick actions|saved prompt|workflow prompt|utility" docs/public/integrations.md docs/public/workflow-tips.md docs/public/developer-tools.md && node --test scripts/validate-public-docs.test.mjs && node scripts/validate-public-docs.mjs
|
||||
```
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `docs/public/integrations.md`
|
||||
- `docs/public/workflow-tips.md`
|
||||
- `docs/public/developer-tools.md`
|
||||
|
||||
## Dependencies
|
||||
|
||||
Tasks 02, 03, and 04.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Parallel-safe with Task 05 after Tasks 02 through 04. This task owns only public documentation files.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec: `What`, `Settings surfaces`, and `Out of scope`.
|
||||
- Plan: `Public documentation`.
|
||||
- Current docs: existing saved-prompt, workflow, watcher, quick-action, and utility sections.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report pages changed, each page's primary Diátaxis type, exact command results, link impact, blockers, risks, and synchronized task and plan status.
|
||||
|
||||
## Results
|
||||
|
||||
- Updated `docs/public/integrations.md`, `docs/public/workflow-tips.md`, and `docs/public/developer-tools.md`.
|
||||
- The pages explain placeholder and saved-prompt completion, route-level save/reset behavior, nested references, current-prompt exclusion, and the utility-agent exception.
|
||||
- `node --test scripts/validate-public-docs.test.mjs` passes: 61 tests.
|
||||
- `node scripts/validate-public-docs.mjs` passes: 41 published pages validated.
|
||||
@@ -95,7 +95,7 @@ Open **Settings > Prompts** (`/settings/prompts`) to add, edit, or delete reusab
|
||||
|
||||
Type `@` in the task chat composer and select a prompt. The visible message keeps the `@name`; Kandev expands the prompt content into hidden system context for the agent. References are recognized only at the start of the text or after whitespace and must match the stored name. Prompt content can reference other saved prompts. Expansion stops at a depth of eight, skips cycles, and includes each prompt only once.
|
||||
|
||||
The same `@name` reference works in a workflow step's Prompt field and in a GitHub Review Watch's prompt; see [Saved prompt references in step prompts](workflow-tips.md#saved-prompt-references-in-step-prompts).
|
||||
The Settings prompt editor also offers the same `@name` completion when you edit a saved prompt, a workflow prompt, a workflow step, an automation instruction, a quick action, or a provider watch. The prompt being edited is excluded from its own completion list, so selecting a reference cannot create a direct self-reference by accident. The same `@name` reference works in a workflow step's Prompt field and in a GitHub Review Watch's prompt; see [Saved prompt references in step prompts](workflow-tips.md#saved-prompt-references-in-step-prompts).
|
||||
|
||||
Kandev seeds these built-ins:
|
||||
|
||||
@@ -111,6 +111,8 @@ A saved prompt is an instruction, not an authorization or policy boundary. Execu
|
||||
|
||||
</details>
|
||||
|
||||
Utility-agent prompt templates use a separate template engine. Type `{{` to select the utility variables shown by the editor, but do not use `@name` saved-prompt references there. Utility calls are sessionless and do not resolve saved prompts at runtime. Put reusable nested instructions in a saved prompt used by a task, workflow, automation, or integration prompt instead.
|
||||
|
||||
## Voice Mode
|
||||
|
||||
<details>
|
||||
|
||||
@@ -43,6 +43,14 @@ GitHub, GitLab, Azure DevOps, Jira, and Linear configuration are workspace-speci
|
||||
|
||||
Provider secrets saved by these forms use Kandev's encrypted secret store. The backend must still decrypt them to make API requests. Limit access to settings and the Kandev data directory, and use the narrowest provider scope that works.
|
||||
|
||||
### Author prompt fields
|
||||
|
||||
Quick actions and provider watch prompts use the same inline prompt editor. Type `{{` to open the provider's placeholder list, or type `@` after whitespace to find a [saved prompt](developer-tools.md#saved-prompts). Select an item to insert it into the draft. The menu shows the exact tokens supported by that provider and prompt type.
|
||||
|
||||
Common quick-action tokens are `{{url}}` and `{{title}}`. Jira quick actions also provide `{{key}}` and `{{description}}`. Watch prompts expose provider data such as `pr.*`, `issue.*`, `mr.*`, `work_item.*`, or `pull_request.*`, depending on the integration and watch type.
|
||||
|
||||
Selecting a completion changes the local draft only. Use the route-level **Save changes** action to persist it; **Reset** restores the provider defaults and **Cancel** or discard returns to the last saved draft. Saved-prompt references are expanded when the watch or action runs, so later edits to the referenced prompt apply without changing each integration setting.
|
||||
|
||||
### The Enabled switch
|
||||
|
||||
Jira, Linear, and Sentry pages show an **Enabled** switch. It is a browser-local preference, saved per installation in that browser and on by default. It controls some client-side entry points, availability checks, and configuration fetches; settings pages can still poll provider health. It does not delete backend configuration and does not stop a server-side watch. Pause/delete watches or remove the provider configuration when processing must stop.
|
||||
|
||||
@@ -146,6 +146,12 @@ promotion.
|
||||
|
||||
Pull candidates are selected by board position, then priority, queue time, creation time, and ID. A candidate that cannot be moved is skipped. Pulling runs for every limited step; a feeder is only needed for overflow created outside the destination step.
|
||||
|
||||
### Complete prompts while editing
|
||||
|
||||
Workflow and step prompt fields use the inline prompt editor. Type `@` after whitespace to select a saved prompt. In a step prompt, type `{{` to select `{{task_prompt}}` and other tokens supported by that step. The completion menu inserts the reference into the draft; it does not save the workflow. Use **Save changes** when the prompt is ready.
|
||||
|
||||
The workflow-level prompt supports saved-prompt references but does not expand step-only variables. `{{task_prompt}}` is available in a step prompt because it is replaced with the task description when that step runs.
|
||||
|
||||
## Events and actions
|
||||
|
||||
<details>
|
||||
|
||||
@@ -219,6 +219,7 @@ Subscription quota tracking and per-agent cheap-model profile routing.
|
||||
| [message-queue-send-now](ui/message-queue-send-now.md) | shipped |
|
||||
| [settings-manual-save](ui/settings-manual-save.md) | shipped |
|
||||
| [settings-discovery](ui/settings-discovery.md) | shipped |
|
||||
| [settings-prompt-editor](ui/settings-prompt-editor.md) | shipped |
|
||||
| [settings-typography](settings-typography/spec.md) | draft |
|
||||
| [executor-settings-card-spacing](ui/executor-settings-card-spacing.md) | shipped |
|
||||
| [quick-chat-elevation](ui/quick-chat-elevation.md) | building |
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
status: shipped
|
||||
created: 2026-08-20
|
||||
owner: Kandev
|
||||
---
|
||||
|
||||
# Settings Prompt Editor
|
||||
|
||||
## Why
|
||||
|
||||
Prompt fields in Settings use different editors and completion rules. Users cannot reliably discover placeholders or reference saved prompts across these fields.
|
||||
|
||||
## What
|
||||
|
||||
- Kandev provides one shared prompt editor for prompt-authoring fields in Settings.
|
||||
- The editor stores plain text and preserves each existing settings and save contract.
|
||||
- Typing `{{` shows only the placeholders that the current prompt context supports.
|
||||
- Selecting a placeholder inside an existing `{{...}}` pair replaces only the
|
||||
placeholder name and preserves the pair's closing braces. Selecting a
|
||||
placeholder after an unfinished `{{` adds exactly one closing pair.
|
||||
- Typing `@` shows saved prompts when the runtime resolves saved-prompt references for that field.
|
||||
- Typing a name prefix after `@` keeps saved prompts whose names match that
|
||||
prefix available for selection.
|
||||
- Prompt names may contain spaces. The active mention starts at a
|
||||
whitespace-bounded `@`, and the full text after it remains part of the
|
||||
filtering range while the user types.
|
||||
- A selected saved prompt inserts its `@name` reference. The editor does not inline or copy the saved prompt content.
|
||||
- The saved-prompt list updates when a prompt is added, edited, or removed.
|
||||
- A custom prompt can reference other saved prompts. Its editor does not suggest the prompt that is currently open.
|
||||
- Keyboard, pointer, and touch users can open, filter, and select completion items.
|
||||
- The editor keeps completion providers scoped to their editor model. One open editor cannot show completion items from another editor.
|
||||
- Each field keeps its existing dirty state, validation, reset behavior, save coordinator, and persisted text format.
|
||||
- Desktop and mobile settings routes provide the same completion functions.
|
||||
|
||||
### Settings surfaces
|
||||
|
||||
| Surface | Placeholder completion | Saved-prompt completion |
|
||||
|---|---|---|
|
||||
| GitHub, GitLab, Jira, and Azure DevOps quick actions | Provider placeholders | Yes |
|
||||
| GitHub, GitLab, Jira, Linear, Sentry, and Azure DevOps watch prompts | Provider placeholders when available | Yes |
|
||||
| Workflow prompt | Workflow placeholders | Yes |
|
||||
| Workflow step prompt | Step placeholders | Yes |
|
||||
| Automation instructions | Trigger placeholders | Yes |
|
||||
| Custom prompt content | None | Yes, excluding the open prompt |
|
||||
| Utility agent prompt | Utility template variables | No |
|
||||
|
||||
Utility prompts run through the sessionless utility template engine. That engine does not resolve saved-prompt references.
|
||||
|
||||
The shared editor does not replace script, query, JSON, or description fields. Those fields have different languages and completion contracts.
|
||||
|
||||
## Failure modes
|
||||
|
||||
- If saved prompts fail to load, placeholder completion continues to work. The `@` menu shows no saved prompts.
|
||||
- If a field has no configured placeholders, `{{` shows no placeholder items.
|
||||
- If Monaco loads slowly, the field shows the existing localized editor loading state. The controlled draft remains unchanged.
|
||||
- If two prompt editors are mounted together, each editor uses only its own placeholders and saved-prompt rules.
|
||||
- Concurrent mounted editors share one in-flight saved-prompt request. A
|
||||
failed request cannot replace a successful result from another editor.
|
||||
|
||||
## Persistence guarantees
|
||||
|
||||
This feature adds no new persistence. Each settings surface continues to store its current plain-text value through its current API.
|
||||
|
||||
Selecting a completion item changes only the local draft. The existing settings save action remains the persistence boundary.
|
||||
|
||||
## Scenarios
|
||||
|
||||
- **GIVEN** a saved prompt named `review-helper`, **WHEN** a user types `@rev` in a GitHub quick action, **THEN** the editor offers `@review-helper`.
|
||||
- **GIVEN** that suggestion, **WHEN** the user selects it, **THEN** the draft contains `@review-helper` and no save starts.
|
||||
- **GIVEN** a GitHub quick action editor, **WHEN** a user types `{{`, **THEN** the editor offers `{{url}}` and `{{title}}`.
|
||||
- **GIVEN** an editor contains `{{}}` with the cursor between the brace pairs,
|
||||
**WHEN** the user selects `{{task_prompt}}`, **THEN** the draft contains
|
||||
exactly `{{task_prompt}}` with no duplicated closing braces.
|
||||
- **GIVEN** an editor contains an unfinished `{{` token, **WHEN** the user
|
||||
selects `{{task_prompt}}`, **THEN** the draft contains exactly
|
||||
`{{task_prompt}}` with one closing brace pair.
|
||||
- **GIVEN** an editor contains `{{ta_prompt}}` with the cursor after `ta`,
|
||||
**WHEN** the user selects `{{task_prompt}}`, **THEN** the partial name and
|
||||
its existing suffix are replaced and the draft contains exactly
|
||||
`{{task_prompt}}`.
|
||||
- **GIVEN** a saved prompt named `changes-walkthrough`, **WHEN** a user types
|
||||
`@c`, **THEN** the completion list keeps `@changes-walkthrough` available.
|
||||
- **GIVEN** a saved prompt named `Daily Summary`, **WHEN** a user types
|
||||
`@Daily `, **THEN** the completion list keeps `@Daily Summary` available
|
||||
and selecting it inserts the complete mention.
|
||||
- **GIVEN** two open editors with different placeholder lists, **WHEN** a user types `{{` in either editor, **THEN** only that editor's placeholders appear.
|
||||
- **GIVEN** an open workflow prompt, **WHEN** another route adds a saved prompt, **THEN** the next `@` list includes it.
|
||||
- **GIVEN** a custom prompt named `release`, **WHEN** the user edits `release` and types `@`, **THEN** the list omits `@release` and includes other saved prompts.
|
||||
- **GIVEN** a utility agent prompt, **WHEN** the user types `{{`, **THEN** utility variables appear and no saved-prompt completion is offered.
|
||||
- **GIVEN** a failed saved-prompt request, **WHEN** the user types a supported placeholder prefix, **THEN** placeholder completion still works.
|
||||
- **GIVEN** an unsaved prompt edit, **WHEN** the user leaves the route, **THEN** the existing settings navigation guard still handles the draft.
|
||||
- **GIVEN** GitHub quick actions on a phone, **WHEN** the user selects both completion types, **THEN** no horizontal page overflow occurs.
|
||||
- **GIVEN** a saved quick action that contains a placeholder and saved-prompt reference, **WHEN** the page reloads, **THEN** the editor shows the same stored text.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Rich-text formatting, Markdown preview, or Tiptap document storage.
|
||||
- Changes to saved-prompt expansion, placeholder interpolation, or backend APIs.
|
||||
- Prompt composers outside Settings, such as task creation and task chat.
|
||||
- Completion for scripts, WIQL, JQL, JSON, descriptions, or confirmation fields.
|
||||
|
||||
## Implementation plan
|
||||
|
||||
See [`../../plans/settings-prompt-editor/plan.md`](../../plans/settings-prompt-editor/plan.md).
|
||||
The completion regression repair is tracked in
|
||||
[`../../plans/settings-prompt-completion-regressions/plan.md`](../../plans/settings-prompt-completion-regressions/plan.md).
|
||||
Reference in New Issue
Block a user