Commit Graph

19 Commits

Author SHA1 Message Date
Carlos Florêncio 86f756e280 feat(workflow): add set_session_mode action and preserve mode across reset (#1188) 2026-05-31 14:36:12 +01:00
Carlos Florêncio 50496fd07d feat(mcp): expose workflow import tool (#1177) 2026-05-31 11:14:42 +01:00
Carlos Florêncio e708a76701 docs: document portable workflow import/export YAML format (#1176) 2026-05-30 22:53:57 +01:00
Carlos Florêncio 50fb93e04b fix(mcp): correct ask_user_question_kandev schema docs and add consistency test (#1018) 2026-05-22 20:09:30 +01:00
Carlos Florêncio 0b2085688b feat(office): autonomous agent management layer (#914) 2026-05-16 20:07:57 +01:00
Carlos Florêncio 7011bbcbc4 fix: session tab leak, PR icon crash, and PR review prompt scope (#897) 2026-05-13 18:39:01 +01:00
Luan Martins 1066ac5b16 feat: extend implement plan button with fresh-agent path and server-side plan mode (#832)
* feat: extend implement plan button with fresh-agent path and server-side plan mode

- Split-button: primary click = same-session, chevron = fresh agent with clean context window
- Forward draft attachments and context files on implement (adds getAttachments() to handle)
- Authoritatively clear plan_mode via new session.set_plan_mode WS endpoint, not a message flag
- Add on_exit:disable_plan_mode to plan-and-build.yml plan step (mirrors feature-dev.yml)
- Drop localStorage plan-mode rehydration; server session metadata is the single source of truth
- Delete dead DocumentPanel component (no callers)
- Add SetSessionPlanModeByID on orchestrator Service; wire wsSetPlanMode handler

* test: fix store isolation in useImplementFresh test + extract duplicate strings

- Fix test isolation: reset store directly and clear mocks before rendering
- Extract sessionId, appFilePath, appFileName to constants to fix ESLint duplicate-string warnings

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(e2e): cover implement-plan fresh-agent split-button path

Adds Playwright coverage for the new chevron menu on the violet Implement
button: asserts a brand-new TaskSession is launched on the same task with
the planning session's agent profile inherited, and that the planning
session is left running in parallel. Second spec verifies the split-button
is gated behind plan mode.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: defer plan-mode exit and surface error toast on implement failures

Move handlePlanModeChange(false) into the message.add success callback in
useImplementPlan so a failed send leaves the plan layout intact for retry.
Add error toast to useImplementFresh catch so launchSession failures are
visible to the user instead of silently logged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: guard fresh-agent launch on planning session executor_id

TaskSession.executor_id is optional, so the fresh-agent path could call
launchSession with an undefined executor and silently inherit the
workspace default instead of the planning session's executor. Add the
field to the early-return guard so the hook no-ops when the planning
session is missing either an agent profile or an executor.

* feat: mark fresh-agent session as primary and focus it

When useImplementFresh launches a new implementation session, the fresh
session is now automatically:
1. Set as primary via session.set_primary WS endpoint
2. Focused/selected as the active session in the UI

This improves UX by switching the focus to the fresh implementation context
immediately rather than keeping the planning session active.

Addresses comment in PR #832 from carlosflorencio.

- Extract setupFreshSession helper to keep complexity under 15
- Add tests for primary session marking and UI focus
- Add test for graceful handling of set_primary failures
- Update JSDoc to document the new behavior
- Extract test constants to avoid duplicate string warnings

* fix(test): replace self-referential test constants

`const TASK_ID = TASK_ID;` (and SESS_PLAN, SESS_FRESH) caused a TDZ
ReferenceError at module load, so vitest reported `(0 test)` and none of
the new fresh-agent coverage actually ran. Replace with literal values
so the 13 tests in this file execute again.

* fix: drop strict executor_id guard and skip composer clear on missing session_id

Two related issues:

1. e2e regression — the planning session in the FE store does not always
   carry executor_id (the field is omitempty on the backend DTO and isn't
   populated for fresh task sessions in the WS push path). The earlier
   guard required it before calling launchSession, so the fresh-agent
   path silently no-op'd in real flows. Drop executor_id from the guard
   and only forward it when set; backend resolves it from the agent
   profile / workspace default when omitted.

2. PR review (Greptile P1) — when launchSession resolves without a
   session_id, the previous flow still cleared the composer and draft
   even though no fresh session was activated. Bail out before the
   clear so the user keeps their typed text and can retry.

Tests updated:
- replace the no-op-on-missing-executor test with one that asserts the
  hook still launches and omits the key from the payload
- add coverage for the no-session_id branch keeping the composer intact

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 17:30:24 +01:00
Carlos Florêncio 8c70aee27d fix(workflows): hide improve-kandev system workflow from settings UI (#842) 2026-05-07 18:42:57 +01:00
João Salavisa 83de4793fd feat: add Linear issue watchers (#805) 2026-05-05 08:28:09 +01:00
João Salavisa a59909ca5a fix(jira): use shared prompt template with placeholder autocomplete (#801)
* fix(jira): use shared prompt template with placeholder autocomplete

Default prompt for the JIRA watcher now lives in
config/prompts/jira-issue-watch-default.md (loaded via promptcfg.Get),
matching how the GitHub issue/PR-review watchers source their defaults.
The watch dialog swaps the plain Textarea for the ScriptEditor used by
the GitHub dialog so users get {{...}} autocomplete, and the inline
hardcoded default string is gone from both backend and frontend.

* fix(jira): treat whitespace-only stored prompt as empty on hydrate

CodeRabbit caught that w.prompt || DEFAULT keeps a stored "   " value,
which canSave then rejects — dialog reopens in an unsavable state. Fall
back to the default whenever the trimmed value is empty.

---------

Co-authored-by: Kandev Agent <agent@kandev.dev>
2026-05-03 20:48:10 +01:00
Carlos Florêncio 1eae869054 feat: add improve kandev in-app contribution flow (#740) 2026-05-01 15:18:18 +01:00
Carlos Florêncio b77b2802ce feat(workflows): review uncommitted changes and add git safety rails (#684) 2026-04-23 18:40:39 +01:00
João Salavisa e8781a6443 refactor: move system prompts from Go constants to external config files (#673)
* refactor: move system prompts from Go constants to external config files

* fix: address review — add session handover tests and Resolve doc comment

* fix: single-pass placeholder replacement and remove no-op InterpolatePlaceholders

---------

Co-authored-by: Kandev Agent <agent@kandev.dev>
2026-04-21 19:29:46 +01:00
João Salavisa c11a6bbfd2 feat(github): add issue watcher with task creation and auto-cleanup (#672)
* feat(github): add issue watcher with task creation and auto-cleanup

Add a GitHub Issue Watcher feature that polls for new issues matching
configurable filters and automatically creates tasks for them. This
complements the existing PR Review Watcher with the same patterns.

Backend:
- Issue watch CRUD (models, store, service, controller, WS handlers)
- Poller integration with configurable intervals
- Event-driven task creation via orchestrator
- Repository resolution and worktree support for issue tasks
- Auto-cleanup of tasks for closed issues (CleanupClosedIssueTasks)
- GetIssueState client method across all implementations
- Default branch auto-detection from cloned repo HEAD

Frontend:
- Issue watch settings UI (table, dialog, placeholders)
- Issue link icon on task cards (green circle-dot)
- API client, store slice, and hook for issue watches
- SSR and WS hydration of issue metadata

* fix: resolve golangci-lint errors (goconst, nestif, dupl) and prettier formatting

* fix(github): fix issue watch update shape, trigger key, and label quoting

- httpUpdateIssueWatch now returns the full IssueWatch object instead of
  {updated:true} so the frontend store correctly refreshes after edits
- httpTriggerIssueWatch returns new_issues_found to match TriggerIssueResponse
  type; was returning new_issues so the toast count was always 0
- buildIssueFilter uses conditional quoting instead of fmt.Sprintf %q to
  avoid Go escape sequences in GitHub search qualifiers

Co-authored-by: João Salavisa <undefined@users.noreply.github.com>

* fix: resolve eslint warnings (max-lines-per-function, no-nested-ternary)

* test(github): add issue watcher tests and fix review feedback

- Add TestInterpolateIssuePrompt (4 cases: empty/all/none/partial)
- Add TestCreateIssueTask (3 cases: skip/reserve+assign/release on fail)
- Add TestShouldDeleteIssueTask (4 cases: open/closed+sessions/closed/error)
- Fix WS response key new_issues -> new_issues_found
- Fix fmt.Printf -> fmt.Fprintf(os.Stderr) in store.go
- Add CleanupClosedIssueTasks call in WS trigger handler

* fix: address PR review feedback and CI failures

- Split test files to fix revive file-length-limit (service_test.go,
  event_handlers_github_test.go)
- Add session checker guard in CleanupClosedIssueTasks
- Normalize poll intervals on UpdateIssueWatch
- Add cleanup call in TriggerAllIssueChecks loop
- Log cleanup errors in controller and WS handler
- Prefer refs/remotes/origin/HEAD in detectGitDefaultBranch
- Add aria-label to issue task icon
- Fix TypeScript type errors: add linkedIssues to GitHubSlice,
  fix hook exports, remove invalid imports

* fix: split test files exceeding revive limit and clean up minor issues

- Split service_test.go (883→779 lines): move TestTriggerPRSync_* to
  service_pr_sync_test.go
- Split event_handlers_github_test.go (806→677 lines): move
  TestCreateReviewTask_* and helpers to event_handlers_github_review_test.go
- Remove redundant s.taskSessionChecker nil-check inside shouldDeleteIssueTask
  (early guard at CleanupClosedIssueTasks already ensures it is non-nil)
- Remove unreachable dead guard in detectAndPersistDefaultBranch
  (repo.DefaultBranch is always "" at that call site)
- Fix bogus #0 issue badge in task-session-sidebar.tsx when issueNumber is absent

Co-authored-by: João Salavisa <undefined@users.noreply.github.com>

* fix: address Claude review — poll clamp and prompt injection

- Handle v <= 0 in UpdateIssueWatch poll interval (fall back to default)
- Remove {{issue.body}} from default template to prevent prompt injection
- Update test expected output for new default template

* fix: remove {{issue.body}} from frontend DEFAULT_ISSUE_WATCH_PROMPT

Mirrors the backend fix — the UI pre-fills the prompt so the backend
fallback was never reached. The placeholder stays in
ISSUE_WATCH_PLACEHOLDERS for explicit opt-in.

* feat(github): add isIssueWatch sidebar filter dimension

Add isIssueWatch boolean to KanbanState, TaskSwitcherItem, and sidebar
filter registry — mirroring the isPRReview pattern. Issue-watch tasks
(created from issue_watch_id in metadata) can now be explicitly filtered
in the sidebar, just like PR review tasks.

Files changed:
- sidebar-view-types: add isIssueWatch dimension
- filter-dimension-registry: add Issue watch filter meta
- apply-view: add isIssueWatch extractor
- kanban types: add isIssueWatch field
- TaskSwitcherItem: add isIssueWatch field
- use-all-workflow-snapshots: derive isIssueWatch from metadata
- ssr/mapper: derive isIssueWatch from metadata
- task-session-sidebar: pass isIssueWatch, extract helpers to fix complexity

* fix: correct deleteIssueWatch response type to match backend

Backend httpDeleteIssueWatch returns {"deleted": true}; the frontend
type was { success: boolean } — a mismatch with no functional impact
(return value is ignored) but wrong per TypeScript contract.

Co-authored-by: João Salavisa <undefined@users.noreply.github.com>

* refactor: extract metadata helpers to shared lib/metadata-utils.ts

- Move isPRReviewFromMetadata, isIssueWatchFromMetadata, and
  issueFieldsFromMetadata to a shared module to eliminate duplicate
  definitions (sonarjs/no-identical-functions).
- Fix deleteIssueWatch response type: { success: boolean } -> { deleted: boolean }
  to match the actual backend response.

* style: fix prettier formatting

* test(web): add tests for isIssueWatch filter dimension and metadata-utils

Co-authored-by: João Salavisa <undefined@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: fix prettier formatting in test files

* fix(github): cascade-delete issue watch tasks on watch deletion and add isPRReview to SSR mapper

- DeleteIssueWatch now wraps in a transaction and deletes related
  github_issue_watch_tasks rows before removing the watch; prevents
  orphaned dedup rows accumulating after a watch is deleted
- snapshotToState in mapper.ts now also sets isPRReview from metadata,
  matching the mapping already done in use-all-workflow-snapshots.ts

Co-authored-by: João Salavisa <undefined@users.noreply.github.com>

* style: extract duplicate string constant in metadata-utils test

* style: extract repeated WS error strings into constants in handlers.go

goconst min-occurrences: 3 — 'invalid payload' (6x) and 'id required' (4x)
both exceed the threshold. Extract to package-level constants.

Co-authored-by: João Salavisa <undefined@users.noreply.github.com>

* style: extract repeated issue key strings into constants in event_handlers_github.go

goconst min-occurrences: 3 — 'issue_number' (9x) and 'issue_watch_id' (5x)
both newly introduced in this PR exceed the threshold.

Co-authored-by: João Salavisa <undefined@users.noreply.github.com>

* style: fix prettier formatting in metadata-utils test

---------

Co-authored-by: Kandev Agent <agent@kandev.dev>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: João Salavisa <undefined@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:32:46 +01:00
Carlos Florêncio 4a9d1a1d7e fix(workflows): tighten default template prompts for commits, todos, and PR review (#655) 2026-04-20 21:55:33 +01:00
José Almeida d1a028fdb6 feat: introduce subtasks, allow sessions to task reuse executor (#419) 2026-03-29 15:33:40 +01:00
Carlos Florêncio dfa4a3369f feat: add Feature Dev workflow and improve default workflow prompts (#481) 2026-03-29 11:36:07 +01:00
Carlos Florêncio 146e63b09e chore: add TDD, E2E, and feature skills, improve code review and pre-commit (#478) 2026-03-28 19:49:28 +00:00
Carlos Florêncio 82d5168b67 refactor: centralize default prompts and fix PR review scoping (#476) 2026-03-28 16:51:24 +00:00