@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.
- package/LICENSE.md +198 -0
- package/README.md +40 -0
- package/index.d.ts +4 -0
- package/index.js +9 -0
- package/package.json +87 -1
- package/skills/apple-notes/SKILL.md +92 -0
- package/skills/apple-notes/append-note.applescript +9 -0
- package/skills/apple-notes/cli.schema.json +32 -0
- package/skills/apple-notes/create-note.applescript +15 -0
- package/skills/apple-notes/delete-note.applescript +10 -0
- package/skills/apple-notes/edit-note.applescript +10 -0
- package/skills/apple-notes/read-note.applescript +28 -0
- package/skills/apple-notes/references/read.md +65 -0
- package/skills/apple-notes/references/write.md +105 -0
- package/skills/apple-notes/search-notes.applescript +21 -0
- package/skills/apple-reminders/SKILL.md +129 -0
- package/skills/apple-reminders/cli.schema.json +201 -0
- package/skills/apple-reminders/references/edit.md +69 -0
- package/skills/apple-reminders/references/view.md +58 -0
- package/skills/asana/SKILL.md +59 -0
- package/skills/diagrams/SKILL.md +107 -0
- package/skills/diagrams/references/class.md +29 -0
- package/skills/diagrams/references/er.md +27 -0
- package/skills/diagrams/references/flowchart.md +33 -0
- package/skills/diagrams/references/gantt.md +38 -0
- package/skills/diagrams/references/mindmap.md +35 -0
- package/skills/diagrams/references/pie.md +27 -0
- package/skills/diagrams/references/sequence.md +32 -0
- package/skills/diagrams/references/state.md +30 -0
- package/skills/diagrams/references/timeline.md +28 -0
- package/skills/excel/SKILL.md +120 -0
- package/skills/excel/references/create.md +374 -0
- package/skills/excel/references/edit.md +353 -0
- package/skills/excel/references/read.md +99 -0
- package/skills/github/SKILL.md +42 -0
- package/skills/gmail/SKILL.md +142 -0
- package/skills/gmail/operations.json +71 -0
- package/skills/google-calendar/SKILL.md +139 -0
- package/skills/google-calendar/operations.json +62 -0
- package/skills/google-docs/SKILL.md +74 -0
- package/skills/google-docs/operations.json +61 -0
- package/skills/google-docs/references/create.md +97 -0
- package/skills/google-docs/references/edit.md +146 -0
- package/skills/google-docs/references/read.md +49 -0
- package/skills/google-drive/SKILL.md +118 -0
- package/skills/google-drive/operations.json +40 -0
- package/skills/google-sheets/SKILL.md +71 -0
- package/skills/google-sheets/operations.json +85 -0
- package/skills/google-sheets/references/create.md +54 -0
- package/skills/google-sheets/references/edit.md +124 -0
- package/skills/google-sheets/references/read.md +74 -0
- package/skills/image-generation/SKILL.md +48 -0
- package/skills/music-generation/SKILL.md +76 -0
- package/skills/notion/SKILL.md +61 -0
- package/skills/notion/operations.json +53 -0
- package/skills/notion/references/comments.md +65 -0
- package/skills/notion/references/databases.md +68 -0
- package/skills/notion/references/pages.md +119 -0
- package/skills/notion/references/tasks.md +28 -0
- package/skills/obsidian/SKILL.md +122 -0
- package/skills/obsidian/cli.schema.json +392 -0
- package/skills/obsidian/references/read.md +79 -0
- package/skills/obsidian/references/write.md +67 -0
- package/skills/pdf/SKILL.md +110 -0
- package/skills/pdf/references/create.md +169 -0
- package/skills/pdf/references/transform.md +270 -0
- package/skills/pdf/scripts/decrypt.py +26 -0
- package/skills/pdf/scripts/encrypt.py +25 -0
- package/skills/pdf/scripts/extract_text.py +25 -0
- package/skills/pdf/scripts/merge.py +21 -0
- package/skills/pdf/scripts/rotate.py +27 -0
- package/skills/presentations/SKILL.md +118 -0
- package/skills/presentations/references/create.md +399 -0
- package/skills/presentations/references/edit.md +314 -0
- package/skills/presentations/references/read.md +127 -0
- package/skills/spotify/SKILL.md +86 -0
- package/skills/weather/SKILL.md +33 -0
- package/skills/word/SKILL.md +141 -0
- package/skills/word/references/create.md +368 -0
- package/skills/word/references/edit.md +704 -0
- package/skills/word/references/read.md +141 -0
- package/skills/word/references/replace.md +86 -0
- package/skills/word/scripts/list_paragraphs.py +19 -0
- 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.
|