@plusonelabs/cue 0.0.93 → 0.0.95
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/bin/cue.js +10 -10
- package/bin/windows-bootstrap.ps1 +9 -9
- package/bin/windows-runtime-artifact.json +2 -2
- package/dist/cli.mjs +1088 -821
- package/dist/skills/README.md +199 -0
- package/dist/skills/_lib/credentials.py +72 -0
- package/dist/skills/activity/SKILL.md +97 -0
- package/dist/skills/assistant/SKILL.md +173 -0
- package/dist/skills/audio/SKILL.md +132 -0
- package/dist/skills/elevenlabs-tts/SKILL.md +76 -0
- package/dist/skills/elevenlabs-tts/scripts/speak.ts +226 -0
- package/dist/skills/event/SKILL.md +98 -0
- package/dist/skills/gemini-search/SKILL.md +52 -0
- package/dist/skills/gemini-search/generate.py +195 -0
- package/dist/skills/image/SKILL.md +169 -0
- package/dist/skills/like/SKILL.md +66 -0
- package/dist/skills/listen/SKILL.md +57 -0
- package/dist/skills/listen/scripts/listen.sh +74 -0
- package/dist/skills/listen/scripts/record.swift +94 -0
- package/dist/skills/markdown-to-pdf/SKILL.md +31 -0
- package/dist/skills/message/SKILL.md +136 -0
- package/dist/skills/mini-apps/SKILL.md +256 -0
- package/dist/skills/music/SKILL.md +139 -0
- package/dist/skills/nano-banana/SKILL.md +70 -0
- package/dist/skills/nano-banana/generate.py +191 -0
- package/dist/skills/news/SKILL.md +41 -0
- package/dist/skills/notify/SKILL.md +123 -0
- package/dist/skills/places/SKILL.md +215 -0
- package/dist/skills/posts/SKILL.md +440 -0
- package/dist/skills/project/SKILL.md +116 -0
- package/dist/skills/pulse/SKILL.md +106 -0
- package/dist/skills/reddit/SKILL.md +41 -0
- package/dist/skills/seeddance/SKILL.md +81 -0
- package/dist/skills/seeddance/generate.py +303 -0
- package/dist/skills/seedream/SKILL.md +86 -0
- package/dist/skills/seedream/generate.py +301 -0
- package/dist/skills/social-graph/SKILL.md +119 -0
- package/dist/skills/transcribe/SKILL.md +150 -0
- package/dist/skills/transcribe/generate.py +389 -0
- package/dist/skills/user/SKILL.md +180 -0
- package/dist/skills/veo3/SKILL.md +76 -0
- package/dist/skills/veo3/generate.py +339 -0
- package/dist/skills/video/SKILL.md +163 -0
- package/dist/skills/weather/SKILL.md +101 -0
- package/dist/skills/web-fetch/SKILL.md +43 -0
- package/dist/skills/web-search/SKILL.md +52 -0
- package/dist/skills/z-asr/SKILL.md +58 -0
- package/dist/skills/z-asr/generate.py +177 -0
- package/dist/skills/z-search/SKILL.md +57 -0
- package/dist/skills/z-search/generate.py +189 -0
- package/dist/skills/z-tts/SKILL.md +51 -0
- package/dist/skills/z-tts/generate.py +172 -0
- package/package.json +1 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: image
|
|
3
|
+
description: Generate images via `cue image`. Create app icons, illustrations, and artwork using AI image generation with customizable aspect ratios and resolutions.
|
|
4
|
+
category: media
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Generate images from text prompts
|
|
8
|
+
scope: first-party
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Generate images from text prompts using the Cue CLI.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- `cue` CLI installed and authenticated (`cue` then `/auth`)
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Generate an image
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cue image "prompt"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Images are saved to `~/.cue/images/` by default with auto-generated filenames.
|
|
26
|
+
|
|
27
|
+
### Save to specific path
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cue image "prompt" -o /path/to/output.png
|
|
31
|
+
cue image "prompt" --output /path/to/output.png
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Set aspect ratio
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cue image "prompt" --aspect-ratio 1:1 # Square (app icons)
|
|
38
|
+
cue image "prompt" --aspect-ratio 16:9 # Landscape (wallpapers)
|
|
39
|
+
cue image "prompt" --aspect-ratio 9:16 # Portrait (phone wallpapers)
|
|
40
|
+
cue image "prompt" -a 1:1 # Short form
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Available aspect ratios:**
|
|
44
|
+
|
|
45
|
+
- `1:1`, `square` - Square (1024x1024)
|
|
46
|
+
- `16:9`, `landscape` - Widescreen landscape
|
|
47
|
+
- `9:16`, `portrait` - Phone portrait
|
|
48
|
+
- `4:3`, `3:4`, `3:2`, `2:3`, `4:5`, `5:4`, `21:9`
|
|
49
|
+
|
|
50
|
+
### Use a specific model
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cue image "prompt" --model gemini-3.1-flash-image-preview # Default, fast
|
|
54
|
+
cue image "prompt" --model gemini-3-pro-image-preview # Higher quality, 4K support
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### High resolution (4K)
|
|
58
|
+
|
|
59
|
+
Only available with `gemini-3-pro-image-preview`:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cue image "prompt" --model gemini-3-pro-image-preview --resolution 4K
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Available resolutions:** `1K`, `2K`, `4K`
|
|
66
|
+
|
|
67
|
+
### Use a specific account
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cue auth list # List accounts
|
|
71
|
+
cue --profile cue:team image "prompt" -o icon.png
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Examples
|
|
75
|
+
|
|
76
|
+
### App icon
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cue image "a sudoku puzzle game icon, blue and white grid, minimal flat design" \
|
|
80
|
+
-o /tmp/sudoku-icon.png --aspect-ratio 1:1
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Cocktail recipe app icon
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
cue image "a cocktail recipe app icon, colorful martini glass with citrus garnish, minimal flat design" \
|
|
87
|
+
-o /tmp/cocktail-icon.png -a 1:1
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Illustration for a post
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
cue image "cozy coffee shop interior, warm lighting, watercolor style illustration" \
|
|
94
|
+
-o /tmp/coffee-shop.png
|
|
95
|
+
|
|
96
|
+
# Then upload and create post
|
|
97
|
+
cue media upload /tmp/coffee-shop.png
|
|
98
|
+
# Returns: {"media_id":"abc-123",...}
|
|
99
|
+
|
|
100
|
+
cue post '{"content":[{"type":"post","title":"Coffee Shop Vibes","media":[{"type":"image","media_id":"abc-123"}]}],"visibility":"public"}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Mini App Icon Workflow
|
|
104
|
+
|
|
105
|
+
Generate an icon for a mini app:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# 1. Generate icon (square, no rounded corners - iOS adds those automatically)
|
|
109
|
+
cue image "your app description, minimal flat design" \
|
|
110
|
+
-o /tmp/icon.png --aspect-ratio 1:1
|
|
111
|
+
|
|
112
|
+
# 2. Deploy with icon (auto-uploads to S3)
|
|
113
|
+
cue app deploy '{"app_id":"my-app","name":"My App","version":"1.0.0"}' \
|
|
114
|
+
--bundle ./dist/release/bundle.js \
|
|
115
|
+
--icon /tmp/icon.png
|
|
116
|
+
|
|
117
|
+
# 3. Publish
|
|
118
|
+
cue app publish my-app
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Or update an existing app's icon:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# 1. Generate new icon
|
|
125
|
+
cue image "updated app icon design" -o /tmp/new-icon.png -a 1:1
|
|
126
|
+
|
|
127
|
+
# 2. Upload and update (manual for now)
|
|
128
|
+
# See mini-apps skill for full workflow
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Prompt Tips
|
|
132
|
+
|
|
133
|
+
### For app icons
|
|
134
|
+
|
|
135
|
+
- Use "minimal flat design" or "flat icon" for clean icons
|
|
136
|
+
- **Do NOT include "iOS app icon style"** - this adds rounded corners which iOS applies automatically
|
|
137
|
+
- Specify colors: "blue and white", "gradient purple to pink"
|
|
138
|
+
- Mention the app purpose: "recipe app", "fitness tracker", "puzzle game"
|
|
139
|
+
- Always use `--aspect-ratio 1:1` for square icons
|
|
140
|
+
|
|
141
|
+
### For illustrations
|
|
142
|
+
|
|
143
|
+
- Specify style: "watercolor", "digital art", "photorealistic", "cartoon"
|
|
144
|
+
- Describe mood: "cozy", "energetic", "serene", "dramatic"
|
|
145
|
+
- Include lighting: "golden hour", "neon lights", "soft diffused light"
|
|
146
|
+
|
|
147
|
+
## Output
|
|
148
|
+
|
|
149
|
+
Images are saved as PNG files. The command outputs the saved path:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
Generating image: "a cocktail recipe app icon, colorful martini..."
|
|
153
|
+
Image saved to: /tmp/cocktail-icon.png
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Troubleshooting
|
|
157
|
+
|
|
158
|
+
| Error | Fix |
|
|
159
|
+
| ---------------------- | ------------------------------------------------------ |
|
|
160
|
+
| Not authenticated | Run `cue` then `/auth` to log in |
|
|
161
|
+
| Authentication expired | Re-authenticate with `/auth` |
|
|
162
|
+
| Invalid aspect ratio | Use supported ratio (1:1, 16:9, 9:16, etc.) |
|
|
163
|
+
| 4K not working | Only available with `gemini-3-pro-image-preview` model |
|
|
164
|
+
| Generation failed | Check prompt for policy violations, simplify if needed |
|
|
165
|
+
|
|
166
|
+
## Related
|
|
167
|
+
|
|
168
|
+
- [posts skill](../posts/SKILL.md) - Creating posts with images
|
|
169
|
+
- [mini-apps skill](../mini-apps/SKILL.md) - Deploying apps with icons
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: like
|
|
3
|
+
description: Like and bookmark posts. Accepts share IDs (short) or UUIDs.
|
|
4
|
+
category: comms
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Post likes and bookmarks
|
|
8
|
+
scope: first-party
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Like and bookmark posts via CLI. Accepts both share IDs (short, like `xK7bQ2mP`) and full UUIDs.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- `cue` CLI installed and authenticated (`cue` then `/auth`)
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Like a post
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cue like <post_id_or_share_id>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Unlike a post
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cue unlike <post_id_or_share_id>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Bookmark a post
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cue bookmark <post_id_or_share_id>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Remove a bookmark
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cue unbookmark <post_id_or_share_id>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Share ID Support
|
|
44
|
+
|
|
45
|
+
Posts have short share IDs (e.g., `xK7bQ2mP`) in addition to UUIDs. The CLI auto-detects which format you're using and resolves share IDs to UUIDs before calling the API.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cue like xK7bQ2mP # Using share ID
|
|
49
|
+
cue like 3cf5ad1c-... # Using UUID
|
|
50
|
+
cue bookmark xK7bQ2mP # Bookmark with share ID
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Use a specific account
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cue --profile cue:<account> like <post_id>
|
|
57
|
+
cue --profile cue:<account> bookmark <post_id>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Troubleshooting
|
|
61
|
+
|
|
62
|
+
| Error | Fix |
|
|
63
|
+
| -------------------------- | ------------------------------------------ |
|
|
64
|
+
| Not authenticated | Run `cue` then `/auth` to log in |
|
|
65
|
+
| Post not found | Check the post ID or share ID |
|
|
66
|
+
| Could not resolve share ID | Share ID doesn't exist or post was deleted |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: listen
|
|
3
|
+
description: Record from microphone and transcribe speech to text using local Whisper. Use when user wants to speak or dictate instead of typing.
|
|
4
|
+
category: media
|
|
5
|
+
type: hybrid
|
|
6
|
+
metadata:
|
|
7
|
+
scope: first-party
|
|
8
|
+
requires:
|
|
9
|
+
bins: [whisper]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Listen
|
|
13
|
+
|
|
14
|
+
Record from microphone and transcribe to text using local Whisper (free, no API key).
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- `whisper` (local): `brew install openai-whisper`
|
|
19
|
+
- `sox` (for recording): `brew install sox`
|
|
20
|
+
- Microphone permissions granted to terminal app
|
|
21
|
+
- Debug temp files (optional): `CUE_LISTEN_KEEP_TEMP=1 cue listen ...` keeps `/tmp/cue-listen-*` files
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Record for default 5 seconds, then transcribe
|
|
27
|
+
<skill-dir>/scripts/listen.sh
|
|
28
|
+
|
|
29
|
+
# Record for 10 seconds
|
|
30
|
+
<skill-dir>/scripts/listen.sh --duration 10
|
|
31
|
+
|
|
32
|
+
# Use a larger model for better accuracy (base, small, medium, large)
|
|
33
|
+
<skill-dir>/scripts/listen.sh --model medium
|
|
34
|
+
|
|
35
|
+
# CLI command wrapper
|
|
36
|
+
cue listen
|
|
37
|
+
cue listen --duration 30
|
|
38
|
+
cue listen --model medium -o transcript.txt
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Models
|
|
42
|
+
|
|
43
|
+
| Model | Speed | Accuracy | Size |
|
|
44
|
+
| -------- | ------------ | --------------------- | ----- |
|
|
45
|
+
| `base` | Fast (~2s) | Good for clear speech | 142MB |
|
|
46
|
+
| `small` | Medium (~5s) | Better | 466MB |
|
|
47
|
+
| `medium` | Slow (~10s) | Great | 1.5GB |
|
|
48
|
+
| `large` | Slowest | Best | 2.9GB |
|
|
49
|
+
|
|
50
|
+
Default is `base` for speed. Use `medium` if accuracy is important.
|
|
51
|
+
|
|
52
|
+
## How it works
|
|
53
|
+
|
|
54
|
+
1. Records audio from default microphone (via `sox` or `ffmpeg`)
|
|
55
|
+
2. Saves as WAV (16kHz mono)
|
|
56
|
+
3. Transcribes locally with Whisper
|
|
57
|
+
4. Outputs text to stdout
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Record from microphone and transcribe with Whisper
|
|
3
|
+
# Usage: listen.sh [--duration SECONDS] [--model MODEL]
|
|
4
|
+
|
|
5
|
+
DURATION=5
|
|
6
|
+
MODEL="base"
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
TMPBASE="/tmp/cue-listen-$$"
|
|
9
|
+
TMPWAV="$TMPBASE.wav"
|
|
10
|
+
WHISPER_STDERR="$TMPBASE.whisper.stderr.log"
|
|
11
|
+
KEEP_TEMP="${CUE_LISTEN_KEEP_TEMP:-0}"
|
|
12
|
+
|
|
13
|
+
while [[ $# -gt 0 ]]; do
|
|
14
|
+
case $1 in
|
|
15
|
+
--duration|-d) DURATION="$2"; shift 2 ;;
|
|
16
|
+
--model|-m) MODEL="$2"; shift 2 ;;
|
|
17
|
+
*) shift ;;
|
|
18
|
+
esac
|
|
19
|
+
done
|
|
20
|
+
|
|
21
|
+
cleanup() {
|
|
22
|
+
if [ "$KEEP_TEMP" = "1" ]; then
|
|
23
|
+
echo "Debug: keeping temp listen files at $TMPBASE.* (CUE_LISTEN_KEEP_TEMP=1)" >&2
|
|
24
|
+
return
|
|
25
|
+
fi
|
|
26
|
+
rm -f "$TMPWAV" "$WHISPER_STDERR" "$TMPBASE"*.txt "$TMPBASE"*.json "$TMPBASE"*.srt "$TMPBASE"*.vtt "$TMPBASE"*.tsv
|
|
27
|
+
}
|
|
28
|
+
trap cleanup EXIT
|
|
29
|
+
|
|
30
|
+
# Record using Swift (works on macOS with proper mic permissions)
|
|
31
|
+
swift "$SCRIPT_DIR/record.swift" --duration "$DURATION" --output "$TMPWAV"
|
|
32
|
+
if [ $? -ne 0 ] || [ ! -s "$TMPWAV" ]; then
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Transcribe with Whisper
|
|
37
|
+
if ! command -v whisper &>/dev/null; then
|
|
38
|
+
echo "Error: whisper not found. Install: brew install openai-whisper" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if ! whisper "$TMPWAV" --model "$MODEL" --output_format txt --output_dir /tmp --language en --fp16 False 2>"$WHISPER_STDERR"; then
|
|
43
|
+
if [ -s "$WHISPER_STDERR" ]; then
|
|
44
|
+
cat "$WHISPER_STDERR" >&2
|
|
45
|
+
fi
|
|
46
|
+
echo "Error: whisper command failed" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
TXTFILE=""
|
|
51
|
+
for candidate in "$TMPBASE.txt" "/tmp/$(basename "$TMPWAV").txt"; do
|
|
52
|
+
if [ -f "$candidate" ]; then
|
|
53
|
+
TXTFILE="$candidate"
|
|
54
|
+
break
|
|
55
|
+
fi
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
if [ -z "$TXTFILE" ]; then
|
|
59
|
+
if [ -s "$WHISPER_STDERR" ]; then
|
|
60
|
+
cat "$WHISPER_STDERR" >&2
|
|
61
|
+
fi
|
|
62
|
+
echo "Error: whisper did not produce a transcript file in /tmp" >&2
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
if [ ! -s "$TXTFILE" ]; then
|
|
67
|
+
if [ -s "$WHISPER_STDERR" ]; then
|
|
68
|
+
cat "$WHISPER_STDERR" >&2
|
|
69
|
+
fi
|
|
70
|
+
echo "Error: transcript is empty. Check microphone permissions/input and speak while recording." >&2
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
cat "$TXTFILE"
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env swift
|
|
2
|
+
|
|
3
|
+
import AVFoundation
|
|
4
|
+
import Foundation
|
|
5
|
+
|
|
6
|
+
let args = CommandLine.arguments
|
|
7
|
+
var duration: Double = 5
|
|
8
|
+
var outputPath = "/tmp/cue-recording.wav"
|
|
9
|
+
|
|
10
|
+
var i = 1
|
|
11
|
+
while i < args.count {
|
|
12
|
+
switch args[i] {
|
|
13
|
+
case "--duration", "-d":
|
|
14
|
+
i += 1
|
|
15
|
+
duration = Double(args[i]) ?? 5
|
|
16
|
+
case "--output", "-o":
|
|
17
|
+
i += 1
|
|
18
|
+
outputPath = args[i]
|
|
19
|
+
default:
|
|
20
|
+
break
|
|
21
|
+
}
|
|
22
|
+
i += 1
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let url = URL(fileURLWithPath: outputPath)
|
|
26
|
+
try? FileManager.default.removeItem(at: url)
|
|
27
|
+
|
|
28
|
+
let authStatus = AVCaptureDevice.authorizationStatus(for: .audio)
|
|
29
|
+
if authStatus == .denied || authStatus == .restricted {
|
|
30
|
+
fputs("Error: microphone access is denied.\n", stderr)
|
|
31
|
+
fputs("Grant access in: System Settings → Privacy & Security → Microphone\n", stderr)
|
|
32
|
+
exit(1)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if authStatus == .notDetermined {
|
|
36
|
+
let semaphore = DispatchSemaphore(value: 0)
|
|
37
|
+
var granted = false
|
|
38
|
+
AVCaptureDevice.requestAccess(for: .audio) { allowed in
|
|
39
|
+
granted = allowed
|
|
40
|
+
semaphore.signal()
|
|
41
|
+
}
|
|
42
|
+
_ = semaphore.wait(timeout: .now() + 10)
|
|
43
|
+
if !granted {
|
|
44
|
+
fputs("Error: microphone permission was not granted.\n", stderr)
|
|
45
|
+
fputs("Grant access in: System Settings → Privacy & Security → Microphone\n", stderr)
|
|
46
|
+
exit(1)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let audioDevices = AVCaptureDevice.devices(for: .audio)
|
|
51
|
+
if audioDevices.isEmpty {
|
|
52
|
+
fputs("Error: no audio input device detected.\n", stderr)
|
|
53
|
+
fputs("This Mac appears to have no active microphone input.\n", stderr)
|
|
54
|
+
fputs("Connect a USB/Bluetooth microphone and select it in System Settings → Sound → Input.\n", stderr)
|
|
55
|
+
exit(1)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let settings: [String: Any] = [
|
|
59
|
+
AVFormatIDKey: Int(kAudioFormatLinearPCM),
|
|
60
|
+
AVSampleRateKey: 16000,
|
|
61
|
+
AVNumberOfChannelsKey: 1,
|
|
62
|
+
AVLinearPCMBitDepthKey: 16,
|
|
63
|
+
AVLinearPCMIsFloatKey: false,
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
guard let recorder = try? AVAudioRecorder(url: url, settings: settings) else {
|
|
67
|
+
fputs("Error: could not create recorder. Check microphone permissions.\n", stderr)
|
|
68
|
+
fputs("Grant access in: System Settings → Privacy & Security → Microphone\n", stderr)
|
|
69
|
+
exit(1)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fputs("Recording for \(Int(duration))s... (speak now)\n", stderr)
|
|
73
|
+
recorder.prepareToRecord()
|
|
74
|
+
recorder.record(forDuration: duration)
|
|
75
|
+
|
|
76
|
+
Thread.sleep(forTimeInterval: duration + 0.5)
|
|
77
|
+
recorder.stop()
|
|
78
|
+
|
|
79
|
+
let fileSize = (try? FileManager.default.attributesOfItem(atPath: outputPath)[.size] as? Int) ?? 0
|
|
80
|
+
let frameCount = (try? AVAudioFile(forReading: url).length) ?? 0
|
|
81
|
+
|
|
82
|
+
if frameCount <= 0 {
|
|
83
|
+
fputs("Error: recording captured no audio frames.\n", stderr)
|
|
84
|
+
fputs("System Settings → Privacy & Security → Microphone → enable your terminal app\n", stderr)
|
|
85
|
+
fputs("Also check your input device and speak while recording.\n", stderr)
|
|
86
|
+
exit(1)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if fileSize <= 1000 {
|
|
90
|
+
fputs("Error: recording failed or too short.\n", stderr)
|
|
91
|
+
exit(1)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
fputs("Saved: \(outputPath) (\(fileSize) bytes, frames=\(frameCount))\n", stderr)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: markdown-to-pdf
|
|
3
|
+
description: Convert Markdown files to PDF via `cue md-to-pdf`. Use when user wants a local PDF export of notes, docs, plans, or proposals.
|
|
4
|
+
category: dev
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Convert Markdown to PDF
|
|
8
|
+
scope: first-party
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Convert Markdown files into polished PDFs locally.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- Node 20+
|
|
16
|
+
- Google Chrome or Chromium installed, or `CHROME_PATH` set explicitly
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cue md-to-pdf input.md output.pdf
|
|
22
|
+
cue md-to-pdf notes/today.md /tmp/today.pdf
|
|
23
|
+
cue md-to-pdf docs/roadmap.md roadmap.pdf --json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Notes
|
|
27
|
+
|
|
28
|
+
- Relative images and links are resolved from the Markdown file location
|
|
29
|
+
- Output path should end in `.pdf`
|
|
30
|
+
- `--json` returns structured `{ input, output }` metadata for scripting
|
|
31
|
+
- This skill is the thin discovery layer; the maintained implementation lives in Cue CLI TypeScript code
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: message
|
|
3
|
+
description: Manage inbox conversations and low-level conversation messages with `cue inbox` and `cue message`.
|
|
4
|
+
category: comms
|
|
5
|
+
type: context
|
|
6
|
+
metadata:
|
|
7
|
+
short-description: Inbox and messaging
|
|
8
|
+
scope: first-party
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Manage inbox conversations and send/read messages via CLI.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- `cue` CLI installed and authenticated (`cue` then `/auth`)
|
|
16
|
+
- Network access
|
|
17
|
+
- For `cue inbox sync` or `cue message send --to <name>`:
|
|
18
|
+
- Agent workspace configured (`cue agent init` or `--agent <name>`)
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Command help
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cue inbox -h
|
|
26
|
+
cue message -h
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### List conversations
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cue inbox
|
|
33
|
+
cue inbox list
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Sync inbox for name-based targeting
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cue inbox sync
|
|
40
|
+
cue message send --to "Project X" "[CLI] Ready for review"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Send a message by conversation ID
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cue message send <conversation_id> "[SCOPE] Your message here"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Read recent messages
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cue message read <conversation_id> 20
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Message Format
|
|
56
|
+
|
|
57
|
+
Include scope prefix for clarity:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
[CLI] Fixed notify to accept both positional and named flag syntax
|
|
61
|
+
[Backend] Added /api/v1/foo endpoint - CLI agents can now use it
|
|
62
|
+
[iOS] WebSocket reconnect issue fixed
|
|
63
|
+
[Sandbox] Network blocked, cannot send notifications
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## When to Post
|
|
67
|
+
|
|
68
|
+
- Found a bug that affects other agents/scopes
|
|
69
|
+
- Need something from another scope (API endpoint, feature, fix)
|
|
70
|
+
- Discovered a gotcha that others should know
|
|
71
|
+
- Blocked and need human or another agent's help
|
|
72
|
+
- Completed work that unblocks other agents
|
|
73
|
+
|
|
74
|
+
## Full CLI Usage
|
|
75
|
+
|
|
76
|
+
### List your conversations
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cue inbox # Default list command (default limit: 20)
|
|
80
|
+
cue inbox list # Explicit list command (default limit: 20)
|
|
81
|
+
cue inbox list 50 --compact # Compact human-readable output
|
|
82
|
+
cue message list # Compatibility alias for inbox listing
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Create a new group
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
cue inbox create "Group Name"
|
|
89
|
+
cue inbox create "Project X" user-id-1 user-id-2
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Sync inbox locally
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cue inbox sync
|
|
96
|
+
cue inbox sync # Default sync limit: 200
|
|
97
|
+
cue inbox sync 200 --json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`cue inbox sync` downloads the backend inbox list into the local agent workspace.
|
|
101
|
+
This is what powers name-based sends like `cue message send --to "Project X" ...`.
|
|
102
|
+
|
|
103
|
+
### Send message to any conversation
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cue message send <conversation_id> "Your message"
|
|
107
|
+
cue message send --to "Project X" "Your message" # Requires cue inbox sync
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Read messages from any conversation
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cue message read <conversation_id> # Default 20
|
|
114
|
+
cue message read <conversation_id> 50 # Read 50
|
|
115
|
+
cue message history <conversation_id> # Alias for read
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Use a specific account
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
cue --profile cue:<account> inbox
|
|
122
|
+
cue --profile cue:<account> inbox create "Group Name"
|
|
123
|
+
cue --profile cue:<account> message send <conversation_id> "Message"
|
|
124
|
+
cue --profile cue:<account> message read <conversation_id>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Troubleshooting
|
|
128
|
+
|
|
129
|
+
| Error | Fix |
|
|
130
|
+
| ------------------------------ | --------------------------------------------------------------------- |
|
|
131
|
+
| Not authenticated | Run `cue` then `/auth` to log in |
|
|
132
|
+
| fetch failed | Network blocked or backend unavailable |
|
|
133
|
+
| No conversation found for name | Run `cue inbox sync` first, or send using a conversation ID |
|
|
134
|
+
| No agent workspace configured | Run `cue agent init` or pass `--agent <name>` before `cue inbox sync` |
|
|
135
|
+
| 403 Forbidden | Not a member of the conversation |
|
|
136
|
+
| 404 Not Found | Conversation ID incorrect |
|