Skip to content

Add scheduled prompt timers, per-session notification opt-in, and "still running" reminders#247

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/build-notification-and-timers
Draft

Add scheduled prompt timers, per-session notification opt-in, and "still running" reminders#247
Copilot wants to merge 3 commits intomainfrom
copilot/build-notification-and-timers

Conversation

Copy link
Contributor

Copilot AI commented Feb 28, 2026

Adds three notification and timer features to Copilot sessions.

Scheduled prompt timers

The core feature: set a timer that automatically runs a given prompt in a session and reports back with the results via system notification.

  • ScheduledPrompt model — stores session name, prompt text, optional label, NextRunAt, RepeatIntervalMinutes, IsEnabled, LastRunAt
  • ScheduledPromptService — background timer checks every minute for due prompts, fires them via SendPromptAsync (enqueues if session is busy, retries if session is not found), sends a system notification when the result arrives. Persists schedules to ~/.polypilot/scheduled-prompts.json
  • "📅 Schedule a prompt…" added to both the sidebar session menu and the dashboard card menu
  • Schedule form in the sidebar footer and a modal overlay on the dashboard — enter the prompt, an optional label, and choose:
    • After a delay: 1 / 5 / 10 / 15 / 30 min, 1h, 2h (one-shot)
    • Repeating: every 5 / 15 / 30 min, 1h, 2h, 6h, or daily
  • The form also lists active schedules for the session with a countdown and a remove button

Per-session notification opt-in

  • AgentSessionInfo.NotifyOnComplete (bool, default false) — per-session flag independent of the global EnableSessionNotifications setting
  • CopilotService.SetSessionNotifyOnComplete(sessionName, bool) — public toggle method
  • Session card menu and sidebar item menu both get "🔔 Notify when done" / "🔔 Watching (tap to stop)" toggle; bell badge appears in card header and sidebar when active
  • Completion notification fires when either the global setting or per-session flag is set

Timer-based "still running" reminders

  • ConnectionSettings.NotificationReminderIntervalMinutes (int, default 0 = off) — configures reminder cadence
  • The processing watchdog calls SendReminderNotificationIfDueAsync each tick with interval-based deduplication via Interlocked.CompareExchange
  • Reminder body: "⏱ Still running · 5m elapsed" / "⏱ Still running · 1h 10m elapsed"
  • Settings UI shows a reminder interval dropdown (Off / 2 / 5 / 10 / 15 / 30 min) below the existing notification toggle

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Copilot AI changed the title [WIP] Add notification and timer functionality for prompts Add per-session notification opt-in and timer-based "still running" reminders Feb 28, 2026
@PureWeen
Copy link
Owner

@copilot no, what i wanted here is a way to set timers thay will run a given prompt and them report back to me

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 28, 2026

@copilot no, what i wanted here is a way to set timers thay will run a given prompt and them report back to me

Implemented in c21cd08. The feature works as follows:

Scheduling a prompt — from any session's context menu (sidebar or card), tap "📅 Schedule a prompt…" to open a form where you enter:

  • The prompt text to send
  • An optional label
  • Run mode: after a delay (1 min / 5 / 10 / 15 / 30 / 1h / 2h) or repeating (every 5 min / 15 / 30 / 1h / 2h / 6h / daily)

How it works:

  • A background timer checks every minute for due prompts
  • When a timer fires, the prompt is sent to the target session via SendPromptAsync; if the session is busy, it's enqueued instead
  • A system notification is sent when the result arrives (title 📅 <label>, body = first 80 chars of the response)
  • Repeating schedules automatically advance to the next interval; one-shot prompts disable themselves

Managing schedules — the panel also lists existing schedules for the session with a countdown (e.g. "12m", "1h 5m") and an ✕ to remove them.

