codemaster-cli 2.2.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.
- codemaster_cli-2.2.0.dist-info/METADATA +645 -0
- codemaster_cli-2.2.0.dist-info/RECORD +170 -0
- codemaster_cli-2.2.0.dist-info/WHEEL +4 -0
- codemaster_cli-2.2.0.dist-info/entry_points.txt +3 -0
- vibe/__init__.py +6 -0
- vibe/acp/__init__.py +0 -0
- vibe/acp/acp_agent_loop.py +746 -0
- vibe/acp/entrypoint.py +81 -0
- vibe/acp/tools/__init__.py +0 -0
- vibe/acp/tools/base.py +100 -0
- vibe/acp/tools/builtins/bash.py +134 -0
- vibe/acp/tools/builtins/read_file.py +54 -0
- vibe/acp/tools/builtins/search_replace.py +129 -0
- vibe/acp/tools/builtins/todo.py +65 -0
- vibe/acp/tools/builtins/write_file.py +98 -0
- vibe/acp/tools/session_update.py +118 -0
- vibe/acp/utils.py +213 -0
- vibe/cli/__init__.py +0 -0
- vibe/cli/autocompletion/__init__.py +0 -0
- vibe/cli/autocompletion/base.py +22 -0
- vibe/cli/autocompletion/path_completion.py +177 -0
- vibe/cli/autocompletion/slash_command.py +99 -0
- vibe/cli/cli.py +188 -0
- vibe/cli/clipboard.py +69 -0
- vibe/cli/commands.py +116 -0
- vibe/cli/entrypoint.py +163 -0
- vibe/cli/history_manager.py +91 -0
- vibe/cli/plan_offer/adapters/http_whoami_gateway.py +67 -0
- vibe/cli/plan_offer/decide_plan_offer.py +87 -0
- vibe/cli/plan_offer/ports/whoami_gateway.py +23 -0
- vibe/cli/terminal_setup.py +323 -0
- vibe/cli/textual_ui/__init__.py +0 -0
- vibe/cli/textual_ui/ansi_markdown.py +58 -0
- vibe/cli/textual_ui/app.py +1546 -0
- vibe/cli/textual_ui/app.tcss +1020 -0
- vibe/cli/textual_ui/external_editor.py +32 -0
- vibe/cli/textual_ui/handlers/__init__.py +5 -0
- vibe/cli/textual_ui/handlers/event_handler.py +147 -0
- vibe/cli/textual_ui/widgets/__init__.py +0 -0
- vibe/cli/textual_ui/widgets/approval_app.py +192 -0
- vibe/cli/textual_ui/widgets/banner/banner.py +85 -0
- vibe/cli/textual_ui/widgets/banner/petit_chat.py +195 -0
- vibe/cli/textual_ui/widgets/braille_renderer.py +58 -0
- vibe/cli/textual_ui/widgets/chat_input/__init__.py +7 -0
- vibe/cli/textual_ui/widgets/chat_input/body.py +214 -0
- vibe/cli/textual_ui/widgets/chat_input/completion_manager.py +58 -0
- vibe/cli/textual_ui/widgets/chat_input/completion_popup.py +43 -0
- vibe/cli/textual_ui/widgets/chat_input/container.py +195 -0
- vibe/cli/textual_ui/widgets/chat_input/text_area.py +365 -0
- vibe/cli/textual_ui/widgets/compact.py +41 -0
- vibe/cli/textual_ui/widgets/config_app.py +171 -0
- vibe/cli/textual_ui/widgets/context_progress.py +30 -0
- vibe/cli/textual_ui/widgets/load_more.py +43 -0
- vibe/cli/textual_ui/widgets/loading.py +201 -0
- vibe/cli/textual_ui/widgets/messages.py +277 -0
- vibe/cli/textual_ui/widgets/no_markup_static.py +11 -0
- vibe/cli/textual_ui/widgets/path_display.py +28 -0
- vibe/cli/textual_ui/widgets/proxy_setup_app.py +127 -0
- vibe/cli/textual_ui/widgets/question_app.py +496 -0
- vibe/cli/textual_ui/widgets/spinner.py +194 -0
- vibe/cli/textual_ui/widgets/status_message.py +76 -0
- vibe/cli/textual_ui/widgets/teleport_message.py +31 -0
- vibe/cli/textual_ui/widgets/tool_widgets.py +371 -0
- vibe/cli/textual_ui/widgets/tools.py +201 -0
- vibe/cli/textual_ui/windowing/__init__.py +29 -0
- vibe/cli/textual_ui/windowing/history.py +105 -0
- vibe/cli/textual_ui/windowing/history_windowing.py +71 -0
- vibe/cli/textual_ui/windowing/state.py +105 -0
- vibe/cli/update_notifier/__init__.py +47 -0
- vibe/cli/update_notifier/adapters/filesystem_update_cache_repository.py +59 -0
- vibe/cli/update_notifier/adapters/github_update_gateway.py +101 -0
- vibe/cli/update_notifier/adapters/pypi_update_gateway.py +107 -0
- vibe/cli/update_notifier/ports/update_cache_repository.py +16 -0
- vibe/cli/update_notifier/ports/update_gateway.py +53 -0
- vibe/cli/update_notifier/update.py +139 -0
- vibe/cli/update_notifier/whats_new.py +49 -0
- vibe/core/__init__.py +5 -0
- vibe/core/agent_loop.py +1075 -0
- vibe/core/agents/__init__.py +31 -0
- vibe/core/agents/manager.py +165 -0
- vibe/core/agents/models.py +122 -0
- vibe/core/auth/__init__.py +6 -0
- vibe/core/auth/crypto.py +137 -0
- vibe/core/auth/github.py +178 -0
- vibe/core/autocompletion/__init__.py +0 -0
- vibe/core/autocompletion/completers.py +257 -0
- vibe/core/autocompletion/file_indexer/__init__.py +10 -0
- vibe/core/autocompletion/file_indexer/ignore_rules.py +156 -0
- vibe/core/autocompletion/file_indexer/indexer.py +179 -0
- vibe/core/autocompletion/file_indexer/store.py +169 -0
- vibe/core/autocompletion/file_indexer/watcher.py +71 -0
- vibe/core/autocompletion/fuzzy.py +189 -0
- vibe/core/autocompletion/path_prompt.py +108 -0
- vibe/core/autocompletion/path_prompt_adapter.py +149 -0
- vibe/core/config.py +673 -0
- vibe/core/config_PATCH_INSTRUCTIONS.md +77 -0
- vibe/core/llm/__init__.py +0 -0
- vibe/core/llm/backend/anthropic.py +630 -0
- vibe/core/llm/backend/base.py +38 -0
- vibe/core/llm/backend/factory.py +7 -0
- vibe/core/llm/backend/generic.py +425 -0
- vibe/core/llm/backend/mistral.py +381 -0
- vibe/core/llm/backend/vertex.py +115 -0
- vibe/core/llm/exceptions.py +195 -0
- vibe/core/llm/format.py +184 -0
- vibe/core/llm/message_utils.py +24 -0
- vibe/core/llm/types.py +120 -0
- vibe/core/middleware.py +209 -0
- vibe/core/output_formatters.py +85 -0
- vibe/core/paths/__init__.py +0 -0
- vibe/core/paths/config_paths.py +68 -0
- vibe/core/paths/global_paths.py +40 -0
- vibe/core/programmatic.py +56 -0
- vibe/core/prompts/__init__.py +32 -0
- vibe/core/prompts/cli.md +111 -0
- vibe/core/prompts/compact.md +48 -0
- vibe/core/prompts/dangerous_directory.md +5 -0
- vibe/core/prompts/explore.md +50 -0
- vibe/core/prompts/project_context.md +8 -0
- vibe/core/prompts/tests.md +1 -0
- vibe/core/proxy_setup.py +65 -0
- vibe/core/session/session_loader.py +222 -0
- vibe/core/session/session_logger.py +318 -0
- vibe/core/session/session_migration.py +41 -0
- vibe/core/skills/__init__.py +7 -0
- vibe/core/skills/manager.py +132 -0
- vibe/core/skills/models.py +92 -0
- vibe/core/skills/parser.py +39 -0
- vibe/core/system_prompt.py +466 -0
- vibe/core/telemetry/__init__.py +0 -0
- vibe/core/telemetry/send.py +185 -0
- vibe/core/teleport/errors.py +9 -0
- vibe/core/teleport/git.py +196 -0
- vibe/core/teleport/nuage.py +180 -0
- vibe/core/teleport/teleport.py +208 -0
- vibe/core/teleport/types.py +54 -0
- vibe/core/tools/base.py +336 -0
- vibe/core/tools/builtins/ask_user_question.py +134 -0
- vibe/core/tools/builtins/bash.py +357 -0
- vibe/core/tools/builtins/grep.py +310 -0
- vibe/core/tools/builtins/prompts/__init__.py +0 -0
- vibe/core/tools/builtins/prompts/ask_user_question.md +84 -0
- vibe/core/tools/builtins/prompts/bash.md +73 -0
- vibe/core/tools/builtins/prompts/grep.md +4 -0
- vibe/core/tools/builtins/prompts/read_file.md +13 -0
- vibe/core/tools/builtins/prompts/search_replace.md +43 -0
- vibe/core/tools/builtins/prompts/task.md +24 -0
- vibe/core/tools/builtins/prompts/todo.md +199 -0
- vibe/core/tools/builtins/prompts/write_file.md +42 -0
- vibe/core/tools/builtins/read_file.py +222 -0
- vibe/core/tools/builtins/search_replace.py +456 -0
- vibe/core/tools/builtins/task.py +154 -0
- vibe/core/tools/builtins/todo.py +134 -0
- vibe/core/tools/builtins/write_file.py +160 -0
- vibe/core/tools/manager.py +341 -0
- vibe/core/tools/mcp.py +397 -0
- vibe/core/tools/ui.py +68 -0
- vibe/core/trusted_folders.py +86 -0
- vibe/core/types.py +405 -0
- vibe/core/utils.py +396 -0
- vibe/setup/onboarding/__init__.py +39 -0
- vibe/setup/onboarding/base.py +14 -0
- vibe/setup/onboarding/onboarding.tcss +134 -0
- vibe/setup/onboarding/screens/__init__.py +5 -0
- vibe/setup/onboarding/screens/api_key.py +200 -0
- vibe/setup/onboarding/screens/provider_selection.py +87 -0
- vibe/setup/onboarding/screens/welcome.py +136 -0
- vibe/setup/trusted_folders/trust_folder_dialog.py +180 -0
- vibe/setup/trusted_folders/trust_folder_dialog.tcss +83 -0
- vibe/whats_new.md +5 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
from packaging.version import InvalidVersion, Version
|
|
9
|
+
|
|
10
|
+
from vibe.cli.update_notifier import (
|
|
11
|
+
DEFAULT_GATEWAY_MESSAGES,
|
|
12
|
+
UpdateCache,
|
|
13
|
+
UpdateCacheRepository,
|
|
14
|
+
UpdateGateway,
|
|
15
|
+
UpdateGatewayCause,
|
|
16
|
+
UpdateGatewayError,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
UPDATE_CACHE_TTL_SECONDS = 24 * 60 * 60
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True, slots=True)
|
|
23
|
+
class UpdateAvailability:
|
|
24
|
+
latest_version: str
|
|
25
|
+
should_notify: bool
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class UpdateError(Exception):
|
|
29
|
+
def __init__(self, message: str) -> None:
|
|
30
|
+
self.message = message
|
|
31
|
+
super().__init__(message)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _parse_version(raw: str) -> Version | None:
|
|
35
|
+
try:
|
|
36
|
+
return Version(raw.replace("-", "+"))
|
|
37
|
+
except InvalidVersion:
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _describe_gateway_error(error: UpdateGatewayError) -> str:
|
|
42
|
+
if message := getattr(error, "user_message", None):
|
|
43
|
+
return message
|
|
44
|
+
|
|
45
|
+
cause = getattr(error, "cause", UpdateGatewayCause.UNKNOWN)
|
|
46
|
+
if isinstance(cause, UpdateGatewayCause):
|
|
47
|
+
return DEFAULT_GATEWAY_MESSAGES.get(
|
|
48
|
+
cause, DEFAULT_GATEWAY_MESSAGES[UpdateGatewayCause.UNKNOWN]
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return DEFAULT_GATEWAY_MESSAGES[UpdateGatewayCause.UNKNOWN]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _is_cache_fresh(
|
|
55
|
+
cache: UpdateCache, get_current_timestamp: Callable[[], int]
|
|
56
|
+
) -> bool:
|
|
57
|
+
return (
|
|
58
|
+
cache.stored_at_timestamp > get_current_timestamp() - UPDATE_CACHE_TTL_SECONDS
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _get_cached_update_if_any(
|
|
63
|
+
cache: UpdateCache, current: Version
|
|
64
|
+
) -> UpdateAvailability | None:
|
|
65
|
+
latest_version_in_cache = _parse_version(cache.latest_version)
|
|
66
|
+
if latest_version_in_cache is None or latest_version_in_cache <= current:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
return UpdateAvailability(latest_version=cache.latest_version, should_notify=False)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
async def _write_update_cache(
|
|
73
|
+
repository: UpdateCacheRepository,
|
|
74
|
+
version: str,
|
|
75
|
+
get_current_timestamp: Callable[[], int],
|
|
76
|
+
) -> None:
|
|
77
|
+
await repository.set(
|
|
78
|
+
UpdateCache(latest_version=version, stored_at_timestamp=get_current_timestamp())
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
async def get_update_if_available(
|
|
83
|
+
update_notifier: UpdateGateway,
|
|
84
|
+
current_version: str,
|
|
85
|
+
update_cache_repository: UpdateCacheRepository,
|
|
86
|
+
get_current_timestamp: Callable[[], int] = lambda: int(time.time()),
|
|
87
|
+
) -> UpdateAvailability | None:
|
|
88
|
+
if not (current := _parse_version(current_version)):
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
if update_cache := await update_cache_repository.get():
|
|
92
|
+
if _is_cache_fresh(update_cache, get_current_timestamp):
|
|
93
|
+
return _get_cached_update_if_any(update_cache, current)
|
|
94
|
+
|
|
95
|
+
try:
|
|
96
|
+
update = await update_notifier.fetch_update()
|
|
97
|
+
except UpdateGatewayError as error:
|
|
98
|
+
await _write_update_cache(
|
|
99
|
+
update_cache_repository, current_version, get_current_timestamp
|
|
100
|
+
)
|
|
101
|
+
raise UpdateError(_describe_gateway_error(error)) from error
|
|
102
|
+
|
|
103
|
+
if not update:
|
|
104
|
+
await _write_update_cache(
|
|
105
|
+
update_cache_repository, current_version, get_current_timestamp
|
|
106
|
+
)
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
if not (latest_version := _parse_version(update.latest_version)):
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
if latest_version <= current:
|
|
113
|
+
await _write_update_cache(
|
|
114
|
+
update_cache_repository, current_version, get_current_timestamp
|
|
115
|
+
)
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
await _write_update_cache(
|
|
119
|
+
update_cache_repository, update.latest_version, get_current_timestamp
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
return UpdateAvailability(latest_version=update.latest_version, should_notify=True)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
UPDATE_COMMANDS = ["uv tool upgrade mistral-vibe", "brew upgrade mistral-vibe"]
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
async def do_update() -> bool:
|
|
129
|
+
for command in UPDATE_COMMANDS:
|
|
130
|
+
process = await asyncio.create_subprocess_shell(
|
|
131
|
+
command,
|
|
132
|
+
stdout=asyncio.subprocess.PIPE,
|
|
133
|
+
stderr=asyncio.subprocess.PIPE,
|
|
134
|
+
stdin=asyncio.subprocess.DEVNULL,
|
|
135
|
+
)
|
|
136
|
+
await process.wait()
|
|
137
|
+
if process.returncode == 0:
|
|
138
|
+
return True
|
|
139
|
+
return False
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
from vibe import VIBE_ROOT
|
|
6
|
+
from vibe.cli.update_notifier.ports.update_cache_repository import (
|
|
7
|
+
UpdateCache,
|
|
8
|
+
UpdateCacheRepository,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def should_show_whats_new(
|
|
13
|
+
current_version: str, repository: UpdateCacheRepository
|
|
14
|
+
) -> bool:
|
|
15
|
+
cache = await repository.get()
|
|
16
|
+
if cache is None:
|
|
17
|
+
return False
|
|
18
|
+
return cache.seen_whats_new_version != current_version
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def load_whats_new_content() -> str | None:
|
|
22
|
+
whats_new_file = VIBE_ROOT / "whats_new.md"
|
|
23
|
+
if not whats_new_file.exists():
|
|
24
|
+
return None
|
|
25
|
+
try:
|
|
26
|
+
content = whats_new_file.read_text(encoding="utf-8").strip()
|
|
27
|
+
return content if content else None
|
|
28
|
+
except OSError:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def mark_version_as_seen(version: str, repository: UpdateCacheRepository) -> None:
|
|
33
|
+
cache = await repository.get()
|
|
34
|
+
if cache is None:
|
|
35
|
+
await repository.set(
|
|
36
|
+
UpdateCache(
|
|
37
|
+
latest_version=version,
|
|
38
|
+
stored_at_timestamp=int(time.time()),
|
|
39
|
+
seen_whats_new_version=version,
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
else:
|
|
43
|
+
await repository.set(
|
|
44
|
+
UpdateCache(
|
|
45
|
+
latest_version=cache.latest_version,
|
|
46
|
+
stored_at_timestamp=cache.stored_at_timestamp,
|
|
47
|
+
seen_whats_new_version=version,
|
|
48
|
+
)
|
|
49
|
+
)
|