Repository navigation
Draft design for extensions (issue #1) - #17
Merged
Merged
Conversation
Extensions are npm packages (bundled, dependency-free) named with npm specs in devlog.json and pinned by a devlog.lock.json; installed by the app into user data with pacote, never into the devlog. Non-secret settings live in the devlog, secrets in the OS keychain. Consent per package hash; main half in a utilityProcess, renderer half in a sandboxed iframe. Covers the time export flow and ledger (#2), custom block kinds (#3), milestones and open questions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…inations Time reaches Jira (by task, with start times) and CMS (by client, weekly cap on the full-time client) through a weekly timesheet: sessions built from tracked time, rounded once to quarter hours, shuffled by hand, stored in a managed Timesheets canvas with one reply per submission as the send record. Destinations (extensions) declare mapping fields, grouping, dated rules and sending. EXTENSIONS.md now points at it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Per the decisions so far: destinations only map, group and send (no caps or other rules; the user finalises hours); the rounding rule is 15 minutes for anything above zero, then nearest quarter hour with halves rounding down; start times round to the quarter hour; rounding inflation is evened out by suggested trims on the longest sessions of the same client and day; CMS is per client per day, with ids found by walking up the canvas tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…d trims Pure functions in @devlog/core for the timesheet design: - roundWorkMinutes: anything above zero is 15 minutes, then the nearest quarter hour with exact halves rounding up; start times round to the nearest local quarter hour; - buildSessions: same-task segments with gaps of up to 30 minutes are one session (short locks count as work), split at longer gaps, at a switch to another task and at midnight; - draftEntries: each session rounded once, starts on quarter hours, no overlaps within a day; - balanceDays: per client (top-level canvas) per day, the rounded total worked versus what the entries report, with suggested 15-minute trims (or additions) on the longest entries, never below 15 minutes, and the residual when it cannot be evened out. Design doc updated with the decisions (halves round up, 30-minute gap rule, comments empty by default). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…do panel - The cross-machine merge of tracked segments (flattenOverlaps) compared every segment with every other: a week of window-focus changes took over 20 seconds to compute, stalling the weekly review and summary. It is now a sweep over the boundaries (O(n log n)), skipped entirely when all time comes from one machine; tests check it matches the old results exactly. A week with ~1,200 focus changes a day now computes in about 0.1 s, and the smoke test checks both views open in under 3 s with a busy day from two machines. - Back / Forward (View menu; Alt+Left / Alt+Right, Cmd+[ / Cmd+] on macOS; the mouse's side buttons) walk the places visited: canvases, views, timeline days. Keys are caught before the editor sees them; deleted canvases are skipped. - The todo panel resizes by dragging its left edge (or arrow keys on the handle); the width is remembered, double-click resets it. - 0.5.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Two or more consecutive done blocks (not hidden, no replies) show as a single quiet line, "✓ N todos done" with their names, styled like the other automatic blocks; clicking it shows the individual blocks with their usual actions. Display only: the blocks in the files are unchanged, and a single done block still shows as itself. 0.5.2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…led blocks - The folded "✓ N todos done" line now has a visible Show all / Hide control (and aria-expanded); expanded, the blocks are indented under it. The smoke test expands a run of twelve and checks every item. - The sticky canvas header now spans the feed's side padding and sits above hovered blocks, so block braces no longer show through it when the stream scrolls underneath; the smoke test checks for it. - 0.5.3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Record the search box value, focused element, composer text and whether any search view rendered, plus a screenshot, and stop the diagnostics from waiting 30 s themselves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Every devlog has been upgraded by 0.5, so the upgrade code goes: the v1/v2 block reader, the pages/categories reader, upgradeRepository and its cross-machine merge logic, adopting the pre-0.4 local activity log, the settings revision bump, and the migration smoke test. Opening a repository now checks devlog.json and refuses an older (or newer) format with a message naming the Devlog version to use. Canvas aliases stay, since old activity and links still use them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- Todo comments can be edited, hidden (folded into one line at the end of the thread, left out of the count) and deleted; core gains setTodoEntryHidden. - The stream only jumps to the end when a block is posted or a canvas opens; deletes, done blocks from the todo panel and captured commits leave it where it was (unless it was already at the end). - Opening or closing a todo keeps that todo in place; ticking one keeps the panel's scroll position. - Opening a todo focuses its comment box, and it keeps focus after posting; Esc closes the todo. - Typing with nothing focused goes into the note box for the canvas on screen. - Smoke: checks for all of the above; clicks rather than check()/uncheck() for todo rows that move between lists; seeds activityInRepo now that the settings revision bump is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Heartbeats only prove the app was alive while time can accrue; lock, idle and suspend are already in the log and close the open segment, so the periodic heartbeat is skipped while paused. That also stops sync from committing and pushing an activity file every five minutes on a locked machine. Foreground-window changes while locked or asleep (the lock screen itself) are no longer recorded either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…tension - Two data channels: contribute to the devlog through the API (marked with the extension's id), or keep its own files in private synced (extensions/<id>/) and machine-local folders, any format. - Isolation between extensions: no paths (a file broker with confined relative paths), no file system (utilityProcess under Node's permission model, to be verified), no shared channel, per-extension sandboxed renderer frames. - Window tracking moves out of the core into a bundled, opt-in first-party extension (devlog-focus); the task clock stays core. - Docs: heartbeats are skipped while the machine is locked or asleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- Reading the devlog is a permission, granted for the whole devlog or for chosen canvases (with what is beneath them); grants live on the machine with the consent, never in the repository. - Extensions are zips on GitHub releases (or any HTTPS URL) with a devlog-extension.json manifest, pinned by SHA-256 in devlog.lock.json; not npm, and no package manager. Ids come from the source, so one extension cannot claim another's folders. - Per-canvas settings in canvas.md, per-devlog settings in devlog.json. - v1 safety: no file-system access (Node permission model, code sent over the channel), no processes/addons/workers, grant-filtered API, no channel between extensions; network declared but not enforced. - Rich blocks and link previews as Adaptive Cards rendered by the app, so no extension code runs in the window. - devlog-focus gets the foreground-window feed as a capability instead of starting its own helper. - Timesheet sending is user-driven only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- extensions.ts (pure): devlog-extension.json validation, devlog.json entries (owner/repo + range, https URL, builtin) and ids derived from the source, a small semver range matcher, read/write grants with whole-devlog or canvas-subtree scopes and what they make visible. - canvas.md keeps unknown front-matter keys (extension fields such as ext.<id>.<key>), settable through updateCanvas; inheritedField walks up the tree. Index schema bumped so cached canvases pick fields up. - devlog.json updates keep unknown keys (extensions, settings); devlog.lock.json read/write. - ExtensionFileStore: an extension's private folder behind relative paths only; refuses .., absolute paths, device names, streams and links (including a linked extensions/ folder from git); atomic writes; size and file-count caps. Append-only globs get union-merge attributes. - Extension files are quiet for sync, like activity logs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…PI, UI (0.7.0) - Installer: GitHub releases (newest tag matching the range, a *.devlog-ext.zip asset, optional token for private repos), https URLs, built-ins shipped in the app's resources, and machine-local development folders. Downloads are checked against devlog.lock.json's SHA-256, unpacked (no path may leave the folder) into a cache keyed by hash. - Sandbox: Electron's utilityProcess ignores --permission, so each extension runs as a Node child of the app binary (ELECTRON_RUN_AS_NODE) under the permission model, allowed to read only the host script (copied out of app.asar), with a heap cap and a stripped environment. The bundle is sent over IPC and evaluated; require resolves Node built-ins only. - Manager: consent per build and devlog (a new build asks again), read and write grants (whole devlog or canvas subtrees) enforced on every API call, private repo/local folders through the file broker, settings in devlog.json, secrets through safeStorage, commands, notifications, confirmations, pause/resume/task notices. Reloads after a pull. - UI: Extensions dialog (add, allow with scopes, settings and secrets, stop, start again, remove, check for updates, GitHub token), consent dialog, extension commands in the quick switcher, extension fields in the canvas dialog, notifications as toasts; blocks written by an extension are read-only with the automatic brace. - @devlog/extension-api: public types, wire protocol and an in-memory test harness; authoring guide in its README. - Tests run a probe extension in the real sandboxed process (file access, child processes and workers refused; grants filter reads, writes and search); smoke drives the whole flow in the app. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- Extension API 1.1: ctx.machine, ctx.system.onForegroundWindow (needs the foregroundWindow permission and consent), ctx.provide.focus. - The app runs the platform window helper only while an allowed extension listens, and passes nothing on while the machine is locked or asleep (straight from powerMonitor, tracked or not). - devlog-focus ships in the app's resources: it appends each change to extensions/builtin.devlog-focus/<machine>/YYYY/MM/<date>.jsonl (union-merged), re-announces the window when the machine comes back, and provides the events back; activity.range merges them, so the timeline, review and summary draw screen time as before. - The core tracker no longer records focus events; existing ones in the activity logs still show. The "record the focused window" setting is gone; people who had it on are told once where it went. - Extensions dialog lists built-ins to add; the consent dialog asks about window titles; the harness supports the 1.1 API. - Tests run devlog-focus in the sandbox with a fake window feed (nothing recorded while locked or asleep, nothing without the permission, the helper stopped on revoke); smoke adds it from the dialog and checks the events reach the views. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- An extension may declare "permissions": { "unrestricted": true }. It
then runs only if you tick "I trust it" in the consent dialog, and runs
without Node's permission model, with the app's environment and
ctx.packageDir (its unpacked folder). A consent without trust does not
start it; the grant records trust per build like the rest.
- devlog-focus carries its own platform helper (moved from
src/main/activity/foreground.ts) and runs unrestricted. The app's window
feed, the foregroundWindow permission and ctx.system are gone (API
1.2); nothing about windows is left in the core.
- Extensions hear about locks and sleep straight from the OS (deduplicated
with the tracker's events), whether or not time is tracked.
- Fix: devlog-focus no longer remembers the lock screen as the last window
and re-records it on resume.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…s (0.9.0) - Core: the stored Timesheet (week, draft/final, entries), sanitised on every save; serialised as a readable markdown table plus the exact data in a devlog-timesheet fence. DevlogStore keeps one block per week (kind timesheet, on its Monday) in a canvas marked devlog.managed: timesheets, created on first use; later saves are edit records. Timesheet blocks are read-only like other automatic blocks. - Draft: tracked task segments (explicit markers applied, removed time excluded) → sessions → entries rounded once; untracked days use the review's estimate, starting at their first note. - Timesheet view (sidebar and quick switcher): week navigation, entries by day with day, start, duration in 15-minute steps, task, note, remove and add; per client and day, reported vs worked with the suggested trims and Apply; Rebuild from tracked time; Mark final / Reopen; saves within a second of each change. - Tests for the model, storage and draft; smoke drafts an hour of tracked time, adjusts it, checks the saved table and marks the week final. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…0.10.0)
- Extension API 1.3: contributes.destinations and
ctx.destinations.register(id, { preview, send }). The app builds the
week's sheet from the saved timesheet (task and client names, the
extension's own canvas fields inherited down the tree); pressing Send is
the consent for that week, so no read grant is needed. Only final weeks
are sent; each send leaves a read-only reply under the week's timesheet.
- devlog-jira (built in, sandboxed): one worklog per entry on its Jira
issue (canvas field "issue"), REST v2 with Basic email+token (Cloud) or
a personal access token (Data Center); a ledger per week in its own
synced folder, so sending again creates, updates or deletes only what
changed; a "Check the Jira connection" command.
- Timesheet view: Send to <destination>… on final weeks; the Send dialog
previews new / changed / removed / already sent / not for this
destination (with reasons), sends, and shows the result.
- Fix: a draft entry whose start rounds past midnight stays on its own day.
- Tests run devlog-jira in the sandbox against a fake Jira server (create,
unchanged, update, delete, auth, the record); smoke sends a week to a
fake Jira through the dialog. Smoke: DEVLOG_PLAINTEXT_SECRETS opts into
Electron's in-memory key on keyring-less Linux (tests only); the review
per-day check no longer assumes the run does not cross midnight.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
The Extensions dialog loads the built-ins after it opens; CI checked the count before they arrived. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…0.10.1) The week is now a table: a column per day plus the week, a row per task grouped under its client (each client row totals its tasks), and at the bottom the day's total reported and, muted, what was worked. Clicking a cell opens its entries under the grid for editing (start, duration, task, day, note, remove, add); an empty cell adds time there; "+ Add a task…" puts a task with no time yet on the grid. The suggested trim for a client's day sits in that client's cell and applies on click. Task names come first in row labels so a narrow window cuts the project path, not the name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…mputer, Test (0.11.0) - Manifest fields (settings, secrets, canvas fields) take a description, a type (text, url, email, number, select with options, checkbox, textarea) and required; contributes.check names a command that tests the settings. - Settings open in their own page, split into "This devlog" (devlog.json, synced) and "This computer" (secrets in the OS keychain, shown as saved with Replace / Clear). Values are checked by type on save; one Save for everything; Test / Save and test runs the check command and shows the text it returns, or its error. The extension's card says what required settings are still missing and offers "Set up…". - Canvas dialog: extension fields use the same typed inputs and show the value a canvas inherits from above as its placeholder. - devlog-jira: typed, described, required fields; its connection check returns its result to the settings page. - Inputs in dialogs share one style whatever their type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
A built-in, sandboxed extension that fills in the Technology Partners consultant timesheet the way the browser does: form login with the session cookie, the week page parsed for assignment rows and each day's timesheet_id, and the day's form submitted with decimal hours. - Hours per assignment (canvas field "assignment": number or project name) per day, across the two Sunday-to-Saturday CMS weeks a Devlog week spans. - The preview compares with what CMS shows; only differing days are sent, days it filled that no longer have time go back to 0 (ledger in sent/<week>.json), days typed into CMS by hand are left alone. - Days without a link (outside the assignment's dates, or not open yet because CMS opens a day on that day) are skipped with the reason; weeks that haven't started aren't fetched. - Commands: check the login, list assignments. The quick switcher now shows a command's answer as a toast. - Username in the devlog, password as a secret on the computer. - Tests against a made-up CMS with the same page structure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- Settings open from the foot of the sidebar into a dialog with its own navigation: Repository, Sync, Appearance, Activity tracking, Updates, and under Extensions a Manage page plus one page per extension (access, settings, secrets, its test). Save stays off until something changes; pages with unsaved changes (or extensions needing setup) are marked, and closing with unsaved changes asks first. The separate extensions and extension-settings dialogs are gone. - Canvas properties use the same paged layout: the canvas, its repositories, and a page per extension that adds canvas fields. Save is off until something changes. - Right-click a canvas in the sidebar (or a breadcrumb or child chip) for Open, Start/Stop, Properties, New canvas/task inside, Archive. - Start is a split button: with a task on screen its main part starts that task in one click; the arrow opens the task list. Task canvases also get Start/Switch/Stop in their header. - The journal is retired: no sidebar entry, no composer target, no todo fallback. Devlog opens on the last canvas viewed (or the running task, or the first canvas); a devlog with no canvases shows a first-canvas page. Old journal notes stay readable under Archived until moved. - devlog-cms 1.0.1: a week still ahead resolves assignment names from the current CMS week. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Phase 1 of docs/BLOCK-PAGES.md.
- Double-click a block (or Open, or its chip) to open it as a page: the
block is the page's surface (double-click to edit), and the blocks
written inside it are the page's stream, grouped by the day each was
written. Breadcrumbs run canvas / blocks above / this block; Alt+Up or
"Up" goes up a level (from a canvas, to its parent canvas).
- Streams no longer show threads inline: a block with blocks inside shows
a chip ("3 blocks inside"). Reply is gone; the note box on a page writes
inside that block. Alt+Enter posts and opens the new block.
- Back and forward, search results, and timeline and review links open
the page a block was written on.
- Reordering works among siblings at any depth.
- Blocks written inside an older block stay in its day file; the date
range query also returns those files (via the index, which now keeps
creation times indexed), so the review, summary, timeline and timesheet
count them on the day they were written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Phase 2 of docs/BLOCK-PAGES.md; docs/TIME-EXTENSION.md records the plan for moving time tracking into an extension. - A todo is a block with kind=todo, anywhere in the streams: on a canvas, inside a block, inside another todo. "[ ] …" lines (or pasted "- [ ]" lists) post one todo per line; the stream shows a checkbox. - Ticking a todo sets its done time where it is (no more "✓" blocks); a run of ticked todos folds into one line; the timeline shows the tick. - The todo panel is built from the index: open todos for the page on screen and everything inside it (or all), grouped under the canvases and blocks they live in, single-path chains merged into one heading, headings foldable. Clicking a todo opens its page; the add box posts into the page on screen. The inline comment threads are gone: notes on a todo are blocks inside it. - Opening a format 3 devlog moves each canvas's todos.md into the day file of the day each todo was written (comments become blocks inside it) and marks the devlog format 4. - Extension API 1.4: addBlock inside a block and as a todo; devlog.todos(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- Drag a block onto the middle of another to put it inside (from any day of the same canvas); Move → "Out of this block" takes it one level up. Core: moveBlock (a single set record within a file; copy and delete across files) and planNest. - Making a block with blocks inside it a task moves those into the task canvas's stream; the block stays as the link. - The quick switcher lists recently opened pages first. - Returning to a canvas from another view re-reads it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- contributes.views: page (sidebar + main area), statusbar (a slot of fixed height; the page asks for a width), popover (anchored to the view that opens it). - Pages load from devlog-ext://<key as hex>/<file>: only from the extension's own folder, only while it runs, in a frame sandboxed to scripts, under a CSP with no network, frames or forms. - The page talks to its extension through the app (postMessage: ready, call, resize, popover, close, open, command); the extension answers with ctx.views.handle and pushes with ctx.views.post; the app sends its theme as CSS custom properties. Message types in @devlog/extension-api/view. - The probe fixture has all three; tests cover the relay, the smoke test the frames, the push, the popover, opening a canvas, and the sandbox. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…core - packages/ui: React components, hooks, and the view bridge for extension views - scripts/build-builtins.mjs bundles built-in extensions' TypeScript sources - Canvases get an optional node type; `task: true` reads as the time extension's task type and is still written that way Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Extensions declare node types (`contributes.nodeTypes`: id, label, icon, placeholder). Canvas properties get a Type choice in place of the task checkbox; the sidebar, child chips, quick switcher and note box show the type's icon and label. `canvases()` reports each canvas's type. The task type stays the app's own until the time extension provides it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…rites; events; app state - Commands take a context (where they were run from, the canvas and block) and can declare a keybinding, a node type, menus (canvas, block, tray), and a note-box variant (`post`, with an optional #tag) - Views can sit in a canvas's header (`canvasHeader`, per node type) and get their canvas as context - devlog.createCanvas / updateCanvas / editBlock / promote / onBlockAdded - ui.pick, ui.open, ui.highlight; app.setTrayLabel, app.keepRunning; activity.idleAfter; provide.activity (time events join the app's views) - The test harness covers all of it; a `shaper` fixture exercises it through the real host process Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- builtin-extensions/devlog-time (TypeScript, bundled at build): the task node type, the clock (start/task/stop/heartbeat events in its own folder, per machine), Start/Stop in the status bar and on task canvases, a task picker, Stop (Mod+Shift+.), Start a task…, post as a task (Mod+Shift+Enter, #task), Make task on a block, the tray label - The app no longer tracks time: the Tracker, its IPC and UI are gone. It still notes locks, idle and sleep (for extensions, and in its activity log while an extension tracks time), and its views draw time from extensions' events alongside the old log - Once per machine that tracked time, the extension is added to the devlog and allowed, with the active task and idle setting carried over - Summary and Timesheet show only while an extension provides time - Extension views get their theme and context even when they load fast Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
…through destinations - devlog.activity(from, to): what the app recorded (its log and what extensions provide), limited to what the extension may read - devlog.range(from, to): day files with blocks written in a range - devlog.managedCanvas(key): a canvas the extension keeps, its own whatever it was granted: blocks of its own kinds on any day, editable; the Timesheets canvas the app made is devlog-time's - destinations.list/preview/send: other extensions' destinations, through the app, for extensions that declare permissions.send (shown at consent) - ui.openPage(viewId) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
- The Timesheet (with Send), and the Summary, move into the extension as page views built on @devlog/ui; the app's own views, IPC and store code for timesheets are gone - Timesheets stay one block per week in the Timesheets canvas, now kept by devlog-time (the canvas the app made is its own); sending goes through the app to the Jira and CMS extensions, and the record is written inside the week by devlog-time - Extension pages are listed in the quick switcher; Ctrl+Shift+H opens the Summary (a devlog-time command) - Shortcuts pressed inside an extension's view that it does not use reach the app (Ctrl+K, Alt+←…) - A built-in extension keeps its grant when the app brings a new build - Views get more of the app's colour tokens Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
devlog-time adds two canvas fields (hours per week, hours per month) that canvases inside do not take on. The Timesheet page shows each target that applies to the week on screen against the timesheet hours under its canvas in its own period: the week, and each month the week touches (other weeks as saved, or drafted from tracked time). Canvas fields can now say they are not inherited (`"inherited": false`). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extensions are npm packages (bundled, dependency-free) named with npm specs
in devlog.json and pinned by a devlog.lock.json; installed by the app into
user data with pacote, never into the devlog. Non-secret settings live in
the devlog, secrets in the OS keychain. Consent per package hash; main half
in a utilityProcess, renderer half in a sandboxed iframe. Covers the time
export flow and ledger (#2), custom block kinds (#3), milestones and open
questions.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01CAgWUf68JDhC5YPtWj1zT6