kctl-zulip 0.9.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. kctl_zulip-0.9.4/.gitignore +33 -0
  2. kctl_zulip-0.9.4/PKG-INFO +17 -0
  3. kctl_zulip-0.9.4/README.md +209 -0
  4. kctl_zulip-0.9.4/docs/completions.md +71 -0
  5. kctl_zulip-0.9.4/e2e/fixtures/zulip-test.ts +19 -0
  6. kctl_zulip-0.9.4/e2e/package.json +13 -0
  7. kctl_zulip-0.9.4/e2e/playwright.config.ts +24 -0
  8. kctl_zulip-0.9.4/e2e/tests/global-setup.ts +6 -0
  9. kctl_zulip-0.9.4/e2e/tests/scenarios/health.spec.ts +17 -0
  10. kctl_zulip-0.9.4/e2e/tsconfig.json +11 -0
  11. kctl_zulip-0.9.4/pyproject.toml +48 -0
  12. kctl_zulip-0.9.4/skills/zulip-admin/SKILL.md +344 -0
  13. kctl_zulip-0.9.4/src/kctl_zulip/__init__.py +1 -0
  14. kctl_zulip-0.9.4/src/kctl_zulip/__main__.py +3 -0
  15. kctl_zulip-0.9.4/src/kctl_zulip/cli.py +173 -0
  16. kctl_zulip-0.9.4/src/kctl_zulip/commands/__init__.py +0 -0
  17. kctl_zulip-0.9.4/src/kctl_zulip/commands/alert_words.py +54 -0
  18. kctl_zulip-0.9.4/src/kctl_zulip/commands/announce.py +35 -0
  19. kctl_zulip-0.9.4/src/kctl_zulip/commands/config_cmd.py +557 -0
  20. kctl_zulip-0.9.4/src/kctl_zulip/commands/dashboard.py +145 -0
  21. kctl_zulip-0.9.4/src/kctl_zulip/commands/doctor_cmd.py +128 -0
  22. kctl_zulip-0.9.4/src/kctl_zulip/commands/drafts.py +116 -0
  23. kctl_zulip-0.9.4/src/kctl_zulip/commands/emoji.py +86 -0
  24. kctl_zulip-0.9.4/src/kctl_zulip/commands/groups.py +186 -0
  25. kctl_zulip-0.9.4/src/kctl_zulip/commands/health.py +152 -0
  26. kctl_zulip-0.9.4/src/kctl_zulip/commands/invitations.py +90 -0
  27. kctl_zulip-0.9.4/src/kctl_zulip/commands/linkifiers.py +71 -0
  28. kctl_zulip-0.9.4/src/kctl_zulip/commands/messages.py +163 -0
  29. kctl_zulip-0.9.4/src/kctl_zulip/commands/muted.py +104 -0
  30. kctl_zulip-0.9.4/src/kctl_zulip/commands/presence.py +97 -0
  31. kctl_zulip-0.9.4/src/kctl_zulip/commands/profile_fields.py +125 -0
  32. kctl_zulip-0.9.4/src/kctl_zulip/commands/reactions.py +79 -0
  33. kctl_zulip-0.9.4/src/kctl_zulip/commands/realm.py +350 -0
  34. kctl_zulip-0.9.4/src/kctl_zulip/commands/scheduled.py +121 -0
  35. kctl_zulip-0.9.4/src/kctl_zulip/commands/skill_cmd.py +76 -0
  36. kctl_zulip-0.9.4/src/kctl_zulip/commands/streams.py +241 -0
  37. kctl_zulip-0.9.4/src/kctl_zulip/commands/topics.py +40 -0
  38. kctl_zulip-0.9.4/src/kctl_zulip/commands/users.py +185 -0
  39. kctl_zulip-0.9.4/src/kctl_zulip/core/__init__.py +0 -0
  40. kctl_zulip-0.9.4/src/kctl_zulip/core/callbacks.py +53 -0
  41. kctl_zulip-0.9.4/src/kctl_zulip/core/client.py +157 -0
  42. kctl_zulip-0.9.4/src/kctl_zulip/core/config.py +249 -0
  43. kctl_zulip-0.9.4/src/kctl_zulip/core/output.py +3 -0
  44. kctl_zulip-0.9.4/src/kctl_zulip/core/server_admin.py +99 -0
  45. kctl_zulip-0.9.4/tests/conftest.py +57 -0
  46. kctl_zulip-0.9.4/tests/test_alert_words.py +35 -0
  47. kctl_zulip-0.9.4/tests/test_announce.py +44 -0
  48. kctl_zulip-0.9.4/tests/test_cli.py +32 -0
  49. kctl_zulip-0.9.4/tests/test_client.py +66 -0
  50. kctl_zulip-0.9.4/tests/test_config.py +66 -0
  51. kctl_zulip-0.9.4/tests/test_dashboard.py +42 -0
  52. kctl_zulip-0.9.4/tests/test_doctor.py +64 -0
  53. kctl_zulip-0.9.4/tests/test_drafts.py +46 -0
  54. kctl_zulip-0.9.4/tests/test_emoji.py +45 -0
  55. kctl_zulip-0.9.4/tests/test_groups.py +48 -0
  56. kctl_zulip-0.9.4/tests/test_health.py +31 -0
  57. kctl_zulip-0.9.4/tests/test_invitations.py +45 -0
  58. kctl_zulip-0.9.4/tests/test_linkifiers.py +49 -0
  59. kctl_zulip-0.9.4/tests/test_messages.py +50 -0
  60. kctl_zulip-0.9.4/tests/test_muted.py +41 -0
  61. kctl_zulip-0.9.4/tests/test_presence.py +44 -0
  62. kctl_zulip-0.9.4/tests/test_profile_fields.py +39 -0
  63. kctl_zulip-0.9.4/tests/test_reactions.py +43 -0
  64. kctl_zulip-0.9.4/tests/test_realm.py +37 -0
  65. kctl_zulip-0.9.4/tests/test_resolve_connection.py +76 -0
  66. kctl_zulip-0.9.4/tests/test_scheduled.py +60 -0
  67. kctl_zulip-0.9.4/tests/test_standard.py +79 -0
  68. kctl_zulip-0.9.4/tests/test_streams.py +74 -0
  69. kctl_zulip-0.9.4/tests/test_topics.py +31 -0
  70. kctl_zulip-0.9.4/tests/test_users.py +75 -0
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ *.egg
6
+ dist/
7
+ build/
8
+ .eggs/
9
+
10
+ # Virtual environments
11
+ .venv/
12
+ venv/
13
+
14
+ # IDE
15
+ .idea/
16
+ .vscode/
17
+ *.swp
18
+ *.swo
19
+
20
+ # Testing
21
+ .pytest_cache/
22
+ .coverage
23
+ htmlcov/
24
+ .mypy_cache/
25
+ .ruff_cache/
26
+
27
+ # OS
28
+ .DS_Store
29
+ Thumbs.db
30
+
31
+ # Environment
32
+ .env
33
+ .env.local
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: kctl-zulip
3
+ Version: 0.9.4
4
+ Summary: Kodemeio Zulip CLI — manage Zulip team chat
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: httpx>=0.28.0
7
+ Requires-Dist: kctl-lib>=0.12.0
8
+ Requires-Dist: pydantic>=2.10.0
9
+ Requires-Dist: pyyaml>=6.0.2
10
+ Requires-Dist: rich>=13.9.0
11
+ Requires-Dist: typer>=0.15.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: mypy>=1.14.0; extra == 'dev'
14
+ Requires-Dist: pytest-httpx>=0.35.0; extra == 'dev'
15
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
16
+ Requires-Dist: ruff>=0.9.0; extra == 'dev'
17
+ Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
@@ -0,0 +1,209 @@
1
+ # kctl-zulip
2
+
3
+ Kodemeio CLI for managing Zulip team chat instances. Part of the
4
+ [kodemeio-platform](../../) monorepo (22nd CLI tool).
5
+
6
+ Manage streams, users, messages, emoji, presence, invitations, and more
7
+ from the command line with profile-based multi-instance support.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ # From workspace root (development)
13
+ uv sync --all-extras --all-packages
14
+
15
+ # Standalone install
16
+ uv tool install ./packages/kctl-zulip
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ # 1. Configure a profile
23
+ kctl-zulip config init
24
+
25
+ # 2. Check server health
26
+ kctl-zulip health
27
+
28
+ # 3. List users
29
+ kctl-zulip users list
30
+
31
+ # 4. List streams
32
+ kctl-zulip streams list
33
+
34
+ # 5. Send a message
35
+ kctl-zulip messages send --stream general --topic "Hello" --content "Hi from kctl-zulip!"
36
+ ```
37
+
38
+ ## Command Groups
39
+
40
+ kctl-zulip provides 22 command groups organized into five panels.
41
+
42
+ ### Admin & Config
43
+
44
+ | Group | Description |
45
+ |-------|-------------|
46
+ | `config` | Profile management (init, add, use, show, validate, remove, set, profiles, current) |
47
+ | `users` | User administration (list, get, create, deactivate, reactivate, update) |
48
+ | `groups` | User group management (list, get, create, delete, add-members, remove-members) |
49
+ | `realm` | Realm/organization settings (get, update, get-emoji, upload-emoji) |
50
+ | `invitations` | Invite management (list, send, resend, revoke) |
51
+
52
+ ### Messaging
53
+
54
+ | Group | Description |
55
+ |-------|-------------|
56
+ | `messages` | Send, fetch, search, edit, delete, and flag messages |
57
+ | `streams` | Stream CRUD, subscribe, unsubscribe, archive |
58
+ | `topics` | Topic listing, resolution, and deletion |
59
+ | `announce` | Broadcast announcements to streams |
60
+ | `drafts` | Draft message management (list, create, edit, delete) |
61
+ | `scheduled` | Scheduled message management (list, create, delete) |
62
+
63
+ ### Personalization
64
+
65
+ | Group | Description |
66
+ |-------|-------------|
67
+ | `emoji` | Custom emoji management (list, upload, delete) |
68
+ | `reactions` | Message reaction management (add, remove, get) |
69
+ | `presence` | User presence/status (get, set, list) |
70
+ | `muted` | Muted users and topics (list, add, remove) |
71
+ | `alert-words` | Alert word management (list, add, remove) |
72
+ | `profile-fields` | Custom profile field management (list, create, update, delete, reorder) |
73
+ | `linkifiers` | Linkifier/regex pattern management (list, create, update, delete) |
74
+
75
+ ### Monitoring
76
+
77
+ | Group | Description |
78
+ |-------|-------------|
79
+ | `health` | Server health checks and connectivity verification |
80
+ | `dashboard` | Overview dashboard with server stats |
81
+
82
+ ### Tools
83
+
84
+ | Group | Description |
85
+ |-------|-------------|
86
+ | `doctor` | Diagnostic checks (config, connectivity, auth, API version) |
87
+ | `self-update` | Check for PyPI updates and upgrade via `uv tool` |
88
+ | `completions` | Generate/install shell completions (zsh, bash, fish) |
89
+ | `skill` | Auto-generate SKILL.md from Typer introspection (hidden) |
90
+
91
+ ## Global Options
92
+
93
+ | Option | Short | Description |
94
+ |--------|-------|-------------|
95
+ | `--json` | | Output as JSON (shortcut for `--format json`) |
96
+ | `--quiet` | `-q` | Suppress info messages |
97
+ | `--format` | `-f` | Output format: `pretty`, `json`, `csv`, `yaml` |
98
+ | `--no-header` | | Omit headers in CSV output |
99
+ | `--profile` | `-p` | Config profile name |
100
+ | `--url` | | API URL override |
101
+ | `--email` | | Auth email override |
102
+ | `--api-key` | | API key override |
103
+ | `--version` | `-V` | Show version and exit |
104
+
105
+ ## Configuration
106
+
107
+ kctl-zulip uses the shared Kodemeio config framework at
108
+ `~/.config/kodemeio/config.yaml` with service key `zulip`.
109
+
110
+ ### Profile Setup
111
+
112
+ ```bash
113
+ # Interactive setup
114
+ kctl-zulip config init
115
+
116
+ # Manual profile
117
+ kctl-zulip config add production \
118
+ --url https://zulip.kodeme.io \
119
+ --email bot@kodeme.io \
120
+ --api-key YOUR_API_KEY
121
+
122
+ # Switch profiles
123
+ kctl-zulip config use production
124
+ kctl-zulip config current
125
+ kctl-zulip config profiles
126
+ ```
127
+
128
+ ### Multi-Instance Support
129
+
130
+ Each profile can target a different Zulip instance. Use `--profile` to
131
+ override the active profile for a single command:
132
+
133
+ ```bash
134
+ kctl-zulip --profile staging health
135
+ kctl-zulip --profile production users list --json
136
+ ```
137
+
138
+ ### Environment Variables
139
+
140
+ | Variable | Description |
141
+ |----------|-------------|
142
+ | `KCTL_ZULIP_URL` | Zulip server URL |
143
+ | `KCTL_ZULIP_EMAIL` | Bot email address |
144
+ | `KCTL_ZULIP_API_KEY` | Bot API key |
145
+ | `KCTL_ZULIP_PROFILE` | Default profile name |
146
+
147
+ Environment variables override config file values. CLI flags (`--url`,
148
+ `--email`, `--api-key`) take highest precedence.
149
+
150
+ ## Shell Completions
151
+
152
+ ```bash
153
+ # Generate completion script
154
+ kctl-zulip completions zsh
155
+
156
+ # Install completions (writes to shell config dir)
157
+ kctl-zulip completions zsh --install
158
+ kctl-zulip completions bash --install
159
+ kctl-zulip completions fish --install
160
+ ```
161
+
162
+ See [docs/completions.md](docs/completions.md) for detailed instructions.
163
+
164
+ ## E2E Testing (Playwright)
165
+
166
+ The `e2e/` directory contains Playwright-based API tests for verifying
167
+ connectivity against a live Zulip instance.
168
+
169
+ ```bash
170
+ cd packages/kctl-zulip/e2e
171
+ pnpm install
172
+ ZULIP_URL=https://zulip.kodeme.io npx playwright test
173
+ npx playwright show-report
174
+ ```
175
+
176
+ ## Development
177
+
178
+ ```bash
179
+ # Run tests
180
+ uv run pytest tests/ -v
181
+
182
+ # Lint
183
+ uv run ruff check src/
184
+
185
+ # Type check
186
+ uv run mypy src/
187
+
188
+ # Build
189
+ uv build
190
+ ```
191
+
192
+ ### Project Structure
193
+
194
+ ```
195
+ packages/kctl-zulip/
196
+ ├── src/kctl_zulip/
197
+ │ ├── cli.py # Main Typer app + command registration
198
+ │ ├── core/ # Shared core (callbacks, client, config)
199
+ │ └── commands/ # 22 command group modules
200
+ ├── tests/ # pytest unit tests (58 tests)
201
+ ├── e2e/ # Playwright E2E tests
202
+ ├── docs/ # Additional documentation
203
+ ├── skills/ # SKILL.md for Claude Code
204
+ └── pyproject.toml # Package metadata
205
+ ```
206
+
207
+ ## License
208
+
209
+ Internal -- Kodemeio Pte Ltd.
@@ -0,0 +1,71 @@
1
+ # Shell Completions for kctl-zulip
2
+
3
+ kctl-zulip supports tab-completion for commands, options, and arguments
4
+ in zsh, bash, and fish shells.
5
+
6
+ ## Quick Install
7
+
8
+ ```bash
9
+ kctl-zulip completions zsh --install
10
+ kctl-zulip completions bash --install
11
+ kctl-zulip completions fish --install
12
+ ```
13
+
14
+ After installing, restart your shell or source the relevant config file.
15
+
16
+ ## Manual Setup
17
+
18
+ ### Zsh
19
+
20
+ Generate the completion script and place it in your fpath:
21
+
22
+ ```bash
23
+ kctl-zulip completions zsh > ~/.zfunc/_kctl-zulip
24
+ ```
25
+
26
+ Ensure `~/.zfunc` is in your fpath. Add to `~/.zshrc` if not already present:
27
+
28
+ ```bash
29
+ fpath=(~/.zfunc $fpath)
30
+ autoload -Uz compinit && compinit
31
+ ```
32
+
33
+ ### Bash
34
+
35
+ Generate and source the completion script:
36
+
37
+ ```bash
38
+ kctl-zulip completions bash > ~/.local/share/bash-completion/completions/kctl-zulip
39
+ ```
40
+
41
+ Or source it directly in `~/.bashrc`:
42
+
43
+ ```bash
44
+ eval "$(kctl-zulip completions bash)"
45
+ ```
46
+
47
+ ### Fish
48
+
49
+ Generate and place the completion file:
50
+
51
+ ```bash
52
+ kctl-zulip completions fish > ~/.config/fish/completions/kctl-zulip.fish
53
+ ```
54
+
55
+ Fish picks up completions automatically from this directory.
56
+
57
+ ## Verifying
58
+
59
+ After installation, open a new terminal and type:
60
+
61
+ ```bash
62
+ kctl-zulip <TAB>
63
+ ```
64
+
65
+ You should see a list of available commands (config, users, streams, messages, etc.).
66
+
67
+ ## Troubleshooting
68
+
69
+ - **Zsh completions not working**: Run `compinit` or delete `~/.zcompdump` and restart.
70
+ - **Bash completions not loading**: Ensure `bash-completion` is installed (`apt install bash-completion`).
71
+ - **Fish completions stale**: Delete the generated file and regenerate.
@@ -0,0 +1,19 @@
1
+ import { test as base, expect } from "@playwright/test";
2
+
3
+ const ZULIP_URL = process.env.ZULIP_URL || "https://zulip.kodeme.io";
4
+ const ZULIP_EMAIL = process.env.ZULIP_EMAIL || "";
5
+ const ZULIP_API_KEY = process.env.ZULIP_API_KEY || "";
6
+
7
+ export interface ZulipFixtures {
8
+ zulipURL: string;
9
+ zulipEmail: string;
10
+ zulipAPIKey: string;
11
+ }
12
+
13
+ export const test = base.extend<ZulipFixtures>({
14
+ zulipURL: ZULIP_URL,
15
+ zulipEmail: ZULIP_EMAIL,
16
+ zulipAPIKey: ZULIP_API_KEY,
17
+ });
18
+
19
+ export { expect };
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "kctl-zulip-e2e",
3
+ "private": true,
4
+ "scripts": {
5
+ "test": "npx playwright test",
6
+ "test:headed": "npx playwright test --headed",
7
+ "report": "npx playwright show-report"
8
+ },
9
+ "devDependencies": {
10
+ "@playwright/test": "^1.48.0",
11
+ "typescript": "^5.6.0"
12
+ }
13
+ }
@@ -0,0 +1,24 @@
1
+ import { defineConfig } from "@playwright/test";
2
+
3
+ export default defineConfig({
4
+ testDir: "./tests",
5
+ fullyParallel: false,
6
+ workers: 1,
7
+ timeout: 60_000,
8
+ retries: 0,
9
+ reporter: [["html", { open: "never" }]],
10
+ use: {
11
+ baseURL: process.env.ZULIP_URL || "https://zulip.kodeme.io",
12
+ screenshot: "only-on-failure",
13
+ trace: "retain-on-failure",
14
+ },
15
+ projects: [
16
+ { name: "setup", testMatch: /global-setup\.ts/ },
17
+ {
18
+ name: "desktop",
19
+ dependencies: ["setup"],
20
+ use: { viewport: { width: 1280, height: 720 } },
21
+ testMatch: /scenarios\/.*\.spec\.ts/,
22
+ },
23
+ ],
24
+ });
@@ -0,0 +1,6 @@
1
+ import { test } from "../fixtures/zulip-test";
2
+
3
+ test("verify environment", async ({ zulipURL }) => {
4
+ test.skip(!zulipURL, "ZULIP_URL not set");
5
+ console.log(`Zulip URL: ${zulipURL}`);
6
+ });
@@ -0,0 +1,17 @@
1
+ import { test, expect } from "../../fixtures/zulip-test";
2
+
3
+ test.describe("Zulip Health", () => {
4
+ test("server settings endpoint returns 200", async ({
5
+ request,
6
+ zulipURL,
7
+ }) => {
8
+ test.skip(!zulipURL, "ZULIP_URL not set");
9
+
10
+ const response = await request.get(`${zulipURL}/api/v1/server_settings`);
11
+ expect(response.status()).toBe(200);
12
+
13
+ const body = await response.json();
14
+ expect(body).toHaveProperty("zulip_version");
15
+ expect(body.result).toBe("success");
16
+ });
17
+ });
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true
9
+ },
10
+ "include": ["**/*.ts"]
11
+ }
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "kctl-zulip"
7
+ version = "0.9.4"
8
+ description = "Kodemeio Zulip CLI — manage Zulip team chat"
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "kctl-lib>=0.12.0",
12
+ "typer>=0.15.0",
13
+ "rich>=13.9.0",
14
+ "pydantic>=2.10.0",
15
+ "pyyaml>=6.0.2",
16
+ "httpx>=0.28.0",
17
+ ]
18
+
19
+ [project.optional-dependencies]
20
+ dev = [
21
+ "pytest>=8.3.0",
22
+ "pytest-httpx>=0.35.0",
23
+ "ruff>=0.9.0",
24
+ "mypy>=1.14.0",
25
+ "types-PyYAML>=6.0.0",
26
+ ]
27
+
28
+ [project.scripts]
29
+ kctl-zulip = "kctl_zulip.cli:_run"
30
+
31
+ [tool.uv.sources]
32
+ kctl-lib = { workspace = true }
33
+
34
+ [project.entry-points."kctl_zulip.plugins"]
35
+
36
+ [tool.hatch.build.targets.wheel]
37
+ packages = ["src/kctl_zulip"]
38
+
39
+ [tool.ruff]
40
+ target-version = "py312"
41
+ line-length = 120
42
+
43
+ [tool.mypy]
44
+ python_version = "3.12"
45
+ strict = true
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]