@orderful/droid 0.40.1 → 0.42.0
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/.claude-plugin/plugin.json +4 -0
- package/CHANGELOG.md +25 -0
- package/dist/bin/droid.js +216 -23
- package/dist/commands/integrations.d.ts.map +1 -1
- package/dist/commands/tui/components/IntegrationsDetails.d.ts +7 -1
- package/dist/commands/tui/components/IntegrationsDetails.d.ts.map +1 -1
- package/dist/commands/tui.d.ts.map +1 -1
- package/dist/integrations/atlassian/references/setup.md +59 -0
- package/dist/integrations/github/index.d.ts +6 -0
- package/dist/integrations/github/index.d.ts.map +1 -0
- package/dist/integrations/github/index.ts +17 -0
- package/dist/integrations/github/references/setup.md +61 -0
- package/dist/integrations/granola/references/setup.md +54 -0
- package/dist/lib/types.d.ts +12 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/tools/meeting/.claude-plugin/plugin.json +22 -0
- package/dist/tools/meeting/TOOL.yaml +15 -0
- package/dist/tools/meeting/commands/meeting.md +35 -0
- package/dist/tools/meeting/skills/meeting/SKILL.md +105 -0
- package/dist/tools/meeting/skills/meeting/references/export-workflow.md +87 -0
- package/dist/tools/share/.claude-plugin/plugin.json +22 -0
- package/dist/tools/share/TOOL.yaml +17 -0
- package/dist/tools/share/commands/share.md +32 -0
- package/dist/tools/share/skills/share/SKILL.md +211 -0
- package/package.json +1 -1
- package/src/commands/integrations.ts +45 -0
- package/src/commands/tui/components/IntegrationsDetails.tsx +185 -4
- package/src/commands/tui.tsx +63 -20
- package/src/integrations/atlassian/references/setup.md +59 -0
- package/src/integrations/github/index.ts +17 -0
- package/src/integrations/github/references/setup.md +61 -0
- package/src/integrations/granola/references/setup.md +54 -0
- package/src/lib/types.ts +15 -0
- package/src/tools/meeting/.claude-plugin/plugin.json +22 -0
- package/src/tools/meeting/TOOL.yaml +15 -0
- package/src/tools/meeting/commands/meeting.md +35 -0
- package/src/tools/meeting/skills/meeting/SKILL.md +105 -0
- package/src/tools/meeting/skills/meeting/references/export-workflow.md +87 -0
- package/src/tools/share/.claude-plugin/plugin.json +22 -0
- package/src/tools/share/TOOL.yaml +17 -0
- package/src/tools/share/commands/share.md +32 -0
- package/src/tools/share/skills/share/SKILL.md +211 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: meeting
|
|
3
|
+
description: "Work with meeting notes, summaries, and transcripts. Use when user asks about meetings, wants to review notes, search decisions, or export to codex. User prompts like 'what did we discuss today', 'summarise the tech design review', 'export my meeting with Thea to codex'."
|
|
4
|
+
argument-hint: "[search {query} | summary {title} | summarize {title} | export {title} | decisions | last week]"
|
|
5
|
+
allowed-tools: [Read, Write, Edit, Glob, Grep, Bash(droid:*)]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Meeting Skill
|
|
9
|
+
|
|
10
|
+
Work with meeting notes, summaries, and transcripts via Granola MCP.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- User asks about what was discussed in a meeting
|
|
15
|
+
- User wants a summary of a specific meeting
|
|
16
|
+
- User wants to search across meeting content for decisions/action items
|
|
17
|
+
- User asks to export meeting notes to codex
|
|
18
|
+
- Natural language like "what did we decide in the partner testing review?", "summarise my meeting with Thea", "what were the action items from today?"
|
|
19
|
+
|
|
20
|
+
## When NOT to Use
|
|
21
|
+
|
|
22
|
+
- Calendar scheduling or upcoming events (this is about past meeting content)
|
|
23
|
+
- User is explicitly asking for Granola app features (this skill does not control Granola)
|
|
24
|
+
|
|
25
|
+
## Prerequisites
|
|
26
|
+
|
|
27
|
+
Check if Granola MCP is available. Run:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
droid config --get integrations.granola.configured
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
If not configured, tell user:
|
|
34
|
+
> "Granola MCP is not connected. Run `/mcp` in Claude Code to add the Granola integration, then try again."
|
|
35
|
+
|
|
36
|
+
If connected, proceed.
|
|
37
|
+
|
|
38
|
+
## Commands
|
|
39
|
+
|
|
40
|
+
| Command | Action |
|
|
41
|
+
|---------|--------|
|
|
42
|
+
| `/meeting` | List recent meetings (this week) |
|
|
43
|
+
| `/meeting last week` | List meetings from last week |
|
|
44
|
+
| `/meeting search {query}` | Natural language search across all meetings |
|
|
45
|
+
| `/meeting summary {title}` | Quick summary from Granola (fast, no context cost) |
|
|
46
|
+
| `/meeting summarize {title}` | Context-aware summary using transcript + loaded project/codex context |
|
|
47
|
+
| `/meeting export {title}` | Export meeting to codex |
|
|
48
|
+
| `/meeting decisions` | Pull decisions from recent meetings |
|
|
49
|
+
|
|
50
|
+
Natural language is the primary interface. Users should not need these commands. Recognise meeting intent and route accordingly:
|
|
51
|
+
- "what did Calvin say about Mosaic?" → search
|
|
52
|
+
- "summarise the partner testing review" → summary or summarize
|
|
53
|
+
- "export today's standup to codex" → export
|
|
54
|
+
- "what decisions were made this week?" → decisions
|
|
55
|
+
|
|
56
|
+
## Procedures
|
|
57
|
+
|
|
58
|
+
### List meetings (`/meeting`, `/meeting last week`)
|
|
59
|
+
|
|
60
|
+
1. Use `ToolSearch` to load `mcp__granola__list_meetings`
|
|
61
|
+
2. Call with `time_range`: `"this_week"` (default) or `"last_week"`
|
|
62
|
+
3. Present results as a table: title, date, participants
|
|
63
|
+
|
|
64
|
+
### Search (`/meeting search {query}`)
|
|
65
|
+
|
|
66
|
+
1. Use `ToolSearch` to load `mcp__granola__query_granola_meetings`
|
|
67
|
+
2. Call with user's query
|
|
68
|
+
3. Preserve citation links in the response
|
|
69
|
+
4. Present the response to the user
|
|
70
|
+
|
|
71
|
+
### Quick summary (`/meeting summary {title}`)
|
|
72
|
+
|
|
73
|
+
1. First, list recent meetings to find the meeting ID matching `{title}` (fuzzy match)
|
|
74
|
+
2. Use `ToolSearch` to load `mcp__granola__get_meetings`
|
|
75
|
+
3. Call with the meeting ID
|
|
76
|
+
4. Present the structured summary to the user
|
|
77
|
+
|
|
78
|
+
### Context-aware summary (`/meeting summarize {title}`)
|
|
79
|
+
|
|
80
|
+
1. First, list recent meetings to find the meeting ID matching `{title}` (fuzzy match)
|
|
81
|
+
2. Warn user: "This will load the full transcript into context. The meeting was ~{duration}. Proceed, or use `/meeting summary` for a quicker Granola summary?"
|
|
82
|
+
3. If user confirms, use `ToolSearch` to load `mcp__granola__get_meeting_transcript`
|
|
83
|
+
4. Call with the meeting ID
|
|
84
|
+
5. Generate a summary that incorporates any loaded project context, codex knowledge, or brain docs
|
|
85
|
+
6. Alternative: use the Task tool with a subagent to process the transcript in a separate context window, then return a summary
|
|
86
|
+
|
|
87
|
+
### Decisions (`/meeting decisions`)
|
|
88
|
+
|
|
89
|
+
1. Use `ToolSearch` to load `mcp__granola__query_granola_meetings`
|
|
90
|
+
2. Call with query: "What decisions were made and what are the action items from recent meetings?"
|
|
91
|
+
3. Preserve citation links in the response
|
|
92
|
+
|
|
93
|
+
### Export (`/meeting export {title}`)
|
|
94
|
+
|
|
95
|
+
See `references/export-workflow.md` for the full procedure.
|
|
96
|
+
|
|
97
|
+
## Error Handling
|
|
98
|
+
|
|
99
|
+
| Error | Action |
|
|
100
|
+
|-------|--------|
|
|
101
|
+
| Granola MCP not available | Suggest `/mcp` to connect Granola |
|
|
102
|
+
| No meetings found for time range | Suggest a different time range |
|
|
103
|
+
| Meeting title not found | Show recent meetings, ask user to pick |
|
|
104
|
+
| Transcript too large for context | Offer subagent approach or fall back to Granola summary |
|
|
105
|
+
| Codex not in current context (export) | Prompt for destination (see export workflow) |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Export Workflow
|
|
2
|
+
|
|
3
|
+
Full procedure for `/meeting export {title}`.
|
|
4
|
+
|
|
5
|
+
## E1. Resolve Meeting
|
|
6
|
+
|
|
7
|
+
1. Use `ToolSearch` to load `mcp__granola__list_meetings`
|
|
8
|
+
2. Call with `time_range: "last_30_days"` to get recent meetings
|
|
9
|
+
3. Fuzzy-match `{title}` against meeting titles
|
|
10
|
+
4. If multiple matches, present list and ask user to pick
|
|
11
|
+
5. If no match, show recent meetings and ask user to clarify
|
|
12
|
+
|
|
13
|
+
## E2. Get Meeting Data
|
|
14
|
+
|
|
15
|
+
1. Use `ToolSearch` to load `mcp__granola__get_meetings`
|
|
16
|
+
2. Call with the resolved meeting ID
|
|
17
|
+
3. Extract: title, date, participants, summary
|
|
18
|
+
|
|
19
|
+
## E3. Resolve Destination
|
|
20
|
+
|
|
21
|
+
If codex is in current context (user has loaded a codex repo this session):
|
|
22
|
+
- Export to `{codex_repo}/meetings/{date}-{slugified-title}.md`
|
|
23
|
+
- Confirm with user: "Export to codex at meetings/{filename}?"
|
|
24
|
+
|
|
25
|
+
If no codex in context:
|
|
26
|
+
- Ask: "Where should I export this meeting?"
|
|
27
|
+
- Codex — "Which codex repo?" (list available via `droid config --get repos`)
|
|
28
|
+
- Brain — Export to brain vault as a meeting doc
|
|
29
|
+
- Clipboard — Copy formatted markdown to clipboard
|
|
30
|
+
- Terminal — Just print it here
|
|
31
|
+
|
|
32
|
+
## E4. Format Document
|
|
33
|
+
|
|
34
|
+
Generate markdown with this exact frontmatter structure:
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
title: "{meeting title}"
|
|
38
|
+
type: meeting
|
|
39
|
+
source: granola
|
|
40
|
+
source_url: "https://notes.granola.ai/d/{meeting_id}"
|
|
41
|
+
date: {YYYY-MM-DD}
|
|
42
|
+
participants: [{comma-separated names}]
|
|
43
|
+
exported: {YYYY-MM-DD}
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
# {meeting title}
|
|
47
|
+
|
|
48
|
+
**Date:** {full date and time}
|
|
49
|
+
**Participants:** {names with roles/orgs if available}
|
|
50
|
+
|
|
51
|
+
## Summary
|
|
52
|
+
|
|
53
|
+
{Granola's structured summary from get_meetings}
|
|
54
|
+
|
|
55
|
+
## Key Decisions
|
|
56
|
+
|
|
57
|
+
{Extract decisions from the summary, or note "No explicit decisions captured"}
|
|
58
|
+
|
|
59
|
+
## Action Items
|
|
60
|
+
|
|
61
|
+
{Extract action items from the summary, or note "No action items captured"}
|
|
62
|
+
|
|
63
|
+
## E5. Slugification Rules
|
|
64
|
+
|
|
65
|
+
Convert title to filename slug:
|
|
66
|
+
- Lowercase
|
|
67
|
+
- Replace spaces with hyphens
|
|
68
|
+
- Remove special characters except hyphens
|
|
69
|
+
- Strip leading/trailing hyphens
|
|
70
|
+
- Collapse multiple hyphens
|
|
71
|
+
|
|
72
|
+
Examples:
|
|
73
|
+
- "[Tech Design Review] Automated Partner Testing" → `automated-partner-testing`
|
|
74
|
+
- "Tyler / Bosun - Partner Testing" → `tyler-bosun-partner-testing`
|
|
75
|
+
- "🌅 Horizon Daily" → `horizon-daily`
|
|
76
|
+
|
|
77
|
+
Final filename: `{YYYY-MM-DD}-{slug}.md`
|
|
78
|
+
|
|
79
|
+
## E6. Write File
|
|
80
|
+
|
|
81
|
+
Write the formatted document to the resolved destination path.
|
|
82
|
+
|
|
83
|
+
## E7. Confirm
|
|
84
|
+
|
|
85
|
+
Tell the user:
|
|
86
|
+
- "Exported to: {path}"
|
|
87
|
+
- If codex: suggest committing the new file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "droid-share",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Share content to external platforms. Publish docs to Confluence or post summaries to Slack.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Orderful",
|
|
7
|
+
"url": "https://github.com/orderful"
|
|
8
|
+
},
|
|
9
|
+
"repository": "https://github.com/orderful/droid",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"droid",
|
|
13
|
+
"ai",
|
|
14
|
+
"share"
|
|
15
|
+
],
|
|
16
|
+
"skills": [
|
|
17
|
+
"./skills/share/SKILL.md"
|
|
18
|
+
],
|
|
19
|
+
"commands": [
|
|
20
|
+
"./commands/share.md"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: share
|
|
2
|
+
description: "Share content to external platforms. Publish docs to Confluence or post summaries to Slack."
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
status: beta
|
|
5
|
+
|
|
6
|
+
includes:
|
|
7
|
+
skills:
|
|
8
|
+
- name: share
|
|
9
|
+
required: true
|
|
10
|
+
commands:
|
|
11
|
+
- name: share
|
|
12
|
+
is_alias: false
|
|
13
|
+
agents: []
|
|
14
|
+
|
|
15
|
+
dependencies: []
|
|
16
|
+
|
|
17
|
+
config_schema: {}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: share
|
|
3
|
+
description: "Share content to external platforms. Publish docs to Confluence or post summaries to Slack with free-form instructions."
|
|
4
|
+
argument-hint: "[confluence|slack] [{file|#channel}] [-- {instructions}]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /share
|
|
8
|
+
|
|
9
|
+
**User invoked:** `/share $ARGUMENTS`
|
|
10
|
+
|
|
11
|
+
**Your task:** Invoke the **share skill** with these arguments.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
- `/share` → Interactive mode, prompts for platform and file
|
|
16
|
+
- `/share confluence` → Publish to Confluence, prompts for file
|
|
17
|
+
- `/share confluence path/to/file.md` → Publish specific file to Confluence
|
|
18
|
+
- `/share slack #eng` → Share to Slack channel, prompts for content
|
|
19
|
+
- `/share slack #eng -- summarise the action items from this meeting`
|
|
20
|
+
- `/share slack #eng-design -- TLDR of this research doc with a link`
|
|
21
|
+
|
|
22
|
+
## Quick Reference
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
/share # Interactive
|
|
26
|
+
/share confluence # Publish doc to Confluence
|
|
27
|
+
/share confluence {file} # Publish specific file
|
|
28
|
+
/share slack #channel # Share to Slack (prompts for content)
|
|
29
|
+
/share slack #channel -- {instructions} # Share with specific instructions
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
See the **share skill** for complete documentation.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: share
|
|
3
|
+
description: "Share content to external platforms. Publish docs to Confluence or post summaries to Slack. User prompts like 'share this to confluence', 'share on slack', 'post a summary to #eng'."
|
|
4
|
+
argument-hint: "[confluence|slack] [{file|#channel}] [-- {instructions}]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
[
|
|
7
|
+
Read,
|
|
8
|
+
Edit,
|
|
9
|
+
Glob,
|
|
10
|
+
Grep,
|
|
11
|
+
Bash(droid:*),
|
|
12
|
+
]
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Share Skill
|
|
16
|
+
|
|
17
|
+
Share content to external platforms. Two modes:
|
|
18
|
+
|
|
19
|
+
- **Confluence** — publish a full markdown file as a Confluence page (create or update)
|
|
20
|
+
- **Slack** — process content with free-form instructions and post the result to a channel
|
|
21
|
+
|
|
22
|
+
## Supported Platforms
|
|
23
|
+
|
|
24
|
+
| Platform | Backend | Mode |
|
|
25
|
+
|----------|---------|------|
|
|
26
|
+
| Confluence | Atlassian MCP (`mcp__claude_ai_Atlassian__*`) | Publish document as page |
|
|
27
|
+
| Slack | `droid integrations slack post` | Process + post message |
|
|
28
|
+
|
|
29
|
+
## Procedure
|
|
30
|
+
|
|
31
|
+
### 1. Resolve Platform
|
|
32
|
+
|
|
33
|
+
**If platform provided in arguments** (e.g. `confluence`, `slack`): use it directly.
|
|
34
|
+
|
|
35
|
+
**If not provided:** Ask the user: "Where do you want to share? (Confluence / Slack)"
|
|
36
|
+
|
|
37
|
+
Then branch to the appropriate flow below.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Confluence Flow
|
|
42
|
+
|
|
43
|
+
### C1. Resolve File
|
|
44
|
+
|
|
45
|
+
**If file path provided in arguments:** use it directly.
|
|
46
|
+
|
|
47
|
+
**If not provided:**
|
|
48
|
+
1. Check conversation context for an active file (e.g. brain doc being worked on)
|
|
49
|
+
2. If none, ask: "Which file would you like to publish?"
|
|
50
|
+
|
|
51
|
+
Read the file to confirm it exists.
|
|
52
|
+
|
|
53
|
+
### C2. Parse File
|
|
54
|
+
|
|
55
|
+
1. **Extract title:** Check YAML frontmatter for `title` field. If none, use the first `# heading`. If neither, use the filename without extension.
|
|
56
|
+
2. **Strip YAML frontmatter** from the content that will be sent (the `---` delimited block at the top). Keep the raw markdown body.
|
|
57
|
+
3. **Check for existing page ID:** Look for `confluence_page_id` in frontmatter — if present, this is an update rather than a create.
|
|
58
|
+
|
|
59
|
+
### C3. Verify Atlassian MCP Connection
|
|
60
|
+
|
|
61
|
+
Use `ToolSearch` to load `mcp__claude_ai_Atlassian__getAccessibleAtlassianResources`, then call it.
|
|
62
|
+
|
|
63
|
+
**If MCP is unavailable or errors:**
|
|
64
|
+
Tell the user: "Atlassian MCP is not connected. Run `/mcp` in Claude Code to add the Atlassian integration, then try again."
|
|
65
|
+
Stop here.
|
|
66
|
+
|
|
67
|
+
**If successful:**
|
|
68
|
+
- Extract the `id` (cloud ID) from the first accessible resource
|
|
69
|
+
- Mark integration as configured:
|
|
70
|
+
```bash
|
|
71
|
+
droid config --set "integrations.atlassian.configured=true"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### C4. Resolve Confluence Space
|
|
75
|
+
|
|
76
|
+
Use `ToolSearch` to load `mcp__claude_ai_Atlassian__getConfluenceSpaces`, then call it with the cloud ID.
|
|
77
|
+
|
|
78
|
+
Present the list of spaces to the user and ask them to pick one.
|
|
79
|
+
|
|
80
|
+
### C5. Resolve Parent Page (Optional)
|
|
81
|
+
|
|
82
|
+
Ask the user: "Place this page under a specific parent, or at the space root?"
|
|
83
|
+
|
|
84
|
+
If they want a parent:
|
|
85
|
+
- Use `mcp__claude_ai_Atlassian__getPagesInConfluenceSpace` to list top-level pages
|
|
86
|
+
- Let the user pick a parent page
|
|
87
|
+
- If they need to go deeper, use `mcp__claude_ai_Atlassian__getConfluencePageDescendants` to navigate
|
|
88
|
+
|
|
89
|
+
If space root: no parent ID needed.
|
|
90
|
+
|
|
91
|
+
### C6. Confirm Title
|
|
92
|
+
|
|
93
|
+
Pre-fill from the extracted title (step C2). Ask the user to confirm or edit.
|
|
94
|
+
|
|
95
|
+
### C7. Create or Update Page
|
|
96
|
+
|
|
97
|
+
#### Update (frontmatter has `confluence_page_id`)
|
|
98
|
+
|
|
99
|
+
1. **Check for comments:** Use `mcp__claude_ai_Atlassian__getConfluencePageInlineComments` and `mcp__claude_ai_Atlassian__getConfluencePageFooterComments` to check for comments on the existing page.
|
|
100
|
+
- If comments exist, warn: "This page has N comments that may reference content being replaced. Continue?"
|
|
101
|
+
- If user declines, stop.
|
|
102
|
+
|
|
103
|
+
2. **Update:** Use `mcp__claude_ai_Atlassian__updateConfluencePage` with:
|
|
104
|
+
- `id`: the `confluence_page_id` from frontmatter
|
|
105
|
+
- `title`: confirmed title
|
|
106
|
+
- `body`: markdown content (frontmatter stripped)
|
|
107
|
+
- `contentFormat`: `"markdown"`
|
|
108
|
+
|
|
109
|
+
#### Create (no existing page ID)
|
|
110
|
+
|
|
111
|
+
Use `mcp__claude_ai_Atlassian__createConfluencePage` with:
|
|
112
|
+
- `spaceId`: chosen space ID
|
|
113
|
+
- `title`: confirmed title
|
|
114
|
+
- `body`: markdown content (frontmatter stripped)
|
|
115
|
+
- `contentFormat`: `"markdown"`
|
|
116
|
+
- `parentId`: parent page ID (if chosen, otherwise omit)
|
|
117
|
+
|
|
118
|
+
### C8. Update Frontmatter
|
|
119
|
+
|
|
120
|
+
After successful create or update, use `Edit` to add/update frontmatter fields in the source file:
|
|
121
|
+
|
|
122
|
+
- `confluence_page_id`: the page ID from the response
|
|
123
|
+
- `confluence_url`: the page URL (construct from cloud URL + page `_links.webui` or similar)
|
|
124
|
+
- `confluence_last_shared`: ISO 8601 timestamp of when this was shared
|
|
125
|
+
|
|
126
|
+
If the file has no frontmatter, add a `---` delimited block at the top.
|
|
127
|
+
|
|
128
|
+
### C9. Return Result
|
|
129
|
+
|
|
130
|
+
Tell the user:
|
|
131
|
+
- "Published to Confluence: {url}"
|
|
132
|
+
- Or "Updated Confluence page: {url}"
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Slack Flow
|
|
137
|
+
|
|
138
|
+
### S1. Resolve Channel
|
|
139
|
+
|
|
140
|
+
**If `#channel` provided in arguments:** use it directly.
|
|
141
|
+
|
|
142
|
+
**If not provided:** Ask: "Which Slack channel?"
|
|
143
|
+
|
|
144
|
+
### S2. Resolve Source Content
|
|
145
|
+
|
|
146
|
+
**If file path provided in arguments:** read it.
|
|
147
|
+
|
|
148
|
+
**If not provided:**
|
|
149
|
+
1. Check conversation context for an active file (brain doc, codex doc, or any file being discussed)
|
|
150
|
+
2. If none, ask: "What content do you want to share?"
|
|
151
|
+
|
|
152
|
+
Read the file to get the full content.
|
|
153
|
+
|
|
154
|
+
### S3. Resolve Instructions
|
|
155
|
+
|
|
156
|
+
**If instructions provided after `--`:** use them.
|
|
157
|
+
|
|
158
|
+
**If not provided:** Ask: "How should I format this for Slack? (e.g. 'summarise the action items', 'TLDR with key decisions', 'list the open questions')"
|
|
159
|
+
|
|
160
|
+
### S4. Build Source Link
|
|
161
|
+
|
|
162
|
+
Check if the source content has a linkable reference:
|
|
163
|
+
|
|
164
|
+
| Source | Link format |
|
|
165
|
+
|--------|------------|
|
|
166
|
+
| File with `confluence_url` in frontmatter | Confluence page link |
|
|
167
|
+
| File in codex repo | Relative path reference |
|
|
168
|
+
| Brain doc with Obsidian path | Obsidian URI (for the user's own reference, not posted) |
|
|
169
|
+
| Other | File path (not posted — no useful link) |
|
|
170
|
+
|
|
171
|
+
If a meaningful URL exists (Confluence, GitHub), include it in the message.
|
|
172
|
+
|
|
173
|
+
### S5. Generate Message
|
|
174
|
+
|
|
175
|
+
Process the source content according to the user's instructions. The output should be a Slack-formatted message:
|
|
176
|
+
|
|
177
|
+
- Use Slack mrkdwn syntax (`*bold*`, `_italic_`, `• ` for bullets)
|
|
178
|
+
- Keep it concise — Slack messages should scan quickly
|
|
179
|
+
- If a source link is available, append it at the end: `:link: <{url}|View full document>`
|
|
180
|
+
- Do NOT dump the entire file — the point is to summarise/extract per the instructions
|
|
181
|
+
|
|
182
|
+
**Show the draft message to the user** and ask to confirm before posting.
|
|
183
|
+
|
|
184
|
+
### S6. Post to Slack
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
node -e 'process.stdout.write(JSON.stringify({channel:"{channel}",text:`{message}`,unfurl_links:false}))' | \
|
|
188
|
+
droid integrations slack post
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Check response for `"ok": true`.
|
|
192
|
+
|
|
193
|
+
### S7. Confirm
|
|
194
|
+
|
|
195
|
+
Tell the user: "Shared to #{channel}"
|
|
196
|
+
|
|
197
|
+
If there was a source link: "Included link to {source}"
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Error Handling
|
|
202
|
+
|
|
203
|
+
| Error | Action |
|
|
204
|
+
|-------|--------|
|
|
205
|
+
| Atlassian MCP not available | Suggest `/mcp` to connect Atlassian |
|
|
206
|
+
| No Confluence spaces returned | Check permissions — user may need Confluence access |
|
|
207
|
+
| Confluence create/update fails | Show error message from API response |
|
|
208
|
+
| No SLACK_USER_TOKEN | Suggest `droid integrations setup slack` |
|
|
209
|
+
| Slack post fails | Show error, offer to copy message to clipboard |
|
|
210
|
+
| File not found | Ask user to provide a valid path |
|
|
211
|
+
| No frontmatter to update | Create frontmatter block at top of file |
|