@qvac/skills 0.0.0 → 0.1.1

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 (84) hide show
  1. package/LICENSE.md +198 -0
  2. package/README.md +40 -0
  3. package/index.d.ts +4 -0
  4. package/index.js +9 -0
  5. package/package.json +87 -1
  6. package/skills/apple-notes/SKILL.md +92 -0
  7. package/skills/apple-notes/append-note.applescript +9 -0
  8. package/skills/apple-notes/cli.schema.json +32 -0
  9. package/skills/apple-notes/create-note.applescript +15 -0
  10. package/skills/apple-notes/delete-note.applescript +10 -0
  11. package/skills/apple-notes/edit-note.applescript +10 -0
  12. package/skills/apple-notes/read-note.applescript +28 -0
  13. package/skills/apple-notes/references/read.md +65 -0
  14. package/skills/apple-notes/references/write.md +105 -0
  15. package/skills/apple-notes/search-notes.applescript +21 -0
  16. package/skills/apple-reminders/SKILL.md +129 -0
  17. package/skills/apple-reminders/cli.schema.json +201 -0
  18. package/skills/apple-reminders/references/edit.md +69 -0
  19. package/skills/apple-reminders/references/view.md +58 -0
  20. package/skills/asana/SKILL.md +59 -0
  21. package/skills/diagrams/SKILL.md +107 -0
  22. package/skills/diagrams/references/class.md +29 -0
  23. package/skills/diagrams/references/er.md +27 -0
  24. package/skills/diagrams/references/flowchart.md +33 -0
  25. package/skills/diagrams/references/gantt.md +38 -0
  26. package/skills/diagrams/references/mindmap.md +35 -0
  27. package/skills/diagrams/references/pie.md +27 -0
  28. package/skills/diagrams/references/sequence.md +32 -0
  29. package/skills/diagrams/references/state.md +30 -0
  30. package/skills/diagrams/references/timeline.md +28 -0
  31. package/skills/excel/SKILL.md +120 -0
  32. package/skills/excel/references/create.md +374 -0
  33. package/skills/excel/references/edit.md +353 -0
  34. package/skills/excel/references/read.md +99 -0
  35. package/skills/github/SKILL.md +42 -0
  36. package/skills/gmail/SKILL.md +142 -0
  37. package/skills/gmail/operations.json +71 -0
  38. package/skills/google-calendar/SKILL.md +139 -0
  39. package/skills/google-calendar/operations.json +62 -0
  40. package/skills/google-docs/SKILL.md +74 -0
  41. package/skills/google-docs/operations.json +61 -0
  42. package/skills/google-docs/references/create.md +97 -0
  43. package/skills/google-docs/references/edit.md +146 -0
  44. package/skills/google-docs/references/read.md +49 -0
  45. package/skills/google-drive/SKILL.md +118 -0
  46. package/skills/google-drive/operations.json +40 -0
  47. package/skills/google-sheets/SKILL.md +71 -0
  48. package/skills/google-sheets/operations.json +85 -0
  49. package/skills/google-sheets/references/create.md +54 -0
  50. package/skills/google-sheets/references/edit.md +124 -0
  51. package/skills/google-sheets/references/read.md +74 -0
  52. package/skills/image-generation/SKILL.md +48 -0
  53. package/skills/music-generation/SKILL.md +76 -0
  54. package/skills/notion/SKILL.md +61 -0
  55. package/skills/notion/operations.json +53 -0
  56. package/skills/notion/references/comments.md +65 -0
  57. package/skills/notion/references/databases.md +68 -0
  58. package/skills/notion/references/pages.md +119 -0
  59. package/skills/notion/references/tasks.md +28 -0
  60. package/skills/obsidian/SKILL.md +122 -0
  61. package/skills/obsidian/cli.schema.json +392 -0
  62. package/skills/obsidian/references/read.md +79 -0
  63. package/skills/obsidian/references/write.md +67 -0
  64. package/skills/pdf/SKILL.md +110 -0
  65. package/skills/pdf/references/create.md +169 -0
  66. package/skills/pdf/references/transform.md +270 -0
  67. package/skills/pdf/scripts/decrypt.py +26 -0
  68. package/skills/pdf/scripts/encrypt.py +25 -0
  69. package/skills/pdf/scripts/extract_text.py +25 -0
  70. package/skills/pdf/scripts/merge.py +21 -0
  71. package/skills/pdf/scripts/rotate.py +27 -0
  72. package/skills/presentations/SKILL.md +118 -0
  73. package/skills/presentations/references/create.md +399 -0
  74. package/skills/presentations/references/edit.md +314 -0
  75. package/skills/presentations/references/read.md +127 -0
  76. package/skills/spotify/SKILL.md +86 -0
  77. package/skills/weather/SKILL.md +33 -0
  78. package/skills/word/SKILL.md +141 -0
  79. package/skills/word/references/create.md +368 -0
  80. package/skills/word/references/edit.md +704 -0
  81. package/skills/word/references/read.md +141 -0
  82. package/skills/word/references/replace.md +86 -0
  83. package/skills/word/scripts/list_paragraphs.py +19 -0
  84. package/skills/word/scripts/replace_paragraphs.py +58 -0
