release: ship v1.5.0 with on-device writing suggestions
Some checks failed
deploy-site / deploy (push) Failing after 33s
portable-unsigned / portable-windows (push) Failing after 4m7s
release / release-windows (push) Failing after 3m16s

Adds next-sentence suggestions while typing, weekly input insights and a
personal phrase memory to the desktop app, and fixes custom instructions so
they process the text instead of inserting the instruction's own wording.
Local model requests are now bounded and individually cancellable.

Bumps the product version to 1.5.0 (Android/iOS build 1050000), refreshes the
landing and web download links, and records the new INPUT feature rows and the
open verification gaps in the infrastructure map.
This commit is contained in:
Yun Chan 2026-09-23 16:04:27 +09:00
parent 99f06c253c
commit 5c11ee2fde
104 changed files with 14410 additions and 174 deletions

View file

@ -1707,5 +1707,192 @@
"keybinding.ui.recordHint": "Enter a combination (e.g. Ctrl+Shift+Q) or a single key (e.g. F5)",
"keybinding.ui.recordAgain": "Clear",
"keybinding.ui.saveFailed": "The shortcut could not be saved",
"keybinding.ui.globalEnabled": "Enable global shortcuts"
"keybinding.ui.globalEnabled": "Enable global shortcuts",
"input.tab": "Input",
"input.consent.title": "Input data collection",
"input.consent.description": "Optional. We count keystrokes and clicks and measure how far the mouse travels so you can see your own typing patterns. Which keys you press is never stored.",
"input.consent.collect": "Collect keyboard and mouse statistics",
"input.consent.running": "Collecting now.",
"input.consent.stopped": "Collection is off. Nothing is recorded.",
"input.consent.pause": "Pause collection",
"input.consent.learnText": "Learn the text I type",
"input.consent.learnTextHint": "Reads the focused text field to learn your phrasing. Password fields are always skipped.",
"input.consent.excludedApps": "Excluded apps",
"input.consent.excludedAppsPlaceholder": "keepassxc.exe, 1password.exe",
"input.consent.excludedAppsHint": "Comma-separated executable names. Nothing is read or counted in these apps.",
"input.consent.clearAll": "Delete collected data",
"input.suggestion.title": "Next-sentence suggestions",
"input.suggestion.description": "Predicts the sentence you are about to write and shows it next to your caret. Accept to insert it.",
"input.suggestion.enabled": "Show suggestions while typing",
"input.suggestion.modelReady": "Local model ready.",
"input.suggestion.modelMissing": "Local model is not running — suggestions stay off.",
"input.suggestion.delay": "Delay (ms)",
"input.suggestion.minPrefix": "Min. characters",
"input.suggestion.modelDefault": "Use default model",
"input.suggestion.overlayInteractive": "Allow clicking the suggestion box",
"input.suggestion.overlayVisible": "Suggestion is on screen",
"input.suggestion.keyHint": "Accept, cycle and dismiss are global key bindings — change them in Settings > Shortcuts.",
"input.suggestion.requestNow": "Suggest now",
"input.suggestion.usage": "{{requests}} of {{budget}} requests used today",
"input.suggestion.lastSkip": "Last skipped: {{reason}}",
"input.insights.title": "Last {{days}} days",
"input.insights.keystrokes": "Keystrokes",
"input.insights.clicks": "Clicks",
"input.insights.words": "Words typed",
"input.insights.sentences": "Sentences",
"input.insights.mouseDistance": "Mouse travel",
"input.insights.perDayMeters": " m/day",
"input.insights.phrases": "Personal phrases",
"input.insights.empty": "No activity collected yet.",
"input.insights.topApps": "Where you type most",
"input.insights.appRow": "{{keystrokes}} keys · {{clicks}} clicks",
"input.insights.privacyNote": "Only counters and distances are stored on this device. Key contents are never saved.",
"input.phrases.title": "Personal phrases",
"input.phrases.description": "Sentences learned from your typing and dictation, used to match your wording.",
"input.phrases.empty": "Nothing learned yet.",
"input.phrases.delete": "Delete phrase",
"input.feedback.excludedSaved": "Exclusions saved.",
"input.feedback.cleared": "Collected data deleted.",
"popup.suggestion.hintAccept": "Accept",
"popup.suggestion.hintNext": "Next",
"popup.suggestion.hintDismiss": "Dismiss",
"popup.suggestion.loading": "Generating…",
"keybinding.ui.sectionInput": "Input suggestions",
"keybinding.action.suggestionAccept": "Accept suggestion",
"keybinding.action.suggestionAccept.desc": "Insert the suggested sentence into the focused app.",
"keybinding.action.suggestionNext": "Next suggestion",
"keybinding.action.suggestionNext.desc": "Cycle to the next suggestion candidate.",
"keybinding.action.suggestionDismiss": "Dismiss suggestion",
"keybinding.action.suggestionDismiss.desc": "Hide the current suggestion.",
"input.suggestion.timeout": "Response limit (ms)",
"input.suggestion.latency": "Last response: {{ms}} ms",
"input.suggestion.slowWarning": "Slower than a typing-speed suggestion — try a smaller model or fewer candidates.",
"input.diagnostics.title": "Live check",
"input.diagnostics.app": "Focused app: {{app}}",
"input.diagnostics.unknownApp": "(unknown)",
"input.diagnostics.noSnapshot": "No field read yet — click into a text field and type.",
"input.diagnostics.readable": "Field is readable ({{source}}, {{length}} chars) — suggestions can run.",
"input.diagnostics.notReadable": "This app does not expose its text field — typing here cannot be read, so no suggestion is made.",
"input.diagnostics.password": "Password field — reading is blocked by design.",
"input.diagnostics.caretFallback": "Caret position unavailable; using the end of the document as the typing position.",
"input.diagnostics.composing": "IME composition in progress — suggestions wait a little longer, then still appear.",
"input.suggestion.onScreenLabel": "Overlay status",
"input.suggestion.onScreen": "On screen",
"input.suggestion.offScreen": "Hidden",
"input.suggestion.generating": "Generating…",
"input.kbView.knowledge": "Knowledge base",
"input.kbView.insights": "Input insights",
"input.insights.tabs.overview": "Overview",
"input.insights.tabs.keyboard": "Keyboard",
"input.insights.tabs.mouse": "Mouse",
"input.insights.tabs.apps": "Apps",
"input.insights.tabs.phrases": "Phrases · suggestions",
"input.insights.chars": "Characters typed",
"input.insights.wordChars": "Characters",
"input.insights.backspaces": "Backspaces",
"input.insights.shortcuts": "Shortcuts",
"input.insights.doubleClicks": "Double clicks",
"input.insights.scrollTicks": "Scroll ticks",
"input.insights.activeMinutes": "Active time",
"input.insights.activeDays": "Days recorded",
"input.insights.streak": "Longest streak",
"input.insights.peakDay": "Busiest day",
"input.insights.perDayAverage": "Daily average",
"input.insights.mouseDistanceTotal": "Total mouse travel",
"input.insights.hourlyTitle": "By hour (0-23)",
"input.insights.dailyTitle": "Daily trend",
"input.insights.wordsDailyTitle": "Words per day",
"input.insights.distanceDailyTitle": "Mouse travel per day",
"input.insights.topHoursHint": "Busiest hours: {{hours}}",
"input.insights.mouseNote": "Mouse travel is the sum of per-axis absolute deltas (Manhattan), the same measure ActivityWatch uses.",
"input.insights.appsHint": "Top apps by typing volume. The bar is that app’s share of all keystrokes.",
"input.insights.suggestions": "Suggestions",
"input.insights.suggestionsTotal": "Generated",
"input.insights.suggestionsAccepted": "Accepted",
"input.insights.acceptRate": "Accept rate",
"input.insights.avgLatency": "Average response",
"input.insights.suggestionHistory": "Recent suggestions",
"input.insights.accepted": "accepted",
"input.insights.notAccepted": "not accepted",
"input.insights.noSuggestions": "No suggestions recorded yet.",
"input.insights.samplesNote": "{{count}} learned samples.",
"input.insights.collectedAt": "Last capture {{at}}",
"input.insights.rangeLabel": "Range",
"input.insights.rangeDays": "{{days}} days",
"input.insights.headerSummary": "Last {{days}} days · {{keys}} keystrokes · {{apps}} apps",
"input.insights.disabledHint": "Input collection is off. Turn it on in Settings > Input and statistics will collect here.",
"input.insights.statsMovedHint": "Detailed statistics live in Knowledge base > Input insights.",
"input.chart.max": "max {{value}}",
"input.chart.noData": "No data yet.",
"input.unit.perDay": "/day",
"input.unit.perDayMeters": "m/day",
"input.unit.meters": "m",
"input.unit.ms": "ms",
"input.unit.percent": "%",
"popup.suggestion.warming": "Preparing model…",
"popup.suggestion.hintGenerating": "Generating…",
"keybinding.action.suggestionPrev": "Previous suggestion",
"keybinding.action.suggestionPrev.desc": "Move to the previous suggestion candidate.",
"input.insights.tabs.graph": "Graph",
"input.graph.description": "Your sentences are stored as nodes and their relations as edges (what follows what, which share terms) so suggestions can pull personal context. Local only.",
"input.graph.nodes": "Sentence nodes",
"input.graph.followsEdges": "Follows edges",
"input.graph.sharesEdges": "Term-sharing edges",
"input.graph.topEdges": "Strongest links",
"input.graph.recentNodes": "Recent nodes",
"input.graph.searchLabel": "Search a sentence",
"input.graph.searchPlaceholder": "e.g. meeting schedule",
"input.graph.searchAction": "Search",
"input.graph.neighbors": "Connected sentences",
"input.graph.empty": "The graph is empty. Enable \"Learn the text I type\" in Settings > Input and it fills up.",
"input.graph.kindFollows": "follows",
"input.graph.kindShares": "shares terms",
"popup.suggestion.generating": "Generating… ({{seconds}}s)",
"keybinding.ui.auditClear": "No shortcut conflicts or invalid settings.",
"keybinding.ui.auditIssues": "{{count}} shortcut issues",
"keybinding.ui.auditInvalid": "{{action}}: {{reason}}",
"keybinding.ui.auditConflict": "{{action}} conflicts with {{conflicts}}",
"keybinding.ui.auditUnknown": "Unknown issue",
"input.flow.title": "Likely flow hours",
"input.flow.empty": "Not enough hourly typing data yet.",
"input.flow.hour": "{{hour}}:00",
"input.flow.window": "Score {{score}} · {{minutes}} active min/day · {{friction}}% edits",
"input.friction.title": "Editing friction",
"input.friction.value": "{{count}} per 100 characters",
"input.friction.band.steady": "Steady",
"input.friction.band.watch": "Watch",
"input.friction.band.high": "High",
"input.appQuality.title": "Suggestion quality by app",
"input.appQuality.empty": "No per-app suggestion history yet.",
"input.appQuality.row": "{{accepted}}/{{total}} accepted · {{rate}}% · {{latency}}ms",
"input.phrases.metadata": "{{source}} · {{count}}× · {{app}}",
"input.phrases.appUnknown": "Shared",
"input.privacy.title": "Local data receipt",
"input.privacy.localOnly": "This data stays on this device.",
"input.privacy.rawKeys": "Raw individual key events and key codes are not retained. Learned text samples are listed separately below.",
"input.privacy.activityRetention": "Activity retention",
"input.privacy.suggestionRetention": "Suggestion retention",
"input.privacy.learnedRetention": "Learned text retention",
"input.privacy.activityBuckets": "Activity buckets",
"input.privacy.typingSamples": "Typing samples",
"input.privacy.personalPhrases": "Personal phrases",
"input.privacy.suggestions": "Suggestion records",
"input.privacy.days": "{{days}} days",
"input.privacy.untilDeleted": "Until deleted",
"input.exclusion.recommendation": "{{app}} had {{samples}} repeated unreadable inputs ({{reason}}).",
"input.exclusion.reason.repeated-unreadable": "repeatedly unreadable",
"input.exclusion.reason.repeated-empty": "repeatedly empty",
"input.exclusion.addButton": "Add {{app}} to exclusions",
"input.feedback.recommendationSaved": "Added {{app}} to exclusions.",
"popup.suggestion.sourceModel": "Local model",
"popup.suggestion.sourceMemory": "Local memory",
"popup.suggestion.continuations": "continuations",
"popup.suggestion.related": "related",
"popup.suggestion.phrases": "phrases",
"popup.suggestion.appPhrases": "app phrases",
"input.privacy.typingSamplesRetention": "Typed text sample retention",
"input.privacy.unavailable": "The local data receipt is unavailable right now. Counts and retention are not shown.",
"input.feedback.clearFailed": "Collected data could not be deleted.",
"input.feedback.excludedFailed": "Exclusions could not be saved.",
"input.feedback.recommendationFailed": "Could not add {{app}} to exclusions."
}