cli-web-codewiki 0.1.0__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.
@@ -0,0 +1,486 @@
1
+ """cli-web REPL Skin — Unified terminal interface for all cli-web-* CLIs.
2
+
3
+ CANONICAL SOURCE: cli-web-core/cli_web_core/repl_skin.py
4
+ This file is vendored into every generated CLI at
5
+ cli_web/<app>/utils/repl_skin.py
6
+ by `cli-web-devkit resync` / scaffold-cli.py. Do not edit vendored copies
7
+ by hand — change the canonical source and resync. App-specific needs are
8
+ covered by constructor parameters (`display_name`, `accent`), not by
9
+ editing this file.
10
+
11
+ Usage:
12
+ from cli_web.<app>.utils.repl_skin import ReplSkin
13
+
14
+ skin = ReplSkin("monday", version="1.0.0")
15
+ skin.print_banner()
16
+ prompt_text = skin.prompt(context="Board: Sprint 42")
17
+ skin.success("Items created")
18
+ skin.error("Auth token expired")
19
+ skin.warning("Rate limit approaching")
20
+ skin.info("Fetching 24 items...")
21
+ skin.status("Workspace", "my-team")
22
+ skin.table(headers, rows)
23
+ skin.print_goodbye()
24
+ """
25
+
26
+ import os
27
+ import sys
28
+
29
+ SKIN_VERSION = "2.0.0"
30
+
31
+ # ── ANSI color codes (no external deps for core styling) ──────────────
32
+
33
+ _RESET = "\033[0m"
34
+ _BOLD = "\033[1m"
35
+ _DIM = "\033[2m"
36
+ _ITALIC = "\033[3m"
37
+ _UNDERLINE = "\033[4m"
38
+
39
+ # Brand colors
40
+ _CYAN = "\033[38;5;80m" # cli-web brand cyan
41
+ _CYAN_BG = "\033[48;5;80m"
42
+ _WHITE = "\033[97m"
43
+ _GRAY = "\033[38;5;245m"
44
+ _DARK_GRAY = "\033[38;5;240m"
45
+ _LIGHT_GRAY = "\033[38;5;250m"
46
+
47
+ # Web app accent colors — each app gets a unique accent.
48
+ # Prefer passing `accent=` to ReplSkin for new apps; this dict exists so
49
+ # vendored copies stay byte-identical across the fleet.
50
+ _ACCENT_COLORS = {
51
+ "monday": "\033[38;5;214m", # warm orange (Monday.com brand)
52
+ "notion": "\033[38;5;255m", # near-white (Notion brand)
53
+ "linear": "\033[38;5;99m", # purple (Linear brand)
54
+ "jira": "\033[38;5;27m", # blue (Jira brand)
55
+ "slack": "\033[38;5;55m", # aubergine (Slack brand)
56
+ "github": "\033[38;5;240m", # dark gray (GitHub brand)
57
+ "figma": "\033[38;5;213m", # pink (Figma brand)
58
+ "airtable": "\033[38;5;35m", # green (Airtable brand)
59
+ "asana": "\033[38;5;196m", # red (Asana brand)
60
+ "trello": "\033[38;5;39m", # blue (Trello brand)
61
+ # Fleet apps
62
+ "amazon": "\033[38;5;214m", # Amazon orange (#FF9900)
63
+ "airbnb": "\033[38;5;197m", # Airbnb rausch pink
64
+ "linkedin": "\033[38;5;32m", # LinkedIn blue
65
+ "reddit": "\033[38;5;202m", # Reddit orangered
66
+ "youtube": "\033[38;5;196m", # YouTube red
67
+ "hackernews": "\033[38;5;208m", # HN orange
68
+ "unsplash": "\033[38;5;240m", # Unsplash dark gray
69
+ "pexels": "\033[38;5;36m", # Pexels teal
70
+ "producthunt": "\033[38;5;209m", # Product Hunt coral
71
+ "booking": "\033[38;5;26m", # Booking blue
72
+ "tripadvisor": "\033[38;5;40m", # TripAdvisor green
73
+ "futbin": "\033[38;5;70m", # FUTBIN pitch green
74
+ "capitoltrades": "\033[38;5;30m", # CapitolTrades teal
75
+ }
76
+ _DEFAULT_ACCENT = "\033[38;5;75m" # default sky blue
77
+
78
+ # Status colors
79
+ _GREEN = "\033[38;5;78m"
80
+ _YELLOW = "\033[38;5;220m"
81
+ _RED = "\033[38;5;196m"
82
+ _BLUE = "\033[38;5;75m"
83
+ _MAGENTA = "\033[38;5;176m"
84
+
85
+ # ── Brand icon ────────────────────────────────────────────────────────
86
+
87
+ _ICON = f"{_CYAN}{_BOLD}◆{_RESET}"
88
+ _ICON_SMALL = f"{_CYAN}▸{_RESET}"
89
+
90
+ # ── Box drawing characters ────────────────────────────────────────────
91
+
92
+ _H_LINE = "─"
93
+ _V_LINE = "│"
94
+ _TL = "╭"
95
+ _TR = "╮"
96
+ _BL = "╰"
97
+ _BR = "╯"
98
+ _T_DOWN = "┬"
99
+ _T_UP = "┴"
100
+ _T_RIGHT = "├"
101
+ _T_LEFT = "┤"
102
+ _CROSS = "┼"
103
+
104
+
105
+ def _strip_ansi(text: str) -> str:
106
+ """Remove ANSI escape codes for length calculation."""
107
+ import re
108
+
109
+ return re.sub(r"\033\[[^m]*m", "", text)
110
+
111
+
112
+ def _visible_len(text: str) -> int:
113
+ """Get visible length of text (excluding ANSI codes)."""
114
+ return len(_strip_ansi(text))
115
+
116
+
117
+ class ReplSkin:
118
+ """Unified REPL skin for cli-web-* CLIs.
119
+
120
+ Provides consistent branding, prompts, and message formatting
121
+ across all CLI harnesses built with the cli-anything-web methodology.
122
+ """
123
+
124
+ def __init__(
125
+ self,
126
+ app: str,
127
+ version: str = "1.0.0",
128
+ history_file: str | None = None,
129
+ display_name: str | None = None,
130
+ accent: str | None = None,
131
+ ):
132
+ """Initialize the REPL skin.
133
+
134
+ Args:
135
+ app: App name (e.g., "monday", "notion", "jira").
136
+ version: CLI version string.
137
+ history_file: Path for persistent command history.
138
+ Defaults to ~/.cli-web-<app>/history
139
+ display_name: Override for the banner display name.
140
+ accent: ANSI escape for the brand accent color (overrides
141
+ the built-in per-app table).
142
+ """
143
+ self.app = app.lower().replace("-", "_")
144
+ self.display_name = display_name or app.replace("_", " ").title()
145
+ self.version = version
146
+ self.accent = accent or _ACCENT_COLORS.get(self.app, _DEFAULT_ACCENT)
147
+
148
+ # History file path. The directory is created lazily in
149
+ # create_prompt_session() — CLIs construct ReplSkin at module import
150
+ # time, and one-shot commands must not pay (or fail on) filesystem
151
+ # writes they never use.
152
+ if history_file is None:
153
+ from pathlib import Path
154
+
155
+ hist_dir = Path.home() / f".cli-web-{self.app}"
156
+ self.history_file = str(hist_dir / "history")
157
+ else:
158
+ self.history_file = history_file
159
+
160
+ # Detect terminal capabilities
161
+ self._color = self._detect_color_support()
162
+
163
+ def _detect_color_support(self) -> bool:
164
+ """Check if terminal supports color."""
165
+ if os.environ.get("NO_COLOR"):
166
+ return False
167
+ if os.environ.get("CLI_WEB_NO_COLOR"):
168
+ return False
169
+ if not hasattr(sys.stdout, "isatty"):
170
+ return False
171
+ return sys.stdout.isatty()
172
+
173
+ def _c(self, code: str, text: str) -> str:
174
+ """Apply color code if colors are supported."""
175
+ if not self._color:
176
+ return text
177
+ return f"{code}{text}{_RESET}"
178
+
179
+ # ── Banner ────────────────────────────────────────────────────────
180
+
181
+ def print_banner(self):
182
+ """Print the startup banner with branding."""
183
+ inner = 54
184
+
185
+ def _box_line(content: str) -> str:
186
+ """Wrap content in box drawing, padding to inner width."""
187
+ pad = inner - _visible_len(content)
188
+ vl = self._c(_DARK_GRAY, _V_LINE)
189
+ return f"{vl}{content}{' ' * max(0, pad)}{vl}"
190
+
191
+ top = self._c(_DARK_GRAY, f"{_TL}{_H_LINE * inner}{_TR}")
192
+ bot = self._c(_DARK_GRAY, f"{_BL}{_H_LINE * inner}{_BR}")
193
+
194
+ # Title: ◆ cli-web · Monday
195
+ icon = self._c(_CYAN + _BOLD, "◆")
196
+ brand = self._c(_CYAN + _BOLD, "cli-web")
197
+ dot = self._c(_DARK_GRAY, "·")
198
+ name = self._c(self.accent + _BOLD, self.display_name)
199
+ title = f" {icon} {brand} {dot} {name}"
200
+
201
+ ver = f" {self._c(_DARK_GRAY, f' v{self.version}')}"
202
+ tip = f" {self._c(_DARK_GRAY, ' Type help for commands, quit to exit')}"
203
+ empty = ""
204
+
205
+ print(top)
206
+ print(_box_line(title))
207
+ print(_box_line(ver))
208
+ print(_box_line(empty))
209
+ print(_box_line(tip))
210
+ print(bot)
211
+ print()
212
+
213
+ # ── Prompt ────────────────────────────────────────────────────────
214
+
215
+ def prompt(self, project_name: str = "", modified: bool = False, context: str = "") -> str:
216
+ """Build a styled prompt string for prompt_toolkit or input()."""
217
+ parts = []
218
+
219
+ if self._color:
220
+ parts.append(f"{_CYAN}◆{_RESET} ")
221
+ else:
222
+ parts.append("> ")
223
+
224
+ parts.append(self._c(self.accent + _BOLD, self.app))
225
+
226
+ if project_name or context:
227
+ ctx = context or project_name
228
+ mod = "*" if modified else ""
229
+ parts.append(f" {self._c(_DARK_GRAY, '[')}")
230
+ parts.append(self._c(_LIGHT_GRAY, f"{ctx}{mod}"))
231
+ parts.append(self._c(_DARK_GRAY, "]"))
232
+
233
+ parts.append(self._c(_GRAY, " ❯ "))
234
+
235
+ return "".join(parts)
236
+
237
+ def prompt_tokens(self, project_name: str = "", modified: bool = False, context: str = ""):
238
+ """Build prompt_toolkit formatted text tokens for the prompt."""
239
+ tokens = []
240
+
241
+ tokens.append(("class:icon", "◆ "))
242
+ tokens.append(("class:app", self.app))
243
+
244
+ if project_name or context:
245
+ ctx = context or project_name
246
+ mod = "*" if modified else ""
247
+ tokens.append(("class:bracket", " ["))
248
+ tokens.append(("class:context", f"{ctx}{mod}"))
249
+ tokens.append(("class:bracket", "]"))
250
+
251
+ tokens.append(("class:arrow", " ❯ "))
252
+
253
+ return tokens
254
+
255
+ def get_prompt_style(self):
256
+ """Get a prompt_toolkit Style object matching the skin."""
257
+ try:
258
+ from prompt_toolkit.styles import Style
259
+ except Exception: # noqa: BLE001 — optional dep must never break the REPL
260
+ return None
261
+
262
+ accent_hex = _ANSI_256_TO_HEX.get(self.accent, "#5fafff")
263
+
264
+ return Style.from_dict(
265
+ {
266
+ "icon": "#5fdfdf bold",
267
+ "app": f"{accent_hex} bold",
268
+ "bracket": "#585858",
269
+ "context": "#bcbcbc",
270
+ "arrow": "#808080",
271
+ "completion-menu.completion": "bg:#303030 #bcbcbc",
272
+ "completion-menu.completion.current": f"bg:{accent_hex} #000000",
273
+ "completion-menu.meta.completion": "bg:#303030 #808080",
274
+ "completion-menu.meta.completion.current": f"bg:{accent_hex} #000000",
275
+ "auto-suggest": "#585858",
276
+ "bottom-toolbar": "bg:#1c1c1c #808080",
277
+ "bottom-toolbar.text": "#808080",
278
+ }
279
+ )
280
+
281
+ # ── Messages ──────────────────────────────────────────────────────
282
+
283
+ def success(self, message: str):
284
+ """Print a success message with green checkmark."""
285
+ icon = self._c(_GREEN + _BOLD, "✓")
286
+ print(f" {icon} {self._c(_GREEN, message)}")
287
+
288
+ def error(self, message: str):
289
+ """Print an error message with red cross."""
290
+ icon = self._c(_RED + _BOLD, "✗")
291
+ print(f" {icon} {self._c(_RED, message)}", file=sys.stderr)
292
+
293
+ def warning(self, message: str):
294
+ """Print a warning message with yellow triangle."""
295
+ icon = self._c(_YELLOW + _BOLD, "⚠")
296
+ print(f" {icon} {self._c(_YELLOW, message)}")
297
+
298
+ def info(self, message: str):
299
+ """Print an info message with blue dot."""
300
+ icon = self._c(_BLUE, "●")
301
+ print(f" {icon} {self._c(_LIGHT_GRAY, message)}")
302
+
303
+ def hint(self, message: str):
304
+ """Print a subtle hint message."""
305
+ print(f" {self._c(_DARK_GRAY, message)}")
306
+
307
+ def section(self, title: str):
308
+ """Print a section header."""
309
+ print()
310
+ print(f" {self._c(self.accent + _BOLD, title)}")
311
+ print(f" {self._c(_DARK_GRAY, _H_LINE * len(title))}")
312
+
313
+ # ── Status display ────────────────────────────────────────────────
314
+
315
+ def status(self, label: str, value: str):
316
+ """Print a key-value status line."""
317
+ lbl = self._c(_GRAY, f" {label}:")
318
+ val = self._c(_WHITE, f" {value}")
319
+ print(f"{lbl}{val}")
320
+
321
+ def status_block(self, items: dict[str, str], title: str = ""):
322
+ """Print a block of status key-value pairs."""
323
+ if title:
324
+ self.section(title)
325
+
326
+ max_key = max(len(k) for k in items) if items else 0
327
+ for label, value in items.items():
328
+ lbl = self._c(_GRAY, f" {label:<{max_key}}")
329
+ val = self._c(_WHITE, f" {value}")
330
+ print(f"{lbl}{val}")
331
+
332
+ def progress(self, current: int, total: int, label: str = ""):
333
+ """Print a simple progress indicator."""
334
+ pct = int(current / total * 100) if total > 0 else 0
335
+ bar_width = 20
336
+ filled = int(bar_width * current / total) if total > 0 else 0
337
+ bar = "█" * filled + "░" * (bar_width - filled)
338
+ text = f" {self._c(_CYAN, bar)} {self._c(_GRAY, f'{pct:3d}%')}"
339
+ if label:
340
+ text += f" {self._c(_LIGHT_GRAY, label)}"
341
+ print(text)
342
+
343
+ # ── Table display ─────────────────────────────────────────────────
344
+
345
+ def table(self, headers: list[str], rows: list[list[str]], max_col_width: int = 40):
346
+ """Print a formatted table with box-drawing characters."""
347
+ if not headers:
348
+ return
349
+
350
+ col_widths = [min(len(h), max_col_width) for h in headers]
351
+ for row in rows:
352
+ for i, cell in enumerate(row):
353
+ if i < len(col_widths):
354
+ col_widths[i] = min(max(col_widths[i], len(str(cell))), max_col_width)
355
+
356
+ def pad(text: str, width: int) -> str:
357
+ t = str(text)[:width]
358
+ return t + " " * (width - len(t))
359
+
360
+ header_cells = [
361
+ self._c(_CYAN + _BOLD, pad(h, col_widths[i])) for i, h in enumerate(headers)
362
+ ]
363
+ sep = self._c(_DARK_GRAY, f" {_V_LINE} ")
364
+ print(f" {sep.join(header_cells)}")
365
+
366
+ sep_line = self._c(_DARK_GRAY, f" {'───'.join([_H_LINE * w for w in col_widths])}")
367
+ print(sep_line)
368
+
369
+ for row in rows:
370
+ cells = []
371
+ for i, cell in enumerate(row):
372
+ if i < len(col_widths):
373
+ cells.append(self._c(_LIGHT_GRAY, pad(str(cell), col_widths[i])))
374
+ row_sep = self._c(_DARK_GRAY, f" {_V_LINE} ")
375
+ print(f" {row_sep.join(cells)}")
376
+
377
+ # ── Help display ──────────────────────────────────────────────────
378
+
379
+ def help(self, commands: dict[str, str]):
380
+ """Print a formatted help listing."""
381
+ self.section("Commands")
382
+ max_cmd = max(len(c) for c in commands) if commands else 0
383
+ for cmd, desc in commands.items():
384
+ cmd_styled = self._c(self.accent, f" {cmd:<{max_cmd}}")
385
+ desc_styled = self._c(_GRAY, f" {desc}")
386
+ print(f"{cmd_styled}{desc_styled}")
387
+ print()
388
+
389
+ # ── Goodbye ───────────────────────────────────────────────────────
390
+
391
+ def print_goodbye(self):
392
+ """Print a styled goodbye message."""
393
+ print(f"\n {_ICON_SMALL} {self._c(_GRAY, 'Goodbye!')}\n")
394
+
395
+ # ── Prompt toolkit session factory ────────────────────────────────
396
+
397
+ def create_prompt_session(self):
398
+ """Create a prompt_toolkit PromptSession with skin styling."""
399
+ try:
400
+ from pathlib import Path
401
+
402
+ from prompt_toolkit import PromptSession
403
+ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
404
+ from prompt_toolkit.history import FileHistory, InMemoryHistory
405
+
406
+ style = self.get_prompt_style()
407
+
408
+ try:
409
+ Path(self.history_file).parent.mkdir(parents=True, exist_ok=True)
410
+ history = FileHistory(self.history_file)
411
+ except OSError: # read-only HOME — run without persistent history
412
+ history = InMemoryHistory()
413
+
414
+ session = PromptSession(
415
+ history=history,
416
+ auto_suggest=AutoSuggestFromHistory(),
417
+ style=style,
418
+ enable_history_search=True,
419
+ )
420
+ return session
421
+ except Exception: # noqa: BLE001 — optional dep must never break the REPL
422
+ return None
423
+
424
+ def get_input(
425
+ self, pt_session, project_name: str = "", modified: bool = False, context: str = ""
426
+ ) -> str:
427
+ """Get input from user using prompt_toolkit or fallback."""
428
+ if pt_session is not None:
429
+ from prompt_toolkit.formatted_text import FormattedText
430
+
431
+ tokens = self.prompt_tokens(project_name, modified, context)
432
+ return pt_session.prompt(FormattedText(tokens)).strip()
433
+ else:
434
+ raw_prompt = self.prompt(project_name, modified, context)
435
+ return input(raw_prompt).strip()
436
+
437
+ # ── Toolbar builder ───────────────────────────────────────────────
438
+
439
+ def bottom_toolbar(self, items: dict[str, str]):
440
+ """Create a bottom toolbar callback for prompt_toolkit."""
441
+
442
+ def toolbar():
443
+ from prompt_toolkit.formatted_text import FormattedText
444
+
445
+ parts = []
446
+ for i, (k, v) in enumerate(items.items()):
447
+ if i > 0:
448
+ parts.append(("class:bottom-toolbar.text", " │ "))
449
+ parts.append(("class:bottom-toolbar.text", f" {k}: "))
450
+ parts.append(("class:bottom-toolbar", v))
451
+ return FormattedText(parts)
452
+
453
+ return toolbar
454
+
455
+
456
+ # ── ANSI 256-color to hex mapping (for prompt_toolkit styles) ─────────
457
+
458
+ _ANSI_256_TO_HEX = {
459
+ # Base entries (from reference implementation)
460
+ "\033[38;5;33m": "#0087ff",
461
+ "\033[38;5;35m": "#00af5f",
462
+ "\033[38;5;39m": "#00afff",
463
+ "\033[38;5;40m": "#00d700",
464
+ "\033[38;5;55m": "#5f00af",
465
+ "\033[38;5;69m": "#5f87ff",
466
+ "\033[38;5;75m": "#5fafff",
467
+ "\033[38;5;80m": "#5fd7d7",
468
+ "\033[38;5;208m": "#ff8700",
469
+ "\033[38;5;214m": "#ffaf00",
470
+ # Web app accent colors
471
+ "\033[38;5;255m": "#eeeeee", # notion
472
+ "\033[38;5;99m": "#875fff", # linear
473
+ "\033[38;5;27m": "#005fff", # jira
474
+ "\033[38;5;240m": "#585858", # github
475
+ "\033[38;5;213m": "#ff87ff", # figma
476
+ "\033[38;5;196m": "#ff0000", # asana
477
+ # Fleet apps
478
+ "\033[38;5;197m": "#ff005f", # airbnb
479
+ "\033[38;5;32m": "#0087d7", # linkedin
480
+ "\033[38;5;202m": "#ff5f00", # reddit
481
+ "\033[38;5;36m": "#00af87", # pexels
482
+ "\033[38;5;209m": "#ff875f", # producthunt
483
+ "\033[38;5;26m": "#005fd7", # booking
484
+ "\033[38;5;70m": "#5faf00", # futbin
485
+ "\033[38;5;30m": "#008787", # capitoltrades
486
+ }
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.4
2
+ Name: cli-web-codewiki
3
+ Version: 0.1.0
4
+ Summary: CLI for Google Code Wiki — AI-generated documentation for open source repos
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: click>=8.0
7
+ Requires-Dist: httpx>=0.24
8
+ Requires-Dist: rich>=13.0
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest>=7.0; extra == "dev"
11
+ Dynamic: provides-extra
12
+ Dynamic: requires-dist
13
+ Dynamic: requires-python
14
+ Dynamic: summary
@@ -0,0 +1,30 @@
1
+ cli_web/codewiki/__init__.py,sha256=0BAnckUl3p09NdXpaBElwXJrWZc5mCoor_YneFwrxwI,76
2
+ cli_web/codewiki/__main__.py,sha256=UqAs7_5Rqpr63ulBhHqrvUYBCnIOdKaWgi70oFJlBpc,122
3
+ cli_web/codewiki/codewiki_cli.py,sha256=eOd9w8sMfIyrpt62udKkiDp5WsoZHjGAnraZ1VCSP5o,4555
4
+ cli_web/codewiki/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ cli_web/codewiki/commands/chat.py,sha256=P8ZbaADZnQ07mAfOw6_ONRclpOMitr6FAjleIvoqLqo,1344
6
+ cli_web/codewiki/commands/repos.py,sha256=s_YsBNZVk66CEJA06TqoXOgzrEmzRXcFTxyEHIfW4ak,2704
7
+ cli_web/codewiki/commands/wiki.py,sha256=QE_poAeGbk-Ug4FkCIjlOtxj1CaDIJ1YI4O8AjWwHpk,9217
8
+ cli_web/codewiki/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ cli_web/codewiki/core/client.py,sha256=drY7lNQshDZfpNsotkH8NnZnKLTPP3jpl6z5rAONr-s,8343
10
+ cli_web/codewiki/core/exceptions.py,sha256=ZPv98rkxoHC9Q3E-VJ3nGAtekpithhhLJc4DI4DXTrw,2012
11
+ cli_web/codewiki/core/models.py,sha256=uUcG2OlSdah1yEwZpvdIjgvgtpBKuvvBkiQ-pgvnWI0,2167
12
+ cli_web/codewiki/core/rpc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ cli_web/codewiki/core/rpc/decoder.py,sha256=PitmIH9YY89jCIqOCey6dJ6MSqChq9CuOPugO2zqtqg,2611
14
+ cli_web/codewiki/core/rpc/encoder.py,sha256=EAaaXj2mqe0VvD91VrfCts2kowowiHtyLsTis8mhR9Y,862
15
+ cli_web/codewiki/core/rpc/types.py,sha256=ncNd4aiofEwVG6fkPocGAhA_Qqa83FZb-_qxH9tshWc,711
16
+ cli_web/codewiki/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ cli_web/codewiki/tests/test_core.py,sha256=0HG7nXx5XAL-x1nHQr_vegcfhicEk4xU6bu04hUZVqc,26466
18
+ cli_web/codewiki/tests/test_e2e.py,sha256=kTbjESpoKbpDC2bkq_KG_UXtMu4FBKYcAuX6loFL8TA,15165
19
+ cli_web/codewiki/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ cli_web/codewiki/utils/config.py,sha256=3S7LPPxJWdln0MH1aeLAYPYnD8CyGWuwvZCyjYoVak0,356
21
+ cli_web/codewiki/utils/doctor.py,sha256=HI3u85HWruCjG2VK8cwel_TSX3zejPTWqAibiPHCTAQ,6552
22
+ cli_web/codewiki/utils/helpers.py,sha256=j9lLulm2eaxWwlEsNBMSDIA3_8IcZQQr2p0FHDxB5B0,1827
23
+ cli_web/codewiki/utils/mcp_server.py,sha256=5rDTR5487yE08gAIgKC8Bqs3RwR2JiSQUfCATYV7r9w,10768
24
+ cli_web/codewiki/utils/output.py,sha256=B5XxI5gnyIBVNjsn4YFfh3NLHnHmgEyKFaHbVMSDiO0,309
25
+ cli_web/codewiki/utils/repl_skin.py,sha256=fIqMbQ5SBYSGzPOoTDT6VE67sFSw0pfS7VPGIdeBmJU,18749
26
+ cli_web_codewiki-0.1.0.dist-info/METADATA,sha256=tLhypiWZhhKytikRnThATeNLvEvVYX9tA1r07w5r2TA,402
27
+ cli_web_codewiki-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
28
+ cli_web_codewiki-0.1.0.dist-info/entry_points.txt,sha256=pgsSTex33MK17dzpog-NvjtnSaUb0PblFQwnMRGVHBE,72
29
+ cli_web_codewiki-0.1.0.dist-info/top_level.txt,sha256=nqEsw6-b5Wtzip1g13XiADPkuClajm6oyFis-CZv-wY,8
30
+ cli_web_codewiki-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cli-web-codewiki = cli_web.codewiki.codewiki_cli:main
@@ -0,0 +1 @@
1
+ cli_web