@@ -0,0 +1,105 @@
1
+ # Creating, Editing, and Deleting Notes
2
+
3
+ Four bundled operations cover every change. Run one per `exec` call as
4
+ `osascript {{SKILL_DIR}}/<file>.applescript <args...>`.
5
+
6
+ | Request | Command |
7
+ | ------------------------------- | ---------------------------------------------------------------- |
8
+ | "add a note" | `create-note.applescript "Title" '<h1>Title</h1>...'` |
9
+ | "add to note X" | `append-note.applescript "X" '<p>...</p>'` |
10
+ | "rewrite / replace note X" | search for its id, then `edit-note.applescript "<id>" '<h1>…'` |
11
+ | "delete note X" | search for its id, then `delete-note.applescript "<id>"` |
12
+
13
+ ## Getting a Note's Id
14
+
15
+ Edit and delete are id-based, not name-based (names collide). Get the stable
16
+ CoreData id from `search-notes.applescript` (argv: query) — it returns one
17
+ `<id>\t<name>` line per matching note. Run it ONCE, then use the id.
18
+
19
+ ```bash
20
+ osascript {{SKILL_DIR}}/search-notes.applescript "Daily Log"
21
+ ```
22
+
23
+ ## Create a Note
24
+
25
+ Apple Notes bodies are HTML, so they contain double quotes (e.g. `href="..."`).
26
+ ALWAYS pass the title and body as ARGUMENTS to `create-note.applescript` (argv:
27
+ name, body, optional folder). Wrap the HTML body in SINGLE quotes at the shell
28
+ level so its double quotes need no escaping. Never embed a body inside
29
+ `osascript -e '...'`: three nested quoting layers drop the closing `"`/`}` and
30
+ produce `syntax error: Expected "}"` and no note.
31
+
32
+ Plain note in the default folder:
33
+
34
+ ```bash
35
+ osascript {{SKILL_DIR}}/create-note.applescript "What is Bitcoin?" '<h1>What is Bitcoin?</h1><p>Bitcoin is <strong>digital gold</strong>. See <a href="https://bitcoin.org/">bitcoin.org</a>.</p>'
36
+ ```
37
+
38
+ In a specific folder (pass the folder name as a third argument):
39
+
40
+ ```bash
41
+ osascript {{SKILL_DIR}}/create-note.applescript "Sprint Planning" '<h1>Sprint Planning</h1><p>Items:</p><ul><li>Item 1</li></ul>' "Work"
42
+ ```
43
+
44
+ A note whose whole content is one line of text: that text IS the title, so the
45
+ body is the `<h1>` alone. Adding a `<p>` copy of it shows the text twice.
46
+
47
+ ```bash
48
+ osascript {{SKILL_DIR}}/create-note.applescript "Buy milk and eggs" '<h1>Buy milk and eggs</h1>'
49
+ ```
50
+
51
+ Rules:
52
+
53
+ - Use `<h1>` for the title (it shows as the note's first line), `<p>` for
54
+ paragraphs, `<ul>/<li>` for lists, `<b>/<i>` for emphasis. The `name`
55
+ argument names the note without adding a line to the body.
56
+ - Write every piece of content ONCE. Never follow the `<h1>` title with a `<p>`
57
+ that restates it — the note then shows the same text twice.
58
+ - The HTML body MUST be wrapped in single quotes `'...'`. HTML attribute quotes
59
+ (`"`) are then safe and need NO backslash escaping.
60
+ - If the body must contain an apostrophe `'`, close-escape-reopen it:
61
+ `...don'\''t...`.
62
+
63
+ ## Append to a Note
64
+
65
+ Pass the note name and the HTML fragment to append to
66
+ `append-note.applescript` (argv: noteName, htmlFragment):
67
+
68
+ ```bash
69
+ osascript {{SKILL_DIR}}/append-note.applescript "Daily Log" '<p>New entry: ...</p>'
70
+ ```
71
+
72
+ ## Edit a Note
73
+
74
+ Get the id first (see above), then pass the id and the COMPLETE replacement
75
+ body to `edit-note.applescript` (argv: noteId, replacementBody):
76
+
77
+ ```bash
78
+ osascript {{SKILL_DIR}}/edit-note.applescript "x-coredata://.../ICNote/p67" '<h1>Daily Log</h1><p>Updated content</p>'
79
+ ```
80
+
81
+ The replacement body must include the title as its first heading or line;
82
+ replacing `body` without it also replaces the note's visible title.
83
+
84
+ ## Delete a Note
85
+
86
+ Get the id first (see above), then pass it to `delete-note.applescript` (argv:
87
+ noteId):
88
+
89
+ ```bash
90
+ osascript {{SKILL_DIR}}/delete-note.applescript "x-coredata://.../ICNote/p67"
91
+ ```
92
+
93
+ Deletion moves the note to Recently Deleted; the user can restore it from Notes
94
+ for 30 days. Confirm the target with the user before deleting — there is no undo
95
+ prompt.
96
+
97
+ ## Common Mistakes
98
+
99
+ - Treating the body as plain text — it is HTML. Use HTML tags in the body argument.
100
+ - Repeating the title inside the body — write it once as the leading `<h1>`.
101
+ - Embedding an HTML body inside `osascript -e '...'` — the nested quotes break.
102
+ Use the bundled script and pass name/body as arguments.
103
+ - Forgetting to wrap the HTML body argument in single quotes — its `"` attribute
104
+ quotes will then break the shell command.
105
+ - Editing or deleting by name — both need the id from `search-notes.applescript`.
@@ -0,0 +1,21 @@
1
+ -- Find notes whose name or body contains a term. argv: query
2
+ -- An empty query returns EVERY note (list-all) — AppleScript's `contains ""` is
3
+ -- false, so the empty case is handled explicitly rather than via the filter.
4
+ -- Emits one match per line as `id<tab>name`, so the caller can then read by
5
+ -- name or edit/delete by the stable id (there is no other bundled way to get
6
+ -- a note's id). The query binds as data via argv, never into the script text.
7
+ on run argv
8
+ set q to item 1 of argv
9
+ set out to ""
10
+ tell application "Notes"
11
+ if q is "" then
12
+ set matches to every note
13
+ else
14
+ set matches to every note whose name contains q or body contains q
15
+ end if
16
+ repeat with n in matches
17
+ set out to out & (id of n) & tab & (name of n) & linefeed
18
+ end repeat
19
+ end tell
20
+ return out
21
+ end run
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: apple-reminders
3
+ description: Manage Apple Reminders through the local remindctl CLI — view, create, complete, and delete reminders, and manage lists, with date filters and JSON/plain output. macOS only.
4
+ tools: [exec(remindctl)]
5
+ platform: [darwin]
6
+ metadata:
7
+ {
8
+ "openclaw":
9
+ {
10
+ "requires": { "bins": ["remindctl"] },
11
+ "install":
12
+ [
13
+ {
14
+ "id": "homebrew",
15
+ "kind": "shell",
16
+ "bins": ["brew"],
17
+ "manual": true,
18
+ "label": "Install Homebrew",
19
+ "command": "/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
20
+ },
21
+ {
22
+ "id": "brew",
23
+ "kind": "brew",
24
+ "formula": "steipete/tap/remindctl",
25
+ "bins": ["remindctl"],
26
+ "label": "Install remindctl via Homebrew"
27
+ },
28
+ {
29
+ "id": "authorize",
30
+ "kind": "shell",
31
+ "command": "remindctl authorize",
32
+ "label": "Grant Reminders access"
33
+ }
34
+ ],
35
+ "setup":
36
+ {
37
+ "summary": "Apple Reminders works through the remindctl CLI. Install it with Homebrew, then grant Reminders access once.",
38
+ "routes":
39
+ [
40
+ {
41
+ "kind": "install",
42
+ "label": "Install remindctl",
43
+ "helpUrl": "https://github.com/steipete/remindctl",
44
+ "steps":
45
+ [
46
+ "Install Homebrew if you don't have it.",
47
+ "Run: brew install steipete/tap/remindctl",
48
+ "Run: remindctl authorize and allow Reminders access.",
49
+ "Reopen this Skills page — apple-reminders should show as ready."
50
+ ]
51
+ }
52
+ ]
53
+ }
54
+ }
55
+ }
56
+ ---
57
+
58
+ # Apple Reminders
59
+
60
+ Manage Apple Reminders through the local `remindctl` CLI. The CLI talks to the
61
+ macOS Reminders app and its lists, so reminders created here sync to the user's
62
+ iPhone and iPad.
63
+
64
+ ## Load the Recipe File First
65
+
66
+ This file carries no commands. The working commands live in two reference files
67
+ — load the one for the job with the `skill` tool BEFORE calling `exec`, then
68
+ copy its command and change only the arguments:
69
+
70
+ Each load is a real `skill` tool call — printing the call as JSON or text in
71
+ your reply loads nothing.
72
+
73
+ - **Viewing reminders and lists** — "what are my reminders", "what's due
74
+ today / tomorrow / this week", "what's overdue", "show my lists", "show my
75
+ Work reminders": call the `skill` tool with `name: "apple-reminders"` and
76
+ `file: "references/view.md"`.
77
+ - **Changing reminders and lists** — "remind me to X", "add X to my Y list",
78
+ "mark N done", "delete reminder", "create / delete a list": call the `skill`
79
+ tool with `name: "apple-reminders"` and `file: "references/edit.md"`. It also
80
+ covers finding the id a complete or delete needs.
81
+
82
+ Most requests are ONE command. Run that single command with `exec`, then answer
83
+ from its output.
84
+
85
+ ## Always Use the remindctl CLI — Never Shell Out
86
+
87
+ Reminders live in the macOS Reminders database. ALWAYS view and edit them with
88
+ `remindctl` commands via the `exec` tool. NEVER use `cat`, `ls`, `find`, `grep`,
89
+ `sqlite3`, filesystem paths, or AppleScript to reach the Reminders store — those
90
+ bypass `remindctl` and are wrong even when they appear to work. If a `remindctl`
91
+ command fails, correct its arguments and retry the `remindctl` command; do not
92
+ switch to shell or file tools.
93
+
94
+ Use `exec` only, one `remindctl` command per call. Do not chain with `&&`, `;`,
95
+ or pipes.
96
+
97
+ ## When to Use
98
+
99
+ - The user explicitly mentions "reminder" or the "Reminders app".
100
+ - Creating personal to-dos with due dates that should sync to iPhone/iPad.
101
+ - Viewing or managing Apple Reminders lists.
102
+
103
+ ## When NOT to Use
104
+
105
+ - Calendar events or appointments — those are not Reminders.
106
+ - Project or work task tracking — use Notion, GitHub Issues, or the task queue.
107
+ - The user says "remind me" but means a local alert or notification in this
108
+ app, not the Reminders app — ask: "Do you want this in Apple Reminders (syncs
109
+ to your phone) or as a local alert here?" and use this skill only for the
110
+ Apple Reminders answer.
111
+ - Notes — use Obsidian, Notion, or Apple Notes.
112
+
113
+ ## Setup and Availability
114
+
115
+ - macOS only. On any other platform, report that Apple Reminders is unavailable
116
+ and stop.
117
+ - Requires the `remindctl` binary: `brew install steipete/tap/remindctl`.
118
+ - The Reminders app must have granted access. Check with `remindctl status`;
119
+ request access with `remindctl authorize`.
120
+ - If a command fails because `remindctl` is missing or access is not granted,
121
+ report that clearly and ask the user to install or authorize — do not fall
122
+ back to another tool.
123
+
124
+ ## Output Policy
125
+
126
+ - Keep results small: the reminder title, its list, and its due date.
127
+ - After a successful command, finish with a concise visible answer.
128
+ - Do not dump every list or the full reminder database unless the user
129
+ explicitly asks.
@@ -0,0 +1,201 @@
1
+ {
2
+ "type": "object",
3
+ "additionalProperties": false,
4
+ "x-positionals": [
5
+ "date"
6
+ ],
7
+ "properties": {
8
+ "date": {
9
+ "type": "string"
10
+ },
11
+ "json": {
12
+ "type": "boolean"
13
+ },
14
+ "plain": {
15
+ "type": "boolean"
16
+ },
17
+ "quiet": {
18
+ "type": "boolean"
19
+ },
20
+ "today": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "properties": {
24
+ "json": {
25
+ "type": "boolean"
26
+ },
27
+ "plain": {
28
+ "type": "boolean"
29
+ },
30
+ "quiet": {
31
+ "type": "boolean"
32
+ }
33
+ },
34
+ "x-effect": "read"
35
+ },
36
+ "tomorrow": {
37
+ "type": "object",
38
+ "additionalProperties": false,
39
+ "properties": {
40
+ "json": {
41
+ "type": "boolean"
42
+ },
43
+ "plain": {
44
+ "type": "boolean"
45
+ },
46
+ "quiet": {
47
+ "type": "boolean"
48
+ }
49
+ },
50
+ "x-effect": "read"
51
+ },
52
+ "week": {
53
+ "type": "object",
54
+ "additionalProperties": false,
55
+ "properties": {
56
+ "json": {
57
+ "type": "boolean"
58
+ },
59
+ "plain": {
60
+ "type": "boolean"
61
+ },
62
+ "quiet": {
63
+ "type": "boolean"
64
+ }
65
+ },
66
+ "x-effect": "read"
67
+ },
68
+ "overdue": {
69
+ "type": "object",
70
+ "additionalProperties": false,
71
+ "properties": {
72
+ "json": {
73
+ "type": "boolean"
74
+ },
75
+ "plain": {
76
+ "type": "boolean"
77
+ },
78
+ "quiet": {
79
+ "type": "boolean"
80
+ }
81
+ },
82
+ "x-effect": "read"
83
+ },
84
+ "all": {
85
+ "type": "object",
86
+ "additionalProperties": false,
87
+ "properties": {
88
+ "json": {
89
+ "type": "boolean"
90
+ },
91
+ "plain": {
92
+ "type": "boolean"
93
+ },
94
+ "quiet": {
95
+ "type": "boolean"
96
+ }
97
+ },
98
+ "x-effect": "read"
99
+ },
100
+ "list": {
101
+ "type": "object",
102
+ "additionalProperties": false,
103
+ "properties": {
104
+ "name": {
105
+ "type": "string"
106
+ },
107
+ "create": {
108
+ "type": "boolean"
109
+ },
110
+ "delete": {
111
+ "type": "boolean"
112
+ },
113
+ "json": {
114
+ "type": "boolean"
115
+ },
116
+ "plain": {
117
+ "type": "boolean"
118
+ },
119
+ "quiet": {
120
+ "type": "boolean"
121
+ }
122
+ },
123
+ "x-positionals": [
124
+ "name"
125
+ ]
126
+ },
127
+ "add": {
128
+ "type": "object",
129
+ "additionalProperties": false,
130
+ "properties": {
131
+ "title": {
132
+ "type": "string"
133
+ },
134
+ "list": {
135
+ "type": "string"
136
+ },
137
+ "due": {
138
+ "type": "string"
139
+ },
140
+ "json": {
141
+ "type": "boolean"
142
+ },
143
+ "plain": {
144
+ "type": "boolean"
145
+ },
146
+ "quiet": {
147
+ "type": "boolean"
148
+ }
149
+ },
150
+ "x-positionals": [
151
+ "title"
152
+ ]
153
+ },
154
+ "complete": {
155
+ "type": "object",
156
+ "additionalProperties": false,
157
+ "properties": {
158
+ "ids": {
159
+ "type": "array",
160
+ "items": {
161
+ "type": "string"
162
+ }
163
+ }
164
+ },
165
+ "x-rest": "ids"
166
+ },
167
+ "delete": {
168
+ "type": "object",
169
+ "additionalProperties": false,
170
+ "properties": {
171
+ "id": {
172
+ "type": "string"
173
+ },
174
+ "force": {
175
+ "type": "boolean"
176
+ },
177
+ "ids": {
178
+ "type": "array",
179
+ "items": {
180
+ "type": "string"
181
+ }
182
+ }
183
+ },
184
+ "x-positionals": [
185
+ "id"
186
+ ],
187
+ "x-rest": "ids"
188
+ },
189
+ "status": {
190
+ "type": "object",
191
+ "additionalProperties": false,
192
+ "properties": {},
193
+ "x-effect": "read"
194
+ },
195
+ "authorize": {
196
+ "type": "object",
197
+ "additionalProperties": false,
198
+ "properties": {}
199
+ }
200
+ }
201
+ }
@@ -0,0 +1,69 @@
1
+ # Creating, Completing, and Deleting Reminders
2
+
3
+ One `remindctl` command per `exec` call, no chaining. Run `add` in the
4
+ foreground (the default): the exit code confirms whether the reminder was
5
+ created — never claim success unless the command succeeded.
6
+
7
+ | Request | Command |
8
+ | -------------------------------- | ------------------------------------------------ |
9
+ | "remind me to X" | `remindctl add --title "X"` |
10
+ | "remind me to X tomorrow" | `remindctl add --title "X" --due tomorrow` |
11
+ | "add X to my <List> list" | `remindctl add --title "X" --list Personal` |
12
+ | "mark X done" | `remindctl all --json` for its id, then `remindctl complete <id>` |
13
+ | "delete reminder X" | `remindctl all --json` for its id, then `remindctl delete <id> --force` |
14
+ | "create a list called X" | `remindctl list X --create` |
15
+ | "delete the list X" | `remindctl list X --delete` |
16
+
17
+ ## Create reminders
18
+
19
+ ```bash
20
+ remindctl add "Buy milk"
21
+ remindctl add --title "Call mom" --list Personal --due tomorrow
22
+ remindctl add --title "Meeting prep" --due "2026-02-15 09:00"
23
+ ```
24
+
25
+ `--due` accepts `today`, `tomorrow`, `YYYY-MM-DD`, `YYYY-MM-DD HH:mm`, and ISO
26
+ 8601 (`2026-01-04T12:34:56Z`). Without `--list` the reminder lands in the
27
+ default list.
28
+
29
+ ## Finding the id
30
+
31
+ `complete` and `delete` take reminder ids, and there is NO search command —
32
+ `remindctl search`, `remindctl show`, `remindctl find` all fail. Get the id
33
+ from a JSON view: `remindctl all --json` lists every reminder in every list,
34
+ including completed ones, one object per reminder with `id`, `title`,
35
+ `listName`, `dueDate`, `isCompleted`. Pick the entry whose `title` matches
36
+ what the user named and copy its `id` (a short prefix like `4A83` is enough).
37
+ Narrow with `remindctl list <Name> --json` or `remindctl today --json` when the
38
+ list or day is known.
39
+
40
+ ```bash
41
+ remindctl all --json
42
+ remindctl list Personal --json
43
+ ```
44
+
45
+ ## Complete / delete
46
+
47
+ ```bash
48
+ remindctl complete 4A83
49
+ remindctl complete 1 2 3
50
+ remindctl delete 4A83 --force
51
+ ```
52
+
53
+ Only delete a reminder when the user explicitly asks; prefer `complete` for
54
+ finished to-dos. `--force` skips the confirmation prompt, which cannot be
55
+ answered from `exec`.
56
+
57
+ ## Lists
58
+
59
+ ```bash
60
+ remindctl list Projects --create
61
+ remindctl list Work --delete
62
+ ```
63
+
64
+ ## Answering
65
+
66
+ Only the commands shown in this file exist; if one fails, fix its arguments
67
+ rather than inventing another subcommand. Confirm with the title, list, and due date of what changed. If the command
68
+ fails because `remindctl` is missing or access is denied, report that and ask
69
+ the user to install or authorize; never switch to another tool.
@@ -0,0 +1,58 @@
1
+ # Viewing Reminders and Lists
2
+
3
+ One `remindctl` command per `exec` call, no chaining. Pick the command from the
4
+ request and answer from its output.
5
+
6
+ | Request | Command |
7
+ | ---------------------------------------- | --------------------------- |
8
+ | "what are my reminders" / "due today" | `remindctl today` |
9
+ | "what's due tomorrow" / "this week" | `remindctl tomorrow` · `remindctl week` |
10
+ | "what's overdue" | `remindctl overdue` |
11
+ | "everything" / "all my reminders" | `remindctl all` |
12
+ | "what's due on <date>" | `remindctl 2026-01-04` |
13
+ | "show my reminder lists" | `remindctl list` |
14
+ | "show my <List> reminders" | `remindctl list Work` |
15
+
16
+ ## View by date
17
+
18
+ ```bash
19
+ remindctl today
20
+ remindctl tomorrow
21
+ remindctl week
22
+ remindctl overdue
23
+ remindctl all
24
+ remindctl 2026-01-04
25
+ ```
26
+
27
+ Date filters accept `today`, `tomorrow`, `yesterday`, `YYYY-MM-DD`,
28
+ `YYYY-MM-DD HH:mm`, and ISO 8601 (`2026-01-04T12:34:56Z`).
29
+
30
+ ## Lists
31
+
32
+ ```bash
33
+ remindctl list
34
+ remindctl list Work
35
+ ```
36
+
37
+ `remindctl list` alone names the lists; `remindctl list <Name>` shows the
38
+ reminders in that list, including ones without a due date.
39
+
40
+ ## Output formats
41
+
42
+ ```bash
43
+ remindctl today --json
44
+ remindctl today --plain
45
+ remindctl today --quiet
46
+ ```
47
+
48
+ Use `--json` when you need structured fields (ids, due dates) before a
49
+ follow-up command; the `id` field is what `complete` and `delete` take.
50
+ `remindctl all --json` covers every list including completed reminders. There
51
+ is no search command — filter the JSON view by `title` yourself.
52
+
53
+ ## Answering
54
+
55
+ Report the title, its list, and its due date for each reminder — not the whole
56
+ database. An empty result means nothing is due: say so plainly. If the command
57
+ fails because `remindctl` is missing or access is denied, report that and ask
58
+ the user to install or authorize; never switch to another tool.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: asana
3
+ description: Asana tasks, projects, and comments via the official Asana MCP server (OAuth). Also handles pasted app.asana.com task links.
4
+ tools: [mcp_call]
5
+ platform: [darwin, linux, win32]
6
+ credentials: [asana_mcp_access_token]
7
+ allow_list: [https://mcp.asana.com/v2/mcp]
8
+ mcp_reads: [get_task, get_tasks, get_my_tasks, get_projects, search_tasks, search_objects]
9
+ ---
10
+
11
+ # Asana
12
+
13
+ One wired transport: the official Asana MCP server (v2), authorized with a pre-registered Asana OAuth app.
14
+
15
+ Use the `mcp_call` tool against `https://mcp.asana.com/v2/mcp`. Authentication uses a pre-registered Asana MCP app (client ID and secret) with PKCE — the user connects "Asana" from the Asana skill's setup, which stores the access token under the credential key `asana_mcp_access_token`. If the credential is connected, act immediately and call the tool(s) — do NOT ask the user for a token. If the credential is missing (a tool result reports it), tell the user to connect "Asana"; do not attempt to drive OAuth yourself.
16
+
17
+ Sessions are automatic: `mcp_call` runs the initialize handshake itself and threads the session for you. Do NOT call `initialize` or `notifications/initialized`, and do NOT pass `sessionId`.
18
+
19
+ If a call returns `Status: 401`, the token is expired/invalid — tell the user to reconnect "Asana" from the Asana skill's setup.
20
+
21
+ ## Workflow
22
+
23
+ Pass the **tool name as `method`** and the **tool's args as `params`** directly. The MCP `url` must be a top-level field beside `method` and `params` — never put `url` inside `params`. Do NOT build a `{ "name": …, "arguments": … }` envelope, and do NOT pass `tokenCredentialKey` — the runtime wraps the envelope and injects the bearer token by host for you.
24
+
25
+ V2's tool set evolves. Call `tools/list` once before the first Asana operation in a conversation, then use the exact returned name and schema. Common tools include:
26
+
27
+ | tool | use for |
28
+ | --- | --- |
29
+ | `get_my_tasks` | list tasks assigned to the connected user |
30
+ | `get_tasks` / `search_tasks` | list or search tasks |
31
+ | `get_task` | fetch one task |
32
+ | `create_tasks` / `update_tasks` | create or update tasks |
33
+ | `search_objects` | find projects, users, teams, tags, or portfolios |
34
+ | `get_projects` | list projects in the authorized workspace |
35
+
36
+ If a tool is absent, do not invent or fall back to a V1 `asana_*` name. Explain the V2 limitation. If a call returns an input validation error, use the `tools/list` schema and retry the same tool once.
37
+
38
+ ### Example: list my tasks
39
+
40
+ ```json
41
+ {
42
+ "url": "https://mcp.asana.com/v2/mcp",
43
+ "method": "get_my_tasks",
44
+ "params": {}
45
+ }
46
+ ```
47
+
48
+ ## Tool choice and pasted links
49
+
50
+ - Use `mcp_call` only. NEVER use `http_request` for Asana, and NEVER fetch `app.asana.com` URLs — they serve the browser login page, not data.
51
+ - When the user pastes an Asana link, extract the task gid and pass it to the matching MCP tool: the number after `/task/` (`…/project/<p>/task/1215448540812360` → `1215448540812360`), or the last path segment in the older `app.asana.com/0/<project>/<task>` form.
52
+
53
+ ## Output Policy
54
+
55
+ - Always quote the task `gid` when reporting tasks back so follow-up actions stay deterministic.
56
+ - Surface workspace and project names, not just GIDs, when human-friendly.
57
+ - For list responses, show name, assignee, due date, and completion state. Fetch full detail only on request.
58
+ - Confirm with the user before deleting anything — task deletion is permanent and takes subtasks with it.
59
+ - Do not ask for or echo credentials in chat. If a tool result reports the credential is missing, tell the user to connect "Asana" from the Asana skill's setup.