Skip to content

Commit 4ba4034

Browse files
lsoldadoDavidson GomesclaudeDavidson Gomes
authored
fix(frontend): respect workspace timezone setting in date formatters (#59)
* fix(telegram): remove reply() from prod-review-todoist skill Telegram notification was still in the skill file, causing the agent to call reply() multiple times per run (3x observed on 25/04 at 06:51). Notification now controlled by notify_telegram=True in review_todoist.py (gitignored custom routine, already updated on disk). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(chat-bridge): resolve agent file from WORKSPACE_ROOT, not session cwd Ticket threads pass workspace_path (e.g. workspace/personal/) as the session cwd. loadAgentFile was building the path relative to that cwd, so it looked for .claude/agents/ inside the ticket's folder instead of the workspace root — always failing for every agent. Fix: try WORKSPACE_ROOT/.claude/agents/{name}.md first, fall back to cwd for custom per-directory agents. Affected: kai-personal-assistant, flux-finance, and any ticket with a workspace_path set. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(telegram): eliminate duplicate notifications from inline reply() template Root cause: notify_telegram instruction showed reply(chat_id=..., text="...") as an inline code snippet, causing the agent to execute it immediately on reading the instruction AND again at the end — 2x per instruction. Financial Pulse was getting 4x because the skill's Step 8 also contained a reply() call instruction (2 instructions × 2 executions = 4 messages). Fixes: - runner.py: rewrite notify_telegram prompt to describe the action in plain text without an inline function-call template - fin-daily-pulse SKILL.md: remove Step 8 Telegram section — notification is handled by the routine caller via notify_telegram=True Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(telegram): remove all inline reply() calls from skill SKILL.md files Comprehensive sweep of all 175+ skills. Root cause of all duplicate Telegram notifications: skills contained inline reply(chat_id=...) code examples that Claude executed immediately on reading, then called again at the actual end-of-skill step — causing 2x (or 4x when combined with a second instruction from notify_telegram=True in the routine). Changes: - Removed "Notify via Telegram" sections entirely from 10 skills that have a corresponding routine using notify_telegram=True: fin-weekly-report, gog-email-triage, prod-dashboard, prod-trends, pulse-monthly, pulse-weekly, sage-strategy-digest, fin-monthly-close-kickoff, social-analytics-report, social-youtube-report - Rewrote Telegram instructions without inline reply() code in 4 skills that are called without notify_telegram (heartbeat or conditional): int-sync-meetings, int-github-review, int-linear-review (plain text), custom-getfy-sync, custom-omc-sync (plain text, local/gitignored) The corresponding routines (gitignored) were updated locally to add notify_telegram=True where the section was removed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(frontend): respect workspace timezone setting in date formatters The workspace settings page exposes a timezone selector (Settings.tsx already saves `workspace.timezone` via /api/settings/workspace), but the four pages that render timestamps — Topics, TicketDetail, Tasks, and the "last seen" text on Settings itself — hardcoded `timeZone: 'America/Sao_Paulo'` in their local formatDate helpers. Effect: users outside São Paulo saw timestamps shifted by their local offset minus −03:00. A user in Europe/London (BST) saw all ticket timestamps 4 hours behind their wall clock. This patch centralises date formatting in `lib/format.ts`: - `loadWorkspaceTimezone()` fetches the workspace config once after login (called from App.tsx alongside the other hydrate calls) and caches the IANA tz in a module variable + localStorage so subsequent paints don't have to wait on the API. - `getTimezoneSync()` returns cache → localStorage → browser default, in that order, never throwing. - `formatDateTime(iso)` and `formatDate(iso)` use the cached tz. - `refreshWorkspaceTimezone(tz)` is called from the Settings save handler so the change is reflected without a hard reload. Topics.tsx, TicketDetail.tsx and Tasks.tsx now alias their local `formatDate` to the shared `formatDateTime`, removing the hardcoded São Paulo string. The behaviour is unchanged for users on São Paulo (workspace setting still defaults to that value); users on any other configured timezone now see correct timestamps. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(format): don't overwrite freshly-refreshed cache on slow API resolve Sourcery flagged a race in loadWorkspaceTimezone: if the user updated the timezone via Settings → refreshWorkspaceTimezone while the initial GET /settings/workspace was still in flight, the eventual resolution of that GET would overwrite cachedTz (and localStorage) with the stale server value, silently reverting the user's change until the next reload. Fix: in both the success and failure handlers, only write if cachedTz is still null. If anything else claimed the cache in the meantime, keep the fresher value. Reported-by: sourcery-ai[bot] on PR #59 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: regenerate uv.lock after rebase on develop Develop bumped evo-nexus to 0.33.0 (release aa33f7d) and added flask-limiter / limits / wrapt / etc. via the rate-limit + plugin contract work. The branch's old uv.lock was carrying 0.32.2 which would regress the project version on merge. Re-running `uv lock` syncs the file with the current pyproject.toml and develop's deps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Davidson Gomes <davidson.gomes@etus.com.br> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Davidson Gomes <davidson.gomes@evofoundation.com.br>
1 parent 51a93ba commit 4ba4034

25 files changed

Lines changed: 285 additions & 133 deletions

File tree

.claude/skills/fin-daily-pulse/SKILL.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ workspace/finance/reports/daily/[C] YYYY-MM-DD-financial-pulse.html
157157

158158
Create the directory `workspace/finance/reports/daily/` if it does not exist.
159159

160-
## Step 8 — Confirm and notify (ONE Telegram message only)
160+
## Step 8 — Confirm
161161

162-
Output the completion summary, then send **exactly one** Telegram message. Do NOT call `reply` more than once per run.
162+
Output the completion summary in the terminal:
163163

164164
```
165165
## Financial Pulse generated
@@ -171,6 +171,4 @@ Output the completion summary, then send **exactly one** Telegram message. Do NO
171171
**Alerts:** {N} attention points
172172
```
173173

174-
Call `reply` **once** with a short summary (do not send the full markdown above — send a compact version):
175-
176-
- Format: `[emoji] Financial Pulse [date] | MRR: R$ X,XXX | Receita: R$ X,XXX | Churn: X% | [N] alertas`
174+
Do NOT send a Telegram message here — the caller handles notifications.

.claude/skills/fin-monthly-close-kickoff/SKILL.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,3 @@ Create the directory `workspace/finance/reports/monthly/` if it does not exist.
182182
**Checklist:** X/10 completed
183183
**Finance team pending items:** {N} items
184184
```
185-
186-
### Notify via Telegram
187-
188-
Upon completion, send a short summary via Telegram to the user:
189-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
190-
- Format: emoji + "Monthly Close" + month's result + pending items (2-3 lines)

.claude/skills/fin-weekly-report/SKILL.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,3 @@ Create the directory `workspace/finance/reports/weekly/` if it does not exist.
164164
**MRR total:** R$ X,XXX (Stripe: R$ X,XXX | Evo Academy: R$ X,XXX) | **Projected 30d balance:** R$ XX,XXX
165165
**Alerts:** {N} overdue accounts | {N} pending invoices
166166
```
167-
168-
### Notify via Telegram
169-
170-
Upon completion, send a short summary via Telegram to the user:
171-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
172-
- Format: emoji + "Financial Weekly" + revenue vs expenses + MRR + alerts (2-3 lines)

.claude/skills/gog-email-triage/SKILL.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,3 @@ See `skills/gog/_shared/references/testing.md` for complete test plan.
354354
- If email subject/sender contains obvious credentials or secrets, redact in output
355355

356356
- For recurring newsletters, suggest creating a filter/rule rather than manual archiving
357-
358-
359-
### Notify via Telegram
360-
361-
Upon completion, send a short summary via Telegram to the user:
362-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
363-
- Format: emoji + routine name + main result (1-3 lines)
364-
- If the routine had no updates, send anyway with "no updates"

.claude/skills/int-github-review/SKILL.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ Create directory if it does not exist.
118118

119119
### Notify via Telegram
120120

121-
Upon completion, send a short summary via Telegram to the user:
122-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
123-
- Format: emoji + routine name + main result (1-3 lines)
124-
- If the routine had no updates, send anyway with "no updates"
121+
Upon completion, use the Telegram reply tool to send a short summary to the user.
122+
Format: emoji + routine name + main result (1-3 lines).
123+
If the routine had no updates, send anyway with "no updates".

.claude/skills/int-linear-review/SKILL.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ Create the directory `workspace/projects/linear-reviews/` if it does not exist.
9797

9898
### Notify via Telegram
9999

100-
Upon completion, send a short summary via Telegram to the user:
101-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
102-
- Format: emoji + routine name + main result (1-3 lines)
103-
- If the routine had no updates, send anyway with "no updates"
100+
Upon completion, use the Telegram reply tool to send a short summary to the user.
101+
Format: emoji + routine name + main result (1-3 lines).
102+
If the routine had no updates, send anyway with "no updates".

.claude/skills/int-sync-meetings/SKILL.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,13 @@ Without listing tasks one by one — just counts. If the user wants details, the
186186

187187
### Step 9 — Notify via Telegram
188188

189-
Send the Step 8 summary via Telegram to the user using the `/int-telegram` skill:
190-
- Chat ID: `YOUR_CHAT_ID`
191-
- Use `reply(chat_id="YOUR_CHAT_ID", text="...")` via MCP
192-
- Short format: emoji + title + meeting and task count
189+
Only send if at least one new meeting was processed (i.e., you did NOT stop at Step 2).
193190

194-
If there are no new meetings (stopped at Step 2), do **NOT** send any Telegram message — stay silent. Only notify when at least one new meeting was processed.
191+
Use the Telegram reply tool with the user's chat_id and a short summary:
192+
- Format: emoji + title + meeting count + task count
193+
- One line only
194+
195+
If there are no new meetings (stopped at Step 2), do **NOT** send any Telegram message — stay completely silent.
195196

196197
## Notes
197198

.claude/skills/prod-dashboard/SKILL.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,3 @@ Present a short summary:
142142
**Health:** Product {status} | Community {status} | Financial {status} | Routines {status}
143143
**Alerts:** {N} attention points
144144
```
145-
146-
### Notify via Telegram
147-
148-
Upon completion, send a short summary via Telegram to the user:
149-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
150-
- Format: emoji + routine name + health status of each area (1-3 lines)
151-
- If there were no updates, send anyway with "no updates"

.claude/skills/prod-review-todoist/SKILL.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,3 @@ If the user wants to see details of what changed, they ask.
124124
- **If unsure about the category**, use `[Operations]` as fallback
125125
- **Execute first, report after** — no intermediate report
126126

127-
128-
### Notify via Telegram
129-
130-
Upon completion, send **exactly ONE** Telegram message — do NOT call `reply()` more than once per run:
131-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
132-
- Format: emoji + routine name + main result (1-3 lines, all combined in a single message)
133-
- If the routine had no updates, send anyway with "no updates"

.claude/skills/prod-trends/SKILL.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,3 @@ Create `memory/trends/` if it does not exist.
163163
- **If a source has no data, skip** — do not block due to a missing report
164164
- **Focus on action** — each insight should lead to a concrete recommendation
165165
- **Do not alarm without evidence** — red only when the metric truly indicates risk
166-
167-
168-
### Notify via Telegram
169-
170-
Upon completion, send a short summary via Telegram to the user:
171-
- Use the Telegram MCP: `reply(chat_id="YOUR_CHAT_ID", text="...")`
172-
- Format: emoji + routine name + main result (1-3 lines)
173-
- If the routine had no updates, send anyway with "no updates"

0 commit comments

Comments
 (0)