twentythree-skills 1.0.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/README.md +47 -0
- package/bin/add.js +103 -0
- package/package.json +46 -0
- package/skills/SKILL.md +211 -0
- package/skills/reference/action.md +233 -0
- package/skills/reference/analytics.md +337 -0
- package/skills/reference/app.md +160 -0
- package/skills/reference/audience.md +377 -0
- package/skills/reference/category.md +123 -0
- package/skills/reference/collector.md +103 -0
- package/skills/reference/comment.md +225 -0
- package/skills/reference/openupload.md +138 -0
- package/skills/reference/player.md +192 -0
- package/skills/reference/poll.md +174 -0
- package/skills/reference/presentation.md +99 -0
- package/skills/reference/protection.md +131 -0
- package/skills/reference/session.md +98 -0
- package/skills/reference/setting.md +115 -0
- package/skills/reference/site.md +94 -0
- package/skills/reference/spot.md +188 -0
- package/skills/reference/tag.md +93 -0
- package/skills/reference/thumbnail.md +224 -0
- package/skills/reference/user.md +216 -0
- package/skills/reference/video.md +631 -0
- package/skills/reference/webhook.md +151 -0
- package/skills/reference/webinar.md +1371 -0
- package/skills/workflows/upload-and-publish.md +146 -0
- package/skills/workflows/webinar-lifecycle.md +209 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# twentythree-skills
|
|
2
|
+
|
|
3
|
+
AI agent skills for the [TwentyThree CLI](https://github.com/23/twentythree-cli) — installable markdown skill definitions for Claude Code, OpenAI Codex, GitHub Copilot, and Cursor.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx twentythree-skills
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Detects your agent runtime and copies skill files into the right location automatically. Run again at any time to update — it's idempotent.
|
|
12
|
+
|
|
13
|
+
**Project-local install:**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx twentythree-skills --project
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Installs into `.claude/skills/`, `.agents/skills/`, `.github/skills/`, or `.cursor/skills/` relative to the current directory.
|
|
20
|
+
|
|
21
|
+
## What's included
|
|
22
|
+
|
|
23
|
+
- `skills/SKILL.md` — root skill file: auth setup, command syntax, resource index, `--agent` flag docs
|
|
24
|
+
- `skills/reference/*.md` — 22 reference files, one per TwentyThree CLI resource group (video, webinar, analytics, …)
|
|
25
|
+
- `skills/workflows/*.md` — workflow files for high-value automation patterns (video upload, webinar lifecycle)
|
|
26
|
+
|
|
27
|
+
## Supported runtimes
|
|
28
|
+
|
|
29
|
+
| Runtime | Detection | Global install path |
|
|
30
|
+
|---------|-----------|---------------------|
|
|
31
|
+
| Claude Code | `~/.claude/` | `~/.claude/skills/twentythree/` |
|
|
32
|
+
| OpenAI Codex | `~/.codex/` | `~/.codex/skills/twentythree/` |
|
|
33
|
+
| GitHub Copilot | `~/.github/copilot/` | `~/.github/skills/twentythree/` |
|
|
34
|
+
| Cursor | `~/.cursor/` | `~/.cursor/skills/twentythree/` |
|
|
35
|
+
|
|
36
|
+
## Prerequisites
|
|
37
|
+
|
|
38
|
+
The skills document the [twentythree-cli](https://www.npmjs.com/package/twentythree-cli). Install and authenticate it first:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install -g twentythree-cli
|
|
42
|
+
twentythree auth credentials
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
package/bin/add.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// bin/add.js — TwentyThree Skills installer
|
|
3
|
+
// Node.js built-ins only. ESM. No build step. Target: < 150 lines.
|
|
4
|
+
|
|
5
|
+
import { existsSync, mkdirSync, cpSync, readdirSync } from 'node:fs'
|
|
6
|
+
import { join, dirname, relative } from 'node:path'
|
|
7
|
+
import { homedir } from 'node:os'
|
|
8
|
+
import { fileURLToPath } from 'node:url'
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
11
|
+
const skillsSource = join(__dirname, '..', 'skills')
|
|
12
|
+
const home = homedir()
|
|
13
|
+
const cwd = process.cwd()
|
|
14
|
+
const isProject = process.argv.includes('--project')
|
|
15
|
+
|
|
16
|
+
const RUNTIMES = [
|
|
17
|
+
{
|
|
18
|
+
name: 'Claude Code',
|
|
19
|
+
detect: join(home, '.claude'),
|
|
20
|
+
globalDest: join(home, '.claude', 'skills', 'twentythree'),
|
|
21
|
+
projectDest: join(cwd, '.claude', 'skills', 'twentythree'),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'OpenAI Codex',
|
|
25
|
+
detect: join(home, '.codex'),
|
|
26
|
+
globalDest: join(home, '.codex', 'skills', 'twentythree'),
|
|
27
|
+
projectDest: join(cwd, '.agents', 'skills', 'twentythree'),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'GitHub Copilot',
|
|
31
|
+
detect: join(home, '.github', 'copilot'),
|
|
32
|
+
globalDest: join(home, '.github', 'skills', 'twentythree'),
|
|
33
|
+
projectDest: join(cwd, '.github', 'skills', 'twentythree'),
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Cursor',
|
|
37
|
+
detect: join(home, '.cursor'),
|
|
38
|
+
globalDest: join(home, '.cursor', 'skills', 'twentythree'),
|
|
39
|
+
projectDest: join(cwd, '.cursor', 'skills', 'twentythree'),
|
|
40
|
+
},
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
function walkDir(dir) {
|
|
44
|
+
const files = []
|
|
45
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
46
|
+
if (entry.isSymbolicLink()) continue
|
|
47
|
+
const full = join(dir, entry.name)
|
|
48
|
+
if (entry.isDirectory()) {
|
|
49
|
+
files.push(...walkDir(full))
|
|
50
|
+
} else {
|
|
51
|
+
files.push(full)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return files
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function shortPath(abs) {
|
|
58
|
+
if (abs.startsWith(home)) return '~' + abs.slice(home.length)
|
|
59
|
+
if (abs.startsWith(cwd + '/')) return '.' + abs.slice(cwd.length)
|
|
60
|
+
if (abs === cwd) return '.'
|
|
61
|
+
return abs
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function installTo(destRoot, label) {
|
|
65
|
+
mkdirSync(destRoot, { recursive: true })
|
|
66
|
+
console.log(`\n${label}`)
|
|
67
|
+
for (const absFile of walkDir(skillsSource)) {
|
|
68
|
+
const rel = relative(skillsSource, absFile)
|
|
69
|
+
const destFile = join(destRoot, rel)
|
|
70
|
+
mkdirSync(dirname(destFile), { recursive: true })
|
|
71
|
+
try {
|
|
72
|
+
cpSync(absFile, destFile, { dereference: false })
|
|
73
|
+
console.log(` ✓ ${rel}`)
|
|
74
|
+
} catch (err) {
|
|
75
|
+
console.error(` ✗ Error installing ${rel}: ${err.message}`)
|
|
76
|
+
process.exitCode = 1
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!existsSync(skillsSource)) {
|
|
82
|
+
console.error('Skills source directory not found. The package may be corrupted.')
|
|
83
|
+
process.exit(1)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const detected = RUNTIMES.filter(r => existsSync(r.detect))
|
|
87
|
+
|
|
88
|
+
if (detected.length === 0) {
|
|
89
|
+
const checked = RUNTIMES.map(r => shortPath(r.detect)).join(' ')
|
|
90
|
+
console.log('No supported agent runtime detected.\n')
|
|
91
|
+
console.log(`Checked: ${checked}\n`)
|
|
92
|
+
console.log('Install manually or see: https://www.npmjs.com/package/twentythree-skills')
|
|
93
|
+
process.exit(0)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const runtime of detected) {
|
|
97
|
+
const dest = isProject ? runtime.projectDest : runtime.globalDest
|
|
98
|
+
const label = `${runtime.name} (${shortPath(dest)}/)`
|
|
99
|
+
installTo(dest, label)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log('\nDone.')
|
|
103
|
+
process.exit(process.exitCode ?? 0)
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "twentythree-skills",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI agent skills for the TwentyThree CLI",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "TwentyThree",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/23/twentythree-cli.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/23/twentythree-cli/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/23/twentythree-cli#readme",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22.0.0"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"twentythree-skills": "./bin/add.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"/bin",
|
|
24
|
+
"/skills",
|
|
25
|
+
"/README.md"
|
|
26
|
+
],
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"ai",
|
|
32
|
+
"skills",
|
|
33
|
+
"twentythree",
|
|
34
|
+
"cli",
|
|
35
|
+
"agent",
|
|
36
|
+
"claude",
|
|
37
|
+
"claude-code",
|
|
38
|
+
"copilot",
|
|
39
|
+
"cursor",
|
|
40
|
+
"codex",
|
|
41
|
+
"ai-agent"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"test": "node scripts/validate-skills.mjs"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/skills/SKILL.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: twentythree
|
|
3
|
+
description: |
|
|
4
|
+
Full TwentyThree video platform CLI. Use when the user asks to upload or manage
|
|
5
|
+
videos, run webinars, query analytics, manage audiences, configure players,
|
|
6
|
+
create categories, manage tags, spots, thumbnails, webhooks, collectors, polls,
|
|
7
|
+
presentations, or any TwentyThree platform operation. Covers 235+ API commands
|
|
8
|
+
across 22 resource groups plus meta commands (auth, workspace, autocomplete, doctor).
|
|
9
|
+
Every command supports --json for machine-readable output and --agent for
|
|
10
|
+
self-describing metadata (api_endpoint, auth_scope, output_shape, side_effects).
|
|
11
|
+
triggers:
|
|
12
|
+
- upload video
|
|
13
|
+
- manage videos
|
|
14
|
+
- webinar
|
|
15
|
+
- live event
|
|
16
|
+
- analytics
|
|
17
|
+
- twentythree
|
|
18
|
+
- video platform
|
|
19
|
+
- TwentyThree CLI
|
|
20
|
+
invocable: true
|
|
21
|
+
argument-hint: "<topic> <verb> [flags]"
|
|
22
|
+
allowed-tools: Bash(twentythree *)
|
|
23
|
+
compatibility: Requires twentythree-cli installed globally (npm install -g twentythree-cli). Node.js >=22.
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# TwentyThree CLI
|
|
27
|
+
|
|
28
|
+
> Terminal access to the full TwentyThree video platform API — videos, webinars, analytics, audiences, and every related resource. 235+ commands across 22 resource groups.
|
|
29
|
+
>
|
|
30
|
+
> Always use `--json` in agentic contexts for structured output. Always run `twentythree <command> --agent` before calling an unfamiliar command to discover its flags, API endpoint, auth scope, and side effects.
|
|
31
|
+
|
|
32
|
+
## Prerequisites: Authentication
|
|
33
|
+
|
|
34
|
+
Before any command, configure credentials once per workspace:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
twentythree auth credentials
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Prompts interactively for:
|
|
41
|
+
- **Domain** — your workspace domain (e.g. `company.video.twentythree.com`)
|
|
42
|
+
- **Bearer token** — copy from `Settings → API` inside your TwentyThree workspace admin
|
|
43
|
+
|
|
44
|
+
Credentials are stored in the OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service) — never in plaintext files.
|
|
45
|
+
|
|
46
|
+
Verify auth is working:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
twentythree auth status
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Multi-Workspace
|
|
53
|
+
|
|
54
|
+
The CLI supports multiple workspaces simultaneously:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
twentythree workspace list # Show all configured workspaces
|
|
58
|
+
twentythree workspace use <domain> # Set the active workspace
|
|
59
|
+
twentythree <command> --workspace <domain> # One-off override for a single call
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Command Syntax
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
twentythree <topic> <verb> [flags]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Global flags available on every command:
|
|
69
|
+
|
|
70
|
+
| Flag | Purpose |
|
|
71
|
+
|------|---------|
|
|
72
|
+
| `--json` | Machine-readable JSON output — always use in agentic contexts |
|
|
73
|
+
| `--agent` | Return machine-readable command metadata (no API call made) |
|
|
74
|
+
| `--workspace <domain>` | Target a specific workspace for this call only |
|
|
75
|
+
|
|
76
|
+
## Self-Discovery: The `--agent` Flag
|
|
77
|
+
|
|
78
|
+
Before calling any command you haven't used recently, introspect it:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
twentythree video upload --agent
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Returns JSON:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"command": "video:upload",
|
|
89
|
+
"description": "Upload a video file",
|
|
90
|
+
"flags": [
|
|
91
|
+
{ "name": "title", "type": "option", "required": true, "description": "..." },
|
|
92
|
+
{ "name": "category-id", "type": "option", "required": false, "description": "..." }
|
|
93
|
+
],
|
|
94
|
+
"examples": ["twentythree video upload ./file.mp4 --title \"Demo\""],
|
|
95
|
+
"api_endpoint": "POST /photo/redeem-upload-token",
|
|
96
|
+
"auth_scope": "write",
|
|
97
|
+
"output_shape": { "type": "key-value" },
|
|
98
|
+
"side_effects": "creates"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Key fields returned by `--agent`:
|
|
103
|
+
|
|
104
|
+
- **`api_endpoint`** — the underlying REST endpoint (note terminology mapping below)
|
|
105
|
+
- **`auth_scope`** — one of `anonymous`, `none`, `read`, `write`, `admin`, `super`
|
|
106
|
+
- **`output_shape`** — `{ type: "table", columns: [...] }`, `{ type: "key-value" }`, or `{ type: "none" }`
|
|
107
|
+
- **`side_effects`** — `none`, `creates`, `updates`, or `destructive`
|
|
108
|
+
- **`flags`** — the complete flag list with types, defaults, and required-ness
|
|
109
|
+
|
|
110
|
+
Always check `auth_scope` and `side_effects` before write/admin operations.
|
|
111
|
+
|
|
112
|
+
## Key Invariants
|
|
113
|
+
|
|
114
|
+
- **Use `--json` in agentic contexts.** Human-formatted tables are the default; agents should always request JSON.
|
|
115
|
+
- **File uploads use chunked upload automatically.** Never construct multipart requests directly — `twentythree video upload <file>` handles chunking under the hood.
|
|
116
|
+
- **Terminology mapping** — the CLI uses product-domain names while the API uses legacy names:
|
|
117
|
+
- CLI `video` ↔ API `photo`
|
|
118
|
+
- CLI `category` ↔ API `album`
|
|
119
|
+
- CLI `webinar` ↔ API `live`
|
|
120
|
+
- The `api_endpoint` field in `--agent` output shows the actual API path.
|
|
121
|
+
- **After upload or create, the CLI prints the new resource ID and its admin URL.** Use the ID for follow-up updates (e.g. setting thumbnail, publishing).
|
|
122
|
+
- **On persistent errors, run `twentythree doctor`** to diagnose auth, connectivity, and dependency issues.
|
|
123
|
+
|
|
124
|
+
## Resource Index
|
|
125
|
+
|
|
126
|
+
All 22 resource groups. Every topic supports `--agent`, `--json`, and `--workspace`.
|
|
127
|
+
|
|
128
|
+
| Topic | Representative verbs | Use for |
|
|
129
|
+
|-------|---------------------|---------|
|
|
130
|
+
| `video` | `upload`, `list`, `get`, `update`, `delete`, `replace`, `frame`, `transcoding-progress` | Video file management, upload, metadata, thumbnails |
|
|
131
|
+
| `webinar` | `create`, `list`, `get`, `update`, `delete`, `repeat`, `highlights`, `clips`, `metrics`, `log` + attachment/mail/queued-video/recording/room/section/series/speaker/transcription subtopics | Live events, scheduling, recordings, attendee comms |
|
|
132
|
+
| `analytics` | `conversions`, `live`, `usage`, `video` subtopics (many verbs each) | Reporting, viewer data, playback metrics, conversion tracking |
|
|
133
|
+
| `audience` | `list`, `create`, `get`, `update`, `delete` + segment ops | Audience segmentation and targeting |
|
|
134
|
+
| `category` | `list`, `create`, `get`, `update`, `delete` | Content organization (API: albums) |
|
|
135
|
+
| `action` | `list`, `create`, `get`, `update`, `delete` + subtypes | Interactive overlays, CTAs inside videos |
|
|
136
|
+
| `collector` | `list`, `create`, `delete` | Lead capture forms |
|
|
137
|
+
| `comment` | `list`, `create`, `get`, `update`, `delete` | Video comments moderation |
|
|
138
|
+
| `player` | `list`, `create`, `get`, `update`, `delete` | Player configuration and theming |
|
|
139
|
+
| `poll` | `list`, `create`, `get`, `update`, `delete` | In-video polls |
|
|
140
|
+
| `spot` | `list`, `create`, `get`, `update`, `delete` | Hotspot annotations on videos |
|
|
141
|
+
| `tag` | `list`, `create` | Content tagging |
|
|
142
|
+
| `thumbnail` | `list`, `create`, `get`, `update`, `delete` | Video thumbnail management |
|
|
143
|
+
| `webhook` | `list`, `create`, `get`, `update`, `delete` | Event webhooks |
|
|
144
|
+
| `app` | `list`, `thumbnail`, `create`, `get`, `update`, `delete` | App/integration management |
|
|
145
|
+
| `presentation` | `list` + page/setting subtopics | Presentation content |
|
|
146
|
+
| `protection` | `list`, `create`, `delete` | Access protection |
|
|
147
|
+
| `session` | `list`, `get` | Viewer session data |
|
|
148
|
+
| `setting` | `get` | Workspace settings |
|
|
149
|
+
| `site` | `list`, `search` | Site-level operations |
|
|
150
|
+
| `openupload` | `list`, `create`, `delete` | Open upload tokens |
|
|
151
|
+
| `user` | `list`, `create`, `get`, `update`, `delete` | User management |
|
|
152
|
+
|
|
153
|
+
## Meta Commands
|
|
154
|
+
|
|
155
|
+
These are not in the 22 resource groups — they are CLI-local utilities:
|
|
156
|
+
|
|
157
|
+
| Topic | Commands | Purpose |
|
|
158
|
+
|-------|----------|---------|
|
|
159
|
+
| `auth` | `credentials`, `status` | Configure and verify bearer-token auth |
|
|
160
|
+
| `workspace` | `list`, `use` | Multi-workspace selection |
|
|
161
|
+
| `autocomplete` | `bash`, `zsh` | Shell completion (`twentythree autocomplete bash | source`) |
|
|
162
|
+
| `doctor` | (top-level: `twentythree doctor`) | Diagnose auth, connectivity, dependency issues |
|
|
163
|
+
|
|
164
|
+
## Common Workflows
|
|
165
|
+
|
|
166
|
+
### Upload and Publish a Video
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# 1. Upload (chunked upload is automatic)
|
|
170
|
+
twentythree video upload ./video.mp4 --title "Product Demo" --json
|
|
171
|
+
# => prints { "id": "<video-id>", "admin_url": "..." }
|
|
172
|
+
|
|
173
|
+
# 2. Assign to a category (API: album)
|
|
174
|
+
twentythree video update <video-id> --category-id <cat-id> --json
|
|
175
|
+
|
|
176
|
+
# 3. Set a thumbnail at second 5
|
|
177
|
+
twentythree thumbnail create --video-id <video-id> --time 5 --json
|
|
178
|
+
|
|
179
|
+
# 4. Publish
|
|
180
|
+
twentythree video update <video-id> --published 1 --json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Webinar Setup
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# 1. Create the webinar (API: live)
|
|
187
|
+
twentythree webinar create --title "Q2 Kickoff" --scheduled-at "2026-05-01T14:00:00Z" --json
|
|
188
|
+
# => prints { "id": "<webinar-id>", "admin_url": "..." }
|
|
189
|
+
|
|
190
|
+
# 2. Fetch room URL and stream key
|
|
191
|
+
twentythree webinar get <webinar-id> --json
|
|
192
|
+
|
|
193
|
+
# 3. Start an associated session when the event begins
|
|
194
|
+
twentythree session list --webinar-id <webinar-id> --json
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Diagnostics
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
twentythree doctor # Check auth, connectivity, Node version, keychain access
|
|
201
|
+
twentythree --version # Print CLI version
|
|
202
|
+
twentythree <cmd> --help # Human-readable help for any command
|
|
203
|
+
twentythree <cmd> --agent # Machine-readable metadata for any command (preferred for agents)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
If a command fails unexpectedly, in order:
|
|
207
|
+
1. `twentythree auth status` — confirm credentials are present and the workspace matches
|
|
208
|
+
2. `twentythree <cmd> --agent` — confirm required flags and auth scope
|
|
209
|
+
3. `twentythree doctor` — catch environmental issues
|
|
210
|
+
|
|
211
|
+
See [twentythree-cli on npm](https://www.npmjs.com/package/twentythree-cli) for installation, and the GitHub repo for docs and issue reporting.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: action
|
|
3
|
+
description: Manage calls-to-action (CTAs) and interactive overlays on videos and webinars.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TwentyThree Action Commands
|
|
7
|
+
|
|
8
|
+
> Attach, configure, and manage interactive CTA overlays on video and webinar timelines.
|
|
9
|
+
> Always use `--json` in agentic contexts for structured output.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
Auth scope required: read (list, get, types), write (add, update, delete, exclude, include, upload).
|
|
14
|
+
Run `twentythree auth credentials` if not already configured.
|
|
15
|
+
Verify: `twentythree auth status --json`
|
|
16
|
+
|
|
17
|
+
> For any flag not listed here, run `twentythree action <cmd> --agent` to get the complete flag list, types, and defaults.
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
### action list
|
|
22
|
+
|
|
23
|
+
**Auth scope:** read **Side effects:** none **Output:** table (ID, Name, Type, Start, End)
|
|
24
|
+
|
|
25
|
+
Flags:
|
|
26
|
+
|
|
27
|
+
| Flag | Required | Description |
|
|
28
|
+
|------|----------|-------------|
|
|
29
|
+
| `--object-id` | no | Object ID to filter actions by |
|
|
30
|
+
| `--video-id` | no | Video ID to filter actions by (maps to photo_id) |
|
|
31
|
+
| `--webinar-id` | no | Webinar ID to filter actions by (maps to live_id) |
|
|
32
|
+
| `--player-id` | no | Player ID to filter actions by |
|
|
33
|
+
| `--exclude-internal` | no | Exclude internal actions |
|
|
34
|
+
| `--exclude-pending` | no | Exclude pending actions |
|
|
35
|
+
| `--exclude-items` | no | Exclude action items |
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# List all actions in the workspace
|
|
39
|
+
twentythree action list --json
|
|
40
|
+
|
|
41
|
+
# List actions for a specific video
|
|
42
|
+
twentythree action list --video-id <video-id> --json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### action add
|
|
46
|
+
|
|
47
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value
|
|
48
|
+
|
|
49
|
+
Flags:
|
|
50
|
+
|
|
51
|
+
| Flag | Required | Description |
|
|
52
|
+
|------|----------|-------------|
|
|
53
|
+
| `--type` | yes | Action type (use `action types` to list valid values) |
|
|
54
|
+
| `--object-id` | yes | Object ID (video or webinar) to attach the action to |
|
|
55
|
+
| `--fields` | no | Additional fields for the action (key=value pairs) |
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Add a basic CTA action to a video
|
|
59
|
+
twentythree action add --type overlay --object-id <video-id> --json
|
|
60
|
+
|
|
61
|
+
# Add a CTA with custom field values
|
|
62
|
+
twentythree action add --type overlay --object-id <video-id> --fields "title=Buy Now" --json
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### action get
|
|
66
|
+
|
|
67
|
+
**Auth scope:** read **Side effects:** none **Output:** key-value
|
|
68
|
+
|
|
69
|
+
Flags:
|
|
70
|
+
|
|
71
|
+
| Flag | Required | Description |
|
|
72
|
+
|------|----------|-------------|
|
|
73
|
+
| `--object-id` | no | Object ID context |
|
|
74
|
+
| `--video-id` | no | Video ID context (maps to photo_id) |
|
|
75
|
+
| `--webinar-id` | no | Webinar ID context (maps to live_id) |
|
|
76
|
+
| `--token` | no | Object token for authentication |
|
|
77
|
+
| `--player-id` | no | Player ID context |
|
|
78
|
+
| `--exclude-internal` | no | Exclude internal actions |
|
|
79
|
+
| `--exclude-pending` | no | Exclude pending actions |
|
|
80
|
+
| `--exclude-items` | no | Exclude action items |
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Get details of a specific action by ID
|
|
84
|
+
twentythree action get <action-id> --json
|
|
85
|
+
|
|
86
|
+
# Get action in the context of a video
|
|
87
|
+
twentythree action get <action-id> --video-id <video-id> --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### action update
|
|
91
|
+
|
|
92
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
93
|
+
|
|
94
|
+
Flags:
|
|
95
|
+
|
|
96
|
+
| Flag | Required | Description |
|
|
97
|
+
|------|----------|-------------|
|
|
98
|
+
| `--name` | yes | Display name for the action |
|
|
99
|
+
| `--start-time` | yes | Start time of the action (seconds) |
|
|
100
|
+
| `--end-time` | yes | End time of the action (seconds) |
|
|
101
|
+
| `--time-relative-to` | no | What the timing is relative to (default: duration) |
|
|
102
|
+
| `--return-url` | no | Return URL for the action |
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Update action timing and name
|
|
106
|
+
twentythree action update <action-id> --name "Buy Now" --start-time 10 --end-time 20 --json
|
|
107
|
+
|
|
108
|
+
# Update action with a click-through URL
|
|
109
|
+
twentythree action update <action-id> --name "Learn More" --start-time 30 --end-time 60 --return-url "https://example.com" --json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### action delete
|
|
113
|
+
|
|
114
|
+
**Auth scope:** write **Side effects:** destructive **Output:** key-value
|
|
115
|
+
|
|
116
|
+
Flags:
|
|
117
|
+
|
|
118
|
+
| Flag | Required | Description |
|
|
119
|
+
|------|----------|-------------|
|
|
120
|
+
| (none) | — | Takes action ID as positional argument |
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Delete a CTA action
|
|
124
|
+
twentythree action delete <action-id> --json
|
|
125
|
+
|
|
126
|
+
# Delete with confirmation
|
|
127
|
+
twentythree action delete <action-id> --json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### action types
|
|
131
|
+
|
|
132
|
+
**Auth scope:** read **Side effects:** none **Output:** table (Type, Name / Description)
|
|
133
|
+
|
|
134
|
+
Flags:
|
|
135
|
+
|
|
136
|
+
| Flag | Required | Description |
|
|
137
|
+
|------|----------|-------------|
|
|
138
|
+
| `--exclude-internal` | no | Exclude internal action types from the list |
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# List all available action types
|
|
142
|
+
twentythree action types --json
|
|
143
|
+
|
|
144
|
+
# List only public action types (excluding internal)
|
|
145
|
+
twentythree action types --exclude-internal --json
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### action exclude
|
|
149
|
+
|
|
150
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
151
|
+
|
|
152
|
+
Flags:
|
|
153
|
+
|
|
154
|
+
| Flag | Required | Description |
|
|
155
|
+
|------|----------|-------------|
|
|
156
|
+
| `--object-id` | yes | Object ID to exclude the action from |
|
|
157
|
+
| `--undo` | no | Remove the exclusion (reverse this operation) |
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Exclude a CTA from a specific video
|
|
161
|
+
twentythree action exclude <action-id> --object-id <video-id> --json
|
|
162
|
+
|
|
163
|
+
# Undo the exclusion (re-enable the action on the video)
|
|
164
|
+
twentythree action exclude <action-id> --object-id <video-id> --undo --json
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### action include
|
|
168
|
+
|
|
169
|
+
**Auth scope:** write **Side effects:** updates **Output:** key-value
|
|
170
|
+
|
|
171
|
+
Flags:
|
|
172
|
+
|
|
173
|
+
| Flag | Required | Description |
|
|
174
|
+
|------|----------|-------------|
|
|
175
|
+
| `--object-id` | yes | Object ID to include the action on |
|
|
176
|
+
| `--undo` | no | Remove the inclusion (reverse this operation) |
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Include an action on a specific video
|
|
180
|
+
twentythree action include <action-id> --object-id <video-id> --json
|
|
181
|
+
|
|
182
|
+
# Undo the inclusion
|
|
183
|
+
twentythree action include <action-id> --object-id <video-id> --undo --json
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### action upload
|
|
187
|
+
|
|
188
|
+
**Auth scope:** write **Side effects:** creates **Output:** key-value
|
|
189
|
+
|
|
190
|
+
Takes positional arguments: `<action-id> <variable> <file>` — no additional flags.
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Upload a banner image to an action's image variable
|
|
194
|
+
twentythree action upload <action-id> image ./banner.png --json
|
|
195
|
+
|
|
196
|
+
# Upload a video clip to an action's video variable
|
|
197
|
+
twentythree action upload <action-id> video ./clip.mp4 --json
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Common Patterns
|
|
201
|
+
|
|
202
|
+
### Discover types, create, and configure an action
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Step 1: List available action types to find a valid type value
|
|
206
|
+
twentythree action types --exclude-internal --json
|
|
207
|
+
|
|
208
|
+
# Step 2: Add the action to a video using the chosen type
|
|
209
|
+
twentythree action add --type <type> --object-id <video-id> --fields "title=Click Here" --json
|
|
210
|
+
|
|
211
|
+
# Step 3: Update the timing on the newly created action
|
|
212
|
+
twentythree action update <action-id> --name "Click Here" --start-time 15 --end-time 45 --json
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Suppress a global CTA on a specific video
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# List actions to find the global action ID
|
|
219
|
+
twentythree action list --json
|
|
220
|
+
|
|
221
|
+
# Exclude that action from the video where it should not appear
|
|
222
|
+
twentythree action exclude <action-id> --object-id <video-id> --json
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Upload a custom image to an overlay action
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# First add the action
|
|
229
|
+
twentythree action add --type overlay --object-id <video-id> --json
|
|
230
|
+
|
|
231
|
+
# Then upload the image file to the action variable
|
|
232
|
+
twentythree action upload <action-id> image ./custom-banner.png --json
|
|
233
|
+
```
|