janet-cli 0.2.2__py3-none-any.whl

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.
janet/utils/errors.py ADDED
@@ -0,0 +1,49 @@
1
+ """Custom exception classes for Janet CLI."""
2
+
3
+
4
+ class JanetCLIError(Exception):
5
+ """Base exception for all CLI errors."""
6
+
7
+ pass
8
+
9
+
10
+ class AuthenticationError(JanetCLIError):
11
+ """Authentication failed or token expired."""
12
+
13
+ pass
14
+
15
+
16
+ class OrganizationAccessError(JanetCLIError):
17
+ """User doesn't have access to organization."""
18
+
19
+ pass
20
+
21
+
22
+ class NetworkError(JanetCLIError):
23
+ """Network request failed."""
24
+
25
+ pass
26
+
27
+
28
+ class ConfigurationError(JanetCLIError):
29
+ """Invalid configuration."""
30
+
31
+ pass
32
+
33
+
34
+ class SyncError(JanetCLIError):
35
+ """Sync operation failed."""
36
+
37
+ pass
38
+
39
+
40
+ class TokenExpiredError(AuthenticationError):
41
+ """Access token has expired."""
42
+
43
+ pass
44
+
45
+
46
+ class InvalidTokenError(AuthenticationError):
47
+ """Invalid or malformed token."""
48
+
49
+ pass
janet/utils/paths.py ADDED
@@ -0,0 +1,66 @@
1
+ """Path utilities for Janet CLI."""
2
+
3
+ import re
4
+ from pathlib import Path
5
+ from platformdirs import user_config_dir, user_data_dir
6
+
7
+
8
+ def get_config_dir() -> Path:
9
+ """Get configuration directory path."""
10
+ config_dir = Path(user_config_dir("janet-cli", appauthor=False))
11
+ config_dir.mkdir(parents=True, exist_ok=True)
12
+ return config_dir
13
+
14
+
15
+ def get_data_dir() -> Path:
16
+ """Get data directory path."""
17
+ data_dir = Path(user_data_dir("janet-cli", appauthor=False))
18
+ data_dir.mkdir(parents=True, exist_ok=True)
19
+ return data_dir
20
+
21
+
22
+ def get_config_file() -> Path:
23
+ """Get configuration file path."""
24
+ return get_config_dir() / "config.json"
25
+
26
+
27
+ def sanitize_filename(name: str) -> str:
28
+ """
29
+ Sanitize a string to be safe for use as a filename.
30
+
31
+ Replaces invalid characters with hyphens and limits length.
32
+
33
+ Args:
34
+ name: String to sanitize
35
+
36
+ Returns:
37
+ Sanitized filename-safe string
38
+ """
39
+ # Replace invalid filesystem characters with hyphens
40
+ invalid_chars = r'[<>:"/\\|?*]'
41
+ sanitized = re.sub(invalid_chars, "-", name)
42
+
43
+ # Remove leading/trailing whitespace and dots
44
+ sanitized = sanitized.strip(". ")
45
+
46
+ # Replace multiple consecutive hyphens with single hyphen
47
+ sanitized = re.sub(r"-+", "-", sanitized)
48
+
49
+ # Limit length to 255 characters (filesystem limit)
50
+ if len(sanitized) > 255:
51
+ sanitized = sanitized[:255].rstrip("-")
52
+
53
+ return sanitized if sanitized else "unnamed"
54
+
55
+
56
+ def expand_path(path: str) -> Path:
57
+ """
58
+ Expand user home directory and resolve path.
59
+
60
+ Args:
61
+ path: Path string (may contain ~)
62
+
63
+ Returns:
64
+ Resolved absolute Path
65
+ """
66
+ return Path(path).expanduser().resolve()
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: janet-cli
3
+ Version: 0.2.2
4
+ Summary: CLI tool to sync Janet AI tickets to local markdown files
5
+ Author-email: Janet AI <support@janet-ai.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/janet-ai/janet-cli
8
+ Project-URL: Repository, https://github.com/janet-ai/janet-cli
9
+ Project-URL: Issues, https://github.com/janet-ai/janet-cli/issues
10
+ Keywords: cli,janet,tickets,markdown,sync
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Requires-Python: >=3.8
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: typer>=0.12.0
24
+ Requires-Dist: httpx>=0.27.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Requires-Dist: pydantic-settings>=2.0.0
27
+ Requires-Dist: rich>=13.0.0
28
+ Requires-Dist: platformdirs>=4.0.0
29
+ Requires-Dist: keyring>=25.0.0
30
+ Requires-Dist: python-dateutil>=2.8.0
31
+ Requires-Dist: pycrdt>=0.9.0
32
+ Requires-Dist: InquirerPy>=0.3.4
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
36
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
37
+ Requires-Dist: httpx-mock>=0.15.0; extra == "dev"
38
+ Requires-Dist: black>=24.0.0; extra == "dev"
39
+ Requires-Dist: mypy>=1.8.0; extra == "dev"
40
+ Requires-Dist: ruff>=0.2.0; extra == "dev"
41
+ Dynamic: license-file
42
+
43
+ # Janet AI CLI
44
+
45
+ > Sync your Janet AI tickets to local markdown files for seamless integration with AI coding agents.
46
+
47
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
48
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
49
+
50
+ ## What is Janet AI?
51
+
52
+ [Janet AI](https://tryjanet.ai) is an AI-native project management platform for modern software teams. The Janet CLI allows developers to sync their tickets locally as markdown files, enabling AI coding assistants like Claude Code, Cursor, and GitHub Copilot to have full project context.
53
+
54
+ ## Why Use the CLI?
55
+
56
+ AI coding assistants work better when they understand your project's tickets, requirements, and priorities. By syncing Janet AI tickets to your workspace, AI agents can:
57
+
58
+ - Reference specific tickets while writing code
59
+ - Understand requirements and acceptance criteria
60
+ - Answer questions about project priorities
61
+ - Suggest implementations based on ticket descriptions
62
+
63
+ ## Installation
64
+
65
+ ```bash
66
+ pip install janet-cli
67
+ ```
68
+
69
+ ## Quick Start
70
+
71
+ ### 1. Authenticate
72
+
73
+ ```bash
74
+ janet login
75
+ ```
76
+
77
+ ### 2. Sync Tickets
78
+
79
+ ```bash
80
+ janet sync
81
+ ```
82
+
83
+ ### 3. Use with AI Agents
84
+
85
+ Your tickets are now available as markdown files! Point your AI coding agent to the sync directory.
86
+
87
+ ```bash
88
+ # Example prompts for Claude Code, Cursor, etc:
89
+ "Look at ticket CS-42 and implement the authentication flow"
90
+ "What are the high priority tickets in the Backend project?"
91
+ "Implement the feature described in PROJ-15"
92
+ ```
93
+
94
+ ## Usage
95
+
96
+ ### Basic Commands
97
+
98
+ ```bash
99
+ # Authentication
100
+ janet login # Authenticate with Janet AI
101
+ janet logout # Clear credentials
102
+ janet auth status # Show authentication status
103
+
104
+ # Organization Management
105
+ janet org list # List your organizations
106
+ janet org select <org-id> # Switch organization
107
+
108
+ # Project Management
109
+ janet project list # List projects in current org
110
+
111
+ # Syncing
112
+ janet sync # Interactive mode
113
+ janet sync --all # Sync all projects (skip selection)
114
+ janet sync --dir ./tickets # Specify custom directory
115
+
116
+ # Status & Configuration
117
+ janet status # Show overall status
118
+ janet config show # Display configuration
119
+ janet --help # Show help
120
+ ```
121
+
122
+ ### Example Workflow
123
+
124
+ ```bash
125
+ # First time setup
126
+ janet login
127
+ janet sync
128
+
129
+ # Re-sync to get updates
130
+ janet sync
131
+
132
+ # Sync to specific directory
133
+ cd /path/to/my/project
134
+ janet sync --dir ./janet-tickets
135
+ ```
136
+
137
+ ## File Organization
138
+
139
+ Tickets are organized in a clear hierarchy:
140
+
141
+ ```
142
+ janet-tickets/
143
+ ├── README.md # Context for AI agents
144
+ └── My Organization/
145
+ ├── Backend/
146
+ │ ├── BACK-1.md
147
+ │ ├── BACK-2.md
148
+ │ └── BACK-42.md
149
+ └── Frontend/
150
+ ├── FRONT-1.md
151
+ └── FRONT-15.md
152
+ ```
153
+
154
+ ## Markdown Format
155
+
156
+ Each ticket is exported with complete information:
157
+
158
+ ```markdown
159
+ # PROJ-42: Add user authentication
160
+
161
+ ## Metadata
162
+ - **Status:** In Progress
163
+ - **Priority:** High
164
+ - **Type:** Feature
165
+ - **Assignees:** John Doe, Jane Smith
166
+ - **Created:** Jan 07, 2026 10:30 AM
167
+ - **Updated:** Jan 07, 2026 02:45 PM
168
+ - **Labels:** backend, security
169
+
170
+ ## Description
171
+
172
+ We need to implement OAuth authentication...
173
+
174
+ ### Requirements
175
+ - Support multiple auth providers
176
+ - Handle token refresh
177
+ - Secure token storage
178
+
179
+ ## Comments (2)
180
+
181
+ ### John Doe - Jan 07, 2026 11:00 AM
182
+
183
+ Started working on the OAuth flow.
184
+
185
+ ### Jane Smith - Jan 07, 2026 01:30 PM
186
+
187
+ Looks good! Add tests when done.
188
+
189
+ ## Attachments (1)
190
+
191
+ ### design-mockup.png
192
+ - **Type:** image/png
193
+ - **Uploaded by:** Jane Smith
194
+ ```
195
+
196
+ ## Configuration
197
+
198
+ The CLI stores configuration at:
199
+ - **macOS/Linux:** `~/.config/janet-cli/config.json`
200
+ - **Windows:** `%APPDATA%\janet-cli\config.json`
201
+
202
+ Configuration includes authentication tokens and your selected organization.
203
+
204
+ ## Requirements
205
+
206
+ - Python 3.8 or higher
207
+ - Janet AI account ([sign up](https://tryjanet.ai))
208
+
209
+ ## License
210
+
211
+ MIT License - see [LICENSE](LICENSE) file for details.
212
+
213
+ ## Acknowledgments
214
+
215
+ Built for [Janet AI](https://tryjanet.ai) - The AI-native project management platform backed by Y Combinator.
216
+
217
+ ---
218
+
219
+ **Current Version:** 0.2.0
220
+ **Status:** Production Ready ✅
@@ -0,0 +1,33 @@
1
+ janet/__init__.py,sha256=Bk05WAYOzsZs3TKPbv1UYe-sbc5J60ppx0B3iwuG5v4,82
2
+ janet/__main__.py,sha256=nxsNRykF1aXRRSYNcMvohre4QDfpUzyr5JMyHRHWrwI,130
3
+ janet/cli.py,sha256=AxjY76l5d7NnsaYEEvUP4dJ1LxXsY1Ya-uNaTGSfXd8,20391
4
+ janet/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ janet/api/client.py,sha256=fiIpCaQlvXBn_T2VGf0sT9jyQE83Xx7o_WJkCDnwykY,4399
6
+ janet/api/models.py,sha256=41or0kCcEJ3KJ2QCdV1xbrAoAcma_DteqqVlO0Ng18g,2002
7
+ janet/api/organizations.py,sha256=abaita6e2drm6RikTOfU-E1ohPeRPhiTYmWRFG0kqaQ,1539
8
+ janet/api/projects.py,sha256=Oxao4vvXMuXWMfUwZUuBrhkSUtC8t57FNc2d6Qzd5ms,1488
9
+ janet/api/tickets.py,sha256=k8EKrShdRVmevNbZahchJI_0iiHosP1QLCWfyFsXGxo,3346
10
+ janet/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ janet/auth/callback_server.py,sha256=mLkkQMMN6PnNUFf4mlQyY3eKOgK1W6_9O9u90xsLMhY,12499
12
+ janet/auth/oauth_flow.py,sha256=YaLQVRXyhAvZ3IWkd3AvjQlCkQgRRjhPEU9fXfZBgko,9133
13
+ janet/auth/token_manager.py,sha256=YxqSmIRiueGYmDxvPeRt--dLpXSfeFd61qCW91FTujU,2721
14
+ janet/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ janet/config/manager.py,sha256=Bs5YjHIzWPR-KuAFJyQL47ntU_JN87bGhROaYP0B3r4,3216
16
+ janet/config/models.py,sha256=2ZLAgM5CwuwQF0C0mZGjxrJO_ECgDGCQ6rnOg68sBp0,1741
17
+ janet/markdown/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ janet/markdown/generator.py,sha256=CgjvCjkna7XsigsrurdSnAXVPYajLQjlP8puuKkSTVM,9168
19
+ janet/markdown/yjs_converter.py,sha256=omoT6dZ0K3UIoSun2fczTw56vbTrHomz64no3U0YUwo,8482
20
+ janet/sync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ janet/sync/file_manager.py,sha256=fwV0VYP-0ZpwTAyDVqlVUPn3MB2wK6TvFQq450Lhr0I,5839
22
+ janet/sync/readme_generator.py,sha256=RHfqlr-3oyGIy5zRbMcloAo1rrwy5aSqAvleC49QZME,6847
23
+ janet/sync/sync_engine.py,sha256=4WEQ6wmcwTWg1cZurQCZTcSBZhKkUtw4eBKUsAcL6WY,9779
24
+ janet/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ janet/utils/console.py,sha256=zMhX4HUXSco-or9KpqBJmYCzmfH_GWtvq-n2Sy6Dfgc,927
26
+ janet/utils/errors.py,sha256=yxoVDF7ovMT7ooJA-8cvxJK8_3nWumGv7s1n8povi-4,783
27
+ janet/utils/paths.py,sha256=JYp5gcSEjIbYNJaUcAwdpz6rmta9m0JzoBARC6_AWmM,1706
28
+ janet_cli-0.2.2.dist-info/licenses/LICENSE,sha256=wNChlibp2El7r-zfLH8QhOg2oLPAvGwP7ETnVWyNRio,1065
29
+ janet_cli-0.2.2.dist-info/METADATA,sha256=8121OXbTb0ZXUbkZ5h0jrNYbCxK8i3I_EvKy3onIgq0,5941
30
+ janet_cli-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
+ janet_cli-0.2.2.dist-info/entry_points.txt,sha256=MeYUkStK_xcqW3AylPNpQh_H5zmfojB1-d8WMhifkvw,40
32
+ janet_cli-0.2.2.dist-info/top_level.txt,sha256=Ux5zWeRoPO3Tu87toTRoiwMkIQNQylV9aRO2g7KqNW4,6
33
+ janet_cli-0.2.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ janet = janet.cli:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Janet AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ janet