Schedules persist across restarts in ~/.polypilot/scheduled-prompts.json.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 192.0.2.1
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/PolyPilot/PolyPilot/PolyPilot.Tests/bin/Debug/net10.0/PolyPilot.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/PolyPilot/PolyPilot/PolyPilot.Tests/bin/Debug/net10.0/PolyPilot.Tests.deps.json /home/REDACTED/work/PolyPilot/PolyPilot/PolyPilot.Tests/bin/Debug/net10.0/testhost.dll --port 44609 --endpoint 127.0.0.1:044609 --role client --parentprocessid 4396 --telemetryoptedin false (packet block)
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/PolyPilot/PolyPilot/PolyPilot.Tests/bin/Debug/net10.0/PolyPilot.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/PolyPilot/PolyPilot/PolyPilot.Tests/bin/Debug/net10.0/PolyPilot.Tests.deps.json /home/REDACTED/work/PolyPilot/PolyPilot/PolyPilot.Tests/bin/Debug/net10.0/testhost.dll --port 45365 --endpoint 127.0.0.1:045365 --role client --parentprocessid 5352 --telemetryoptedin false (packet block)
  • josvsblobprodcus372.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-abbd4936ea2bb08e/dbs/csharp/working/622A4908CDBE24FF535A100F8AC55E4F/missingpackages_workingdir --packages /tmp/codeql-scratch-abbd4936ea2bb08e/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-abbd4936ea2bb08e/dbs/csharp/working/nugetconfig/nuget.config --force (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add per-session notification opt-in and timer-based "still running" reminders Add scheduled prompt timers, per-session notification opt-in, and "still running" reminders Feb 28, 2026
PureWeen added a commit that referenced this pull request Mar 5, 2026
Root cause of wrong-remote pushes:
- Workers used 'git fetch origin pull/<N>/head:pr-<N>' which creates a branch
  with NO tracking info. Subsequent 'git push' defaulted to origin, silently
  pushing to PureWeen/PolyPilot even for fork PRs.
- Workers also used 'git rebase + --force-with-lease' which is unnecessary
  when using merge.

Fix:
- .squad/routing.md: updated Fix Process to use 'gh pr checkout <N>' (sets
  correct tracking) and 'git merge origin/main' (no force push needed)
- .squad/decisions.md: explicit rules against force push and manual fetch
- push-to-pr.sh: script that derives correct remote from gh pr view metadata
  and pushes without --force, with pre-push safety checks

Verified: 'gh pr checkout' correctly sets tracking to fork remote for PR #280
(vitek-karas) and to origin for same-repo PRs like #247 (PureWeen).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PureWeen added a commit that referenced this pull request Mar 9, 2026
## Problem

PR review workers were pushing to the wrong remote (e.g., pushing to
`origin/PureWeen` when the PR comes from a fork like `vitek-karas`), and
using `--force-with-lease` after rebasing unnecessarily.

### Root Cause (verified by testing)

Workers were using manual checkout:
```bash
git fetch origin pull/<N>/head:pr-<N>
git checkout pr-<N>
```

This creates a branch with **no tracking info** (`Remote: NONE`, `Merge:
NONE`). When the worker then runs `git push` or `git push origin`, git
defaults to `origin` (PureWeen/PolyPilot) — even if the PR came from a
fork.

In contrast, `gh pr checkout <N>` correctly sets up tracking:
- Same-repo PR #247: `Remote: origin`, `Merge:
refs/heads/copilot/build-notification-and-timers` ✅
- Fork PR #280: `Remote: vitek-karas`, `Merge:
refs/heads/Add-a-way-to-specify-polypilot-clone-root-7299` ✅

The second problem was `git rebase origin/main` + `--force-with-lease`,
which requires force pushing. Using `git merge origin/main` adds a merge
commit instead — no force push needed.

## Changes

### `push-to-pr.sh`
A shell script that:
1. Reads PR metadata via `gh pr view` to find the correct owner and
branch
2. Maps the owner to the correct git remote
3. Pushes to that remote **without** `--force`
4. Verifies the push landed by comparing local and remote HEADs
5. Refuses to push if current branch doesn't match the PR branch (guards
against wrong-branch pushes)

### `.squad/routing.md`
Updated Fix Process replacing rebase+force-push with merge+safe-push,
with clear explanation of why `gh pr checkout` is required.

### `.squad/decisions.md`
Explicit shared rules:
- Never force push
- Always use `gh pr checkout` (not manual fetch)
- Always merge (not rebase)
- Always verify push target before pushing
- Use `push-to-pr.sh` for all PR pushes

### `.squad/team.md`
Team definition file (required for squad directory to be recognized by
PolyPilot's squad discovery).

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants