draftwatch 0.2.2__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {draftwatch-0.2.2 → draftwatch-0.2.4}/PKG-INFO +3 -1
  2. {draftwatch-0.2.2 → draftwatch-0.2.4}/README.md +2 -0
  3. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/app.py +61 -20
  4. draftwatch-0.2.4/draftwatch/assets/favicon.png +0 -0
  5. draftwatch-0.2.4/draftwatch/assets/icon.png +0 -0
  6. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch.egg-info/PKG-INFO +3 -1
  7. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch.egg-info/SOURCES.txt +2 -0
  8. {draftwatch-0.2.2 → draftwatch-0.2.4}/pyproject.toml +1 -1
  9. {draftwatch-0.2.2 → draftwatch-0.2.4}/LICENSE +0 -0
  10. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/__init__.py +0 -0
  11. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/__main__.py +0 -0
  12. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/assets/codemirror.js +0 -0
  13. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/assets/marked.js +0 -0
  14. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/assets/purify.js +0 -0
  15. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/assets/turndown.js +0 -0
  16. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/assets/xterm.css +0 -0
  17. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/assets/xterm.js +0 -0
  18. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch/term.py +0 -0
  19. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch.egg-info/dependency_links.txt +0 -0
  20. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch.egg-info/entry_points.txt +0 -0
  21. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch.egg-info/requires.txt +0 -0
  22. {draftwatch-0.2.2 → draftwatch-0.2.4}/draftwatch.egg-info/top_level.txt +0 -0
  23. {draftwatch-0.2.2 → draftwatch-0.2.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: draftwatch
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Review an AI agent's edits to your writing files as a real git word-diff — keep or revert changes hunk by hunk, then commit.
5
5
  Author: Mike Konczal
6
6
  License: MIT
@@ -22,6 +22,8 @@ Dynamic: license-file
22
22
 
23
23
  # Draftwatch
24
24
 
25
+ <img src="https://raw.githubusercontent.com/mtkonczal/Draftwatch/main/draftwatch/assets/icon.png" alt="DraftWatch logo: a white D on blue with equal coral and green revision marks" width="220">
26
+
25
27
  ![Draftwatch reviewing an agent's edits: your working text on the left in a real editor, the word diff against your baseline on the right. Click any change to revert it.](https://raw.githubusercontent.com/mtkonczal/Draftwatch/main/assets/draftwatch_screenshot.png)
26
28
 
27
29
  It’s difficult for writers to have AI act as an editor, because it’s never clear exactly what it changed. You can’t trust eyeballing it, but making the changes manually yourself means you don’t save much time. So you either ignore this potentially powerful writing helper, or you trust it at the risk that it does far more than you asked.
@@ -1,5 +1,7 @@
1
1
  # Draftwatch
2
2
 
3
+ <img src="https://raw.githubusercontent.com/mtkonczal/Draftwatch/main/draftwatch/assets/icon.png" alt="DraftWatch logo: a white D on blue with equal coral and green revision marks" width="220">
4
+
3
5
  ![Draftwatch reviewing an agent's edits: your working text on the left in a real editor, the word diff against your baseline on the right. Click any change to revert it.](https://raw.githubusercontent.com/mtkonczal/Draftwatch/main/assets/draftwatch_screenshot.png)
4
6
 
5
7
  It’s difficult for writers to have AI act as an editor, because it’s never clear exactly what it changed. You can’t trust eyeballing it, but making the changes manually yourself means you don’t save much time. So you either ignore this potentially powerful writing helper, or you trust it at the risk that it does far more than you asked.
@@ -40,7 +40,7 @@ TERM_SUPPORTED = _term is not None
40
40
  # Single source of truth for the version and the date of the latest release.
41
41
  # __init__.py re-exports __version__; the About panel shows both (injected into
42
42
  # the served page from these constants).
43
- __version__ = "0.2.2"
43
+ __version__ = "0.2.3"
44
44
  RELEASE_DATE = "2026-09-23"
45
45
 
46
46
  # Preferred port. When --port is not given, Draftwatch tries this first and
@@ -840,6 +840,7 @@ STATIC_ASSETS = {
840
840
  "marked.js": "application/javascript; charset=utf-8",
841
841
  "purify.js": "application/javascript; charset=utf-8",
842
842
  "turndown.js": "application/javascript; charset=utf-8",
843
+ "favicon.png": "image/png",
843
844
  }
844
845
 
845
846
 
@@ -1462,6 +1463,7 @@ INDEX_HTML = r"""<!DOCTYPE html>
1462
1463
  <meta name="referrer" content="no-referrer">
1463
1464
  <meta name="viewport" content="width=device-width, initial-scale=1">
1464
1465
  <title>Draftwatch</title>
1466
+ <link rel="icon" type="image/png" href="/static/favicon.png">
1465
1467
  <script src="/static/codemirror.js"></script>
1466
1468
  <script src="/static/marked.js"></script>
1467
1469
  <script src="/static/purify.js"></script>
@@ -1617,7 +1619,7 @@ INDEX_HTML = r"""<!DOCTYPE html>
1617
1619
 
1618
1620
  /* app chrome (native window via pywebview, ?app=1): the OS title bar
1619
1621
  already says "draftwatch · file", so the in-page wordmark is redundant —
1620
- drop it, tighten the toolbar, and make the chrome feel native (no text
1622
+ drop the word (the logo, outside .title, stays as the brand), tighten the toolbar, and make the chrome feel native (no text
1621
1623
  selection on controls, no web-page tells). */
1622
1624
  body.app-mode header .title { display: none; }
1623
1625
  body.app-mode header { padding: 5px 10px; }
@@ -1638,14 +1640,22 @@ INDEX_HTML = r"""<!DOCTYPE html>
1638
1640
  display: flex;
1639
1641
  flex-direction: column;
1640
1642
  }
1643
+ /* logo on the left, spanning both toolbar rows; the rows stack beside it */
1641
1644
  header {
1642
1645
  display: flex;
1643
- flex-direction: column;
1644
- gap: 6px;
1646
+ align-items: center;
1647
+ gap: 10px;
1645
1648
  padding: 8px 12px;
1646
1649
  border-bottom: 1px solid var(--border);
1647
1650
  background: var(--panel);
1648
1651
  }
1652
+ header .rows {
1653
+ flex: 1;
1654
+ min-width: 0;
1655
+ display: flex;
1656
+ flex-direction: column;
1657
+ gap: 6px;
1658
+ }
1649
1659
  /* Two fixed rows that never wrap into each other, so the layout stays put
1650
1660
  regardless of title length or window width:
1651
1661
  row 1 = what you're looking at (title, file picker, baseline selector —
@@ -1668,19 +1678,11 @@ INDEX_HTML = r"""<!DOCTYPE html>
1668
1678
  gap: 7px;
1669
1679
  letter-spacing: .02em;
1670
1680
  }
1671
- /* the +/− mark: the product in two characters (keep the add, strike the del) */
1672
- .mark {
1673
- display: inline-flex;
1674
- align-items: center;
1675
- background: var(--bg);
1676
- border: 1px solid var(--border);
1677
- border-radius: 5px;
1678
- padding: 0 5px;
1679
- font-weight: 700;
1680
- line-height: 1.45;
1681
- }
1682
- .mark .ma { color: var(--add-fg); }
1683
- .mark .md { color: var(--del-fg); text-decoration: line-through; }
1681
+ /* the logo: same drawing as the Dock icon and favicon (scripts/make_icon.py),
1682
+ inline so it stays crisp at any size. Fixed brand colors, not the accent. */
1683
+ .logo { width: 28px; height: 28px; flex: none; display: block; }
1684
+ header > .logo { width: 54px; height: 54px; }
1685
+ #about h2 .logo { width: 48px; height: 48px; }
1684
1686
  header .status { color: var(--muted); }
1685
1687
  header #status {
1686
1688
  flex: 1 1 auto;
@@ -2067,9 +2069,23 @@ INDEX_HTML = r"""<!DOCTYPE html>
2067
2069
  </style>
2068
2070
  </head>
2069
2071
  <body>
2072
+ <!-- logo geometry mirrors scripts/make_icon.py (1024 grid, tile at 100..924) -->
2073
+ <svg width="0" height="0" style="position:absolute" aria-hidden="true">
2074
+ <defs>
2075
+ <symbol id="dw-logo" viewBox="100 100 824 824">
2076
+ <rect x="100" y="100" width="824" height="824" rx="182" fill="#2f6fb0"/>
2077
+ <path fill="#f7fbff" fill-rule="evenodd"
2078
+ d="M314 251H461A257 257 0 0 1 461 765H314Z M425 354H461A154 154 0 0 1 461 662H425Z"/>
2079
+ <rect x="472" y="433" width="166" height="48" rx="24" fill="#f18d7f"/>
2080
+ <rect x="472" y="536" width="166" height="48" rx="24" fill="#85d296"/>
2081
+ </symbol>
2082
+ </defs>
2083
+ </svg>
2070
2084
  <header>
2085
+ <svg class="logo" aria-hidden="true"><use href="#dw-logo"/></svg>
2086
+ <div class="rows">
2071
2087
  <div class="bar">
2072
- <span class="title"><span class="mark"><span class="ma">+</span><span class="md">−</span></span>Draftwatch</span>
2088
+ <span class="title"><span class="word">Draftwatch</span></span>
2073
2089
  <span class="filepick">
2074
2090
  <label class="status" for="file-select">file</label>
2075
2091
  <select id="file-select" title="pick a writing file in this repo"></select>
@@ -2094,6 +2110,7 @@ INDEX_HTML = r"""<!DOCTYPE html>
2094
2110
  <button id="accent-toggle" title="accent color — click to cycle"><span class="swatch"></span><span id="accent-name">blue</span></button>
2095
2111
  <button id="about-btn" title="what is Draftwatch?">about</button>
2096
2112
  </div>
2113
+ </div>
2097
2114
  </header>
2098
2115
 
2099
2116
  <div id="banner">
@@ -2106,7 +2123,7 @@ INDEX_HTML = r"""<!DOCTYPE html>
2106
2123
  <div id="about" role="dialog" aria-modal="true" aria-label="About Draftwatch">
2107
2124
  <div class="card">
2108
2125
  <button class="about-close" id="about-close" title="close (Esc)">close ✕</button>
2109
- <h2><span class="mark"><span class="ma">+</span><span class="md">−</span></span>Draftwatch</h2>
2126
+ <h2><svg class="logo" aria-hidden="true"><use href="#dw-logo"/></svg>Draftwatch</h2>
2110
2127
  <p class="tag">Review an AI agent's edits as a real git diff — locally.</p>
2111
2128
  <p>An autonomous agent (Claude Code and the like) edits your files on disk.
2112
2129
  Draftwatch shows you exactly what changed, as the word-level diff
@@ -3799,6 +3816,30 @@ def _webview_available():
3799
3816
  return False
3800
3817
 
3801
3818
 
3819
+ def _app_identity_kwargs(webview):
3820
+ """Brand the native window as Draftwatch rather than the Python interpreter
3821
+ running it: the Dock icon (draftwatch/assets/icon.png, drawn by
3822
+ scripts/make_icon.py) and, on macOS, the app name in the menu bar and its
3823
+ About/Hide/Quit items. Best effort: any failure leaves pywebview's defaults.
3824
+ Returns the kwargs for webview.start()."""
3825
+ if sys.platform == "darwin":
3826
+ try:
3827
+ from Foundation import NSBundle # PyObjC, a pywebview dependency on macOS
3828
+ info = NSBundle.mainBundle().infoDictionary()
3829
+ if info is not None:
3830
+ info["CFBundleName"] = "Draftwatch"
3831
+ except Exception:
3832
+ pass
3833
+ icon = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets", "icon.png")
3834
+ try:
3835
+ import inspect
3836
+ takes_icon = "icon" in inspect.signature(webview.start).parameters
3837
+ except (TypeError, ValueError):
3838
+ takes_icon = False
3839
+ # start(icon=) arrived in pywebview 5; on 4.x the window just keeps its default
3840
+ return {"icon": icon} if takes_icon and os.path.isfile(icon) else {}
3841
+
3842
+
3802
3843
  def _run_app_window(url, title):
3803
3844
  """Open the UI in a native window (PyWebView). Returns True when the window
3804
3845
  ran and was closed by the user; False when unavailable, in which case the
@@ -3816,7 +3857,7 @@ def _run_app_window(url, title):
3816
3857
  try:
3817
3858
  webview.create_window(title, url, width=1280, height=860,
3818
3859
  min_size=(880, 560))
3819
- webview.start()
3860
+ webview.start(**_app_identity_kwargs(webview))
3820
3861
  return True
3821
3862
  except Exception as e:
3822
3863
  sys.stderr.write(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: draftwatch
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Review an AI agent's edits to your writing files as a real git word-diff — keep or revert changes hunk by hunk, then commit.
5
5
  Author: Mike Konczal
6
6
  License: MIT
@@ -22,6 +22,8 @@ Dynamic: license-file
22
22
 
23
23
  # Draftwatch
24
24
 
25
+ <img src="https://raw.githubusercontent.com/mtkonczal/Draftwatch/main/draftwatch/assets/icon.png" alt="DraftWatch logo: a white D on blue with equal coral and green revision marks" width="220">
26
+
25
27
  ![Draftwatch reviewing an agent's edits: your working text on the left in a real editor, the word diff against your baseline on the right. Click any change to revert it.](https://raw.githubusercontent.com/mtkonczal/Draftwatch/main/assets/draftwatch_screenshot.png)
26
28
 
27
29
  It’s difficult for writers to have AI act as an editor, because it’s never clear exactly what it changed. You can’t trust eyeballing it, but making the changes manually yourself means you don’t save much time. So you either ignore this potentially powerful writing helper, or you trust it at the risk that it does far more than you asked.
@@ -12,6 +12,8 @@ draftwatch.egg-info/entry_points.txt
12
12
  draftwatch.egg-info/requires.txt
13
13
  draftwatch.egg-info/top_level.txt
14
14
  draftwatch/assets/codemirror.js
15
+ draftwatch/assets/favicon.png
16
+ draftwatch/assets/icon.png
15
17
  draftwatch/assets/marked.js
16
18
  draftwatch/assets/purify.js
17
19
  draftwatch/assets/turndown.js
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "draftwatch"
7
- version = "0.2.2"
7
+ version = "0.2.4"
8
8
  description = "Review an AI agent's edits to your writing files as a real git word-diff — keep or revert changes hunk by hunk, then commit."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
File without changes
File without changes