We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Improve VSCode draft editor robustness
Users can lose drafts if window switch is too slow.  To address this issue, we propose the following:

- [x] Increase sleep timeout in https://github.com/knausj85/knausj_talon/blob/0d4ad8523b87c2fe10457b7fae7f2ba2f22ad735/draft_editor/draft_editor.py#L112
- [x] Keep last draft in memory, and have "draft submit" when outside of VSCode just submit the most recent draft.  That way if initial draft submit doesn't work, user can just say "draft submit" again
- [x] While we're here, add "draft top", which selects from cursor to start of document

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `draft_editor/draft_editor.py`
Content:
```
1 from talon import Context, Module, actions, ui
2 
3 mod = Module()
4 mod.tag("draft_editor_active", "Indicates whether the draft editor has been activated")
5 mod.tag(
6     "draft_editor_app_focused",
7     "Indicates that the draft editor app currently has focus",
8 )
9 
10 ctx = Context()
11 tags: set[str] = set()
12 
13 
14 def add_tag(tag: str):
15     tags.add(tag)
16     ctx.tags = list(tags)
17 
18 
19 def remove_tag(tag: str):
20     tags.discard(tag)
21     ctx.tags = list(tags)
22 
23 
24 default_names = ["Visual Studio Code", "Code", "VSCodium", "Codium", "code-oss"]
25 
26 setting_editor_names = mod.setting(
27     "draft_editor",
28     type=str,
29     default=None,
30     desc="List of application names to use for draft editor",
31 )
32 
33 
34 def get_editor_names():
35     names_csv = setting_editor_names.get()
36     return names_csv.split(", ") if names_csv else default_names
37 
38 
39 @mod.scope
40 def scope():
41     editor_names = get_editor_names()
42 
43     for app in ui.apps(background=False):
44         if app.name in editor_names:
45             return {"draft_editor_running": True}
46 
47     return {"draft_editor_running": False}
48 
49 
50 def handle_app_activate(app):
51     if app.name in get_editor_names():
52         add_tag("user.draft_editor_app_focused")
53     else:
54         remove_tag("user.draft_editor_app_focused")
55 
56 
57 ui.register("app_launch", scope.update)
58 ui.register("app_close", scope.update)
59 ui.register("app_activate", handle_app_activate)
60 
61 
62 original_window = None
63 
64 
65 @mod.action_class
66 class Actions:
67     def draft_editor_open():
68         """Open draft editor"""
69         global original_window
70         original_window = ui.active_window()
71         editor_app = get_editor_app()
72         selected_text = actions.edit.selected_text()
73         actions.user.switcher_focus_app(editor_app)
74         # Wait additional time for talon context to update.
75         actions.sleep("200ms")
76         actions.app.tab_open()
77         if selected_text != "":
78             actions.user.paste(selected_text)
79         add_tag("user.draft_editor_active")
80 
81     def draft_editor_submit():
82         """Submit/save draft editor"""
83         close_editor(submit_draft=True)
84 
85     def draft_editor_discard():
86         """Discard draft editor"""
87         close_editor(submit_draft=False)
88 
89 
90 def get_editor_app() -> ui.App:
91     editor_names = get_editor_names()
92 
93     for app in ui.apps(background=False):
94         if app.name in editor_names:
95             return app
96 
97     raise RuntimeError("Draft editor is not running")
98 
99 
100 def close_editor(submit_draft: bool):
101     remove_tag("user.draft_editor_active")
102     actions.edit.select_all()
103     selected_text = actions.edit.selected_text()
104     actions.edit.delete()
105     actions.app.tab_close()
106     actions.user.switcher_focus_window(original_window)
107     actions.sleep("200ms")
108     if submit_draft:
109         actions.user.paste(selected_text)
110
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/draft_editor/draft_editor.py b/draft_editor/draft_editor.py
--- a/draft_editor/draft_editor.py
+++ b/draft_editor/draft_editor.py
@@ -61,6 +61,8 @@
 
 original_window = None
 
+last_draft = None
+
 
 @mod.action_class
 class Actions:
@@ -86,6 +88,11 @@
         """Discard draft editor"""
         close_editor(submit_draft=False)
 
+    def draft_editor_paste_last():
+        """Paste last submitted draft"""
+        if last_draft:
+            actions.user.paste(last_draft)
+
 
 def get_editor_app() -> ui.App:
     editor_names = get_editor_names()
@@ -98,12 +105,14 @@
 
 
 def close_editor(submit_draft: bool):
+    global last_draft
     remove_tag("user.draft_editor_active")
     actions.edit.select_all()
     selected_text = actions.edit.selected_text()
     actions.edit.delete()
     actions.app.tab_close()
     actions.user.switcher_focus_window(original_window)
-    actions.sleep("200ms")
+    actions.sleep("300ms")
     if submit_draft:
+        last_draft = selected_text
         actions.user.paste(selected_text)

{"golden_diff": "diff --git a/draft_editor/draft_editor.py b/draft_editor/draft_editor.py\n--- a/draft_editor/draft_editor.py\n+++ b/draft_editor/draft_editor.py\n@@ -61,6 +61,8 @@\n \n original_window = None\n \n+last_draft = None\n+\n \n @mod.action_class\n class Actions:\n@@ -86,6 +88,11 @@\n         \"\"\"Discard draft editor\"\"\"\n         close_editor(submit_draft=False)\n \n+    def draft_editor_paste_last():\n+        \"\"\"Paste last submitted draft\"\"\"\n+        if last_draft:\n+            actions.user.paste(last_draft)\n+\n \n def get_editor_app() -> ui.App:\n     editor_names = get_editor_names()\n@@ -98,12 +105,14 @@\n \n \n def close_editor(submit_draft: bool):\n+    global last_draft\n     remove_tag(\"user.draft_editor_active\")\n     actions.edit.select_all()\n     selected_text = actions.edit.selected_text()\n     actions.edit.delete()\n     actions.app.tab_close()\n     actions.user.switcher_focus_window(original_window)\n-    actions.sleep(\"200ms\")\n+    actions.sleep(\"300ms\")\n     if submit_draft:\n+        last_draft = selected_text\n         actions.user.paste(selected_text)\n", "issue": "Improve VSCode draft editor robustness\nUsers can lose drafts if window switch is too slow.  To address this issue, we propose the following:\r\n\r\n- [x] Increase sleep timeout in https://github.com/knausj85/knausj_talon/blob/0d4ad8523b87c2fe10457b7fae7f2ba2f22ad735/draft_editor/draft_editor.py#L112\r\n- [x] Keep last draft in memory, and have \"draft submit\" when outside of VSCode just submit the most recent draft.  That way if initial draft submit doesn't work, user can just say \"draft submit\" again\r\n- [x] While we're here, add \"draft top\", which selects from cursor to start of document\n", "before_files": [{"content": "from talon import Context, Module, actions, ui\n\nmod = Module()\nmod.tag(\"draft_editor_active\", \"Indicates whether the draft editor has been activated\")\nmod.tag(\n    \"draft_editor_app_focused\",\n    \"Indicates that the draft editor app currently has focus\",\n)\n\nctx = Context()\ntags: set[str] = set()\n\n\ndef add_tag(tag: str):\n    tags.add(tag)\n    ctx.tags = list(tags)\n\n\ndef remove_tag(tag: str):\n    tags.discard(tag)\n    ctx.tags = list(tags)\n\n\ndefault_names = [\"Visual Studio Code\", \"Code\", \"VSCodium\", \"Codium\", \"code-oss\"]\n\nsetting_editor_names = mod.setting(\n    \"draft_editor\",\n    type=str,\n    default=None,\n    desc=\"List of application names to use for draft editor\",\n)\n\n\ndef get_editor_names():\n    names_csv = setting_editor_names.get()\n    return names_csv.split(\", \") if names_csv else default_names\n\n\n@mod.scope\ndef scope():\n    editor_names = get_editor_names()\n\n    for app in ui.apps(background=False):\n        if app.name in editor_names:\n            return {\"draft_editor_running\": True}\n\n    return {\"draft_editor_running\": False}\n\n\ndef handle_app_activate(app):\n    if app.name in get_editor_names():\n        add_tag(\"user.draft_editor_app_focused\")\n    else:\n        remove_tag(\"user.draft_editor_app_focused\")\n\n\nui.register(\"app_launch\", scope.update)\nui.register(\"app_close\", scope.update)\nui.register(\"app_activate\", handle_app_activate)\n\n\noriginal_window = None\n\n\n@mod.action_class\nclass Actions:\n    def draft_editor_open():\n        \"\"\"Open draft editor\"\"\"\n        global original_window\n        original_window = ui.active_window()\n        editor_app = get_editor_app()\n        selected_text = actions.edit.selected_text()\n        actions.user.switcher_focus_app(editor_app)\n        # Wait additional time for talon context to update.\n        actions.sleep(\"200ms\")\n        actions.app.tab_open()\n        if selected_text != \"\":\n            actions.user.paste(selected_text)\n        add_tag(\"user.draft_editor_active\")\n\n    def draft_editor_submit():\n        \"\"\"Submit/save draft editor\"\"\"\n        close_editor(submit_draft=True)\n\n    def draft_editor_discard():\n        \"\"\"Discard draft editor\"\"\"\n        close_editor(submit_draft=False)\n\n\ndef get_editor_app() -> ui.App:\n    editor_names = get_editor_names()\n\n    for app in ui.apps(background=False):\n        if app.name in editor_names:\n            return app\n\n    raise RuntimeError(\"Draft editor is not running\")\n\n\ndef close_editor(submit_draft: bool):\n    remove_tag(\"user.draft_editor_active\")\n    actions.edit.select_all()\n    selected_text = actions.edit.selected_text()\n    actions.edit.delete()\n    actions.app.tab_close()\n    actions.user.switcher_focus_window(original_window)\n    actions.sleep(\"200ms\")\n    if submit_draft:\n        actions.user.paste(selected_text)\n", "path": "draft_editor/draft_editor.py"}], "after_files": [{"content": "from talon import Context, Module, actions, ui\n\nmod = Module()\nmod.tag(\"draft_editor_active\", \"Indicates whether the draft editor has been activated\")\nmod.tag(\n    \"draft_editor_app_focused\",\n    \"Indicates that the draft editor app currently has focus\",\n)\n\nctx = Context()\ntags: set[str] = set()\n\n\ndef add_tag(tag: str):\n    tags.add(tag)\n    ctx.tags = list(tags)\n\n\ndef remove_tag(tag: str):\n    tags.discard(tag)\n    ctx.tags = list(tags)\n\n\ndefault_names = [\"Visual Studio Code\", \"Code\", \"VSCodium\", \"Codium\", \"code-oss\"]\n\nsetting_editor_names = mod.setting(\n    \"draft_editor\",\n    type=str,\n    default=None,\n    desc=\"List of application names to use for draft editor\",\n)\n\n\ndef get_editor_names():\n    names_csv = setting_editor_names.get()\n    return names_csv.split(\", \") if names_csv else default_names\n\n\n@mod.scope\ndef scope():\n    editor_names = get_editor_names()\n\n    for app in ui.apps(background=False):\n        if app.name in editor_names:\n            return {\"draft_editor_running\": True}\n\n    return {\"draft_editor_running\": False}\n\n\ndef handle_app_activate(app):\n    if app.name in get_editor_names():\n        add_tag(\"user.draft_editor_app_focused\")\n    else:\n        remove_tag(\"user.draft_editor_app_focused\")\n\n\nui.register(\"app_launch\", scope.update)\nui.register(\"app_close\", scope.update)\nui.register(\"app_activate\", handle_app_activate)\n\n\noriginal_window = None\n\nlast_draft = None\n\n\n@mod.action_class\nclass Actions:\n    def draft_editor_open():\n        \"\"\"Open draft editor\"\"\"\n        global original_window\n        original_window = ui.active_window()\n        editor_app = get_editor_app()\n        selected_text = actions.edit.selected_text()\n        actions.user.switcher_focus_app(editor_app)\n        # Wait additional time for talon context to update.\n        actions.sleep(\"200ms\")\n        actions.app.tab_open()\n        if selected_text != \"\":\n            actions.user.paste(selected_text)\n        add_tag(\"user.draft_editor_active\")\n\n    def draft_editor_submit():\n        \"\"\"Submit/save draft editor\"\"\"\n        close_editor(submit_draft=True)\n\n    def draft_editor_discard():\n        \"\"\"Discard draft editor\"\"\"\n        close_editor(submit_draft=False)\n\n    def draft_editor_paste_last():\n        \"\"\"Paste last submitted draft\"\"\"\n        if last_draft:\n            actions.user.paste(last_draft)\n\n\ndef get_editor_app() -> ui.App:\n    editor_names = get_editor_names()\n\n    for app in ui.apps(background=False):\n        if app.name in editor_names:\n            return app\n\n    raise RuntimeError(\"Draft editor is not running\")\n\n\ndef close_editor(submit_draft: bool):\n    global last_draft\n    remove_tag(\"user.draft_editor_active\")\n    actions.edit.select_all()\n    selected_text = actions.edit.selected_text()\n    actions.edit.delete()\n    actions.app.tab_close()\n    actions.user.switcher_focus_window(original_window)\n    actions.sleep(\"300ms\")\n    if submit_draft:\n        last_draft = selected_text\n        actions.user.paste(selected_text)\n", "path": "draft_editor/draft_editor.py"}]}