bead 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.
- bead/__init__.py +11 -0
- bead/__main__.py +11 -0
- bead/active_learning/__init__.py +15 -0
- bead/active_learning/config.py +231 -0
- bead/active_learning/loop.py +566 -0
- bead/active_learning/models/__init__.py +24 -0
- bead/active_learning/models/base.py +852 -0
- bead/active_learning/models/binary.py +910 -0
- bead/active_learning/models/categorical.py +943 -0
- bead/active_learning/models/cloze.py +862 -0
- bead/active_learning/models/forced_choice.py +956 -0
- bead/active_learning/models/free_text.py +773 -0
- bead/active_learning/models/lora.py +365 -0
- bead/active_learning/models/magnitude.py +835 -0
- bead/active_learning/models/multi_select.py +795 -0
- bead/active_learning/models/ordinal_scale.py +811 -0
- bead/active_learning/models/peft_adapter.py +155 -0
- bead/active_learning/models/random_effects.py +639 -0
- bead/active_learning/selection.py +354 -0
- bead/active_learning/strategies.py +391 -0
- bead/active_learning/trainers/__init__.py +26 -0
- bead/active_learning/trainers/base.py +210 -0
- bead/active_learning/trainers/data_collator.py +172 -0
- bead/active_learning/trainers/dataset_utils.py +261 -0
- bead/active_learning/trainers/huggingface.py +304 -0
- bead/active_learning/trainers/lightning.py +324 -0
- bead/active_learning/trainers/metrics.py +424 -0
- bead/active_learning/trainers/mixed_effects.py +551 -0
- bead/active_learning/trainers/model_wrapper.py +509 -0
- bead/active_learning/trainers/registry.py +104 -0
- bead/adapters/__init__.py +11 -0
- bead/adapters/huggingface.py +61 -0
- bead/behavioral/__init__.py +116 -0
- bead/behavioral/analytics.py +646 -0
- bead/behavioral/extraction.py +343 -0
- bead/behavioral/merging.py +343 -0
- bead/cli/__init__.py +11 -0
- bead/cli/active_learning.py +513 -0
- bead/cli/active_learning_commands.py +779 -0
- bead/cli/completion.py +359 -0
- bead/cli/config.py +624 -0
- bead/cli/constraint_builders.py +286 -0
- bead/cli/deployment.py +859 -0
- bead/cli/deployment_trials.py +493 -0
- bead/cli/deployment_ui.py +332 -0
- bead/cli/display.py +378 -0
- bead/cli/items.py +960 -0
- bead/cli/items_factories.py +776 -0
- bead/cli/list_constraints.py +714 -0
- bead/cli/lists.py +490 -0
- bead/cli/main.py +430 -0
- bead/cli/models.py +877 -0
- bead/cli/resource_loaders.py +621 -0
- bead/cli/resources.py +1036 -0
- bead/cli/shell.py +356 -0
- bead/cli/simulate.py +840 -0
- bead/cli/templates.py +1158 -0
- bead/cli/training.py +1080 -0
- bead/cli/utils.py +614 -0
- bead/cli/workflow.py +1273 -0
- bead/config/__init__.py +68 -0
- bead/config/active_learning.py +1009 -0
- bead/config/config.py +192 -0
- bead/config/defaults.py +118 -0
- bead/config/deployment.py +217 -0
- bead/config/env.py +147 -0
- bead/config/item.py +45 -0
- bead/config/list.py +193 -0
- bead/config/loader.py +149 -0
- bead/config/logging.py +42 -0
- bead/config/model.py +49 -0
- bead/config/paths.py +46 -0
- bead/config/profiles.py +320 -0
- bead/config/resources.py +47 -0
- bead/config/serialization.py +210 -0
- bead/config/simulation.py +206 -0
- bead/config/template.py +238 -0
- bead/config/validation.py +267 -0
- bead/data/__init__.py +65 -0
- bead/data/base.py +87 -0
- bead/data/identifiers.py +97 -0
- bead/data/language_codes.py +61 -0
- bead/data/metadata.py +270 -0
- bead/data/range.py +123 -0
- bead/data/repository.py +358 -0
- bead/data/serialization.py +249 -0
- bead/data/timestamps.py +89 -0
- bead/data/validation.py +349 -0
- bead/data_collection/__init__.py +11 -0
- bead/data_collection/jatos.py +223 -0
- bead/data_collection/merger.py +154 -0
- bead/data_collection/prolific.py +198 -0
- bead/deployment/__init__.py +5 -0
- bead/deployment/distribution.py +402 -0
- bead/deployment/jatos/__init__.py +1 -0
- bead/deployment/jatos/api.py +200 -0
- bead/deployment/jatos/exporter.py +210 -0
- bead/deployment/jspsych/__init__.py +9 -0
- bead/deployment/jspsych/biome.json +44 -0
- bead/deployment/jspsych/config.py +411 -0
- bead/deployment/jspsych/generator.py +598 -0
- bead/deployment/jspsych/package.json +51 -0
- bead/deployment/jspsych/pnpm-lock.yaml +2141 -0
- bead/deployment/jspsych/randomizer.py +299 -0
- bead/deployment/jspsych/src/lib/list-distributor.test.ts +327 -0
- bead/deployment/jspsych/src/lib/list-distributor.ts +1282 -0
- bead/deployment/jspsych/src/lib/randomizer.test.ts +232 -0
- bead/deployment/jspsych/src/lib/randomizer.ts +367 -0
- bead/deployment/jspsych/src/plugins/cloze-dropdown.ts +252 -0
- bead/deployment/jspsych/src/plugins/forced-choice.ts +265 -0
- bead/deployment/jspsych/src/plugins/plugins.test.ts +141 -0
- bead/deployment/jspsych/src/plugins/rating.ts +248 -0
- bead/deployment/jspsych/src/slopit/index.ts +9 -0
- bead/deployment/jspsych/src/types/jatos.d.ts +256 -0
- bead/deployment/jspsych/src/types/jspsych.d.ts +228 -0
- bead/deployment/jspsych/templates/experiment.css +1 -0
- bead/deployment/jspsych/templates/experiment.js.template +289 -0
- bead/deployment/jspsych/templates/index.html +51 -0
- bead/deployment/jspsych/templates/randomizer.js +241 -0
- bead/deployment/jspsych/templates/randomizer.js.template +313 -0
- bead/deployment/jspsych/trials.py +723 -0
- bead/deployment/jspsych/tsconfig.json +23 -0
- bead/deployment/jspsych/tsup.config.ts +30 -0
- bead/deployment/jspsych/ui/__init__.py +1 -0
- bead/deployment/jspsych/ui/components.py +383 -0
- bead/deployment/jspsych/ui/styles.py +411 -0
- bead/dsl/__init__.py +80 -0
- bead/dsl/ast.py +168 -0
- bead/dsl/context.py +178 -0
- bead/dsl/errors.py +71 -0
- bead/dsl/evaluator.py +570 -0
- bead/dsl/grammar.lark +81 -0
- bead/dsl/parser.py +231 -0
- bead/dsl/stdlib.py +929 -0
- bead/evaluation/__init__.py +13 -0
- bead/evaluation/convergence.py +485 -0
- bead/evaluation/interannotator.py +398 -0
- bead/items/__init__.py +40 -0
- bead/items/adapters/__init__.py +70 -0
- bead/items/adapters/anthropic.py +224 -0
- bead/items/adapters/api_utils.py +167 -0
- bead/items/adapters/base.py +216 -0
- bead/items/adapters/google.py +259 -0
- bead/items/adapters/huggingface.py +1074 -0
- bead/items/adapters/openai.py +323 -0
- bead/items/adapters/registry.py +202 -0
- bead/items/adapters/sentence_transformers.py +224 -0
- bead/items/adapters/togetherai.py +309 -0
- bead/items/binary.py +515 -0
- bead/items/cache.py +558 -0
- bead/items/categorical.py +593 -0
- bead/items/cloze.py +757 -0
- bead/items/constructor.py +784 -0
- bead/items/forced_choice.py +413 -0
- bead/items/free_text.py +681 -0
- bead/items/generation.py +432 -0
- bead/items/item.py +396 -0
- bead/items/item_template.py +787 -0
- bead/items/magnitude.py +573 -0
- bead/items/multi_select.py +621 -0
- bead/items/ordinal_scale.py +569 -0
- bead/items/scoring.py +448 -0
- bead/items/validation.py +723 -0
- bead/lists/__init__.py +30 -0
- bead/lists/balancer.py +263 -0
- bead/lists/constraints.py +1067 -0
- bead/lists/experiment_list.py +286 -0
- bead/lists/list_collection.py +378 -0
- bead/lists/partitioner.py +1141 -0
- bead/lists/stratification.py +254 -0
- bead/participants/__init__.py +73 -0
- bead/participants/collection.py +699 -0
- bead/participants/merging.py +312 -0
- bead/participants/metadata_spec.py +491 -0
- bead/participants/models.py +276 -0
- bead/resources/__init__.py +29 -0
- bead/resources/adapters/__init__.py +19 -0
- bead/resources/adapters/base.py +104 -0
- bead/resources/adapters/cache.py +128 -0
- bead/resources/adapters/glazing.py +508 -0
- bead/resources/adapters/registry.py +117 -0
- bead/resources/adapters/unimorph.py +796 -0
- bead/resources/classification.py +856 -0
- bead/resources/constraint_builders.py +329 -0
- bead/resources/constraints.py +165 -0
- bead/resources/lexical_item.py +223 -0
- bead/resources/lexicon.py +744 -0
- bead/resources/loaders.py +209 -0
- bead/resources/template.py +441 -0
- bead/resources/template_collection.py +707 -0
- bead/resources/template_generation.py +349 -0
- bead/simulation/__init__.py +29 -0
- bead/simulation/annotators/__init__.py +15 -0
- bead/simulation/annotators/base.py +175 -0
- bead/simulation/annotators/distance_based.py +135 -0
- bead/simulation/annotators/lm_based.py +114 -0
- bead/simulation/annotators/oracle.py +182 -0
- bead/simulation/annotators/random.py +181 -0
- bead/simulation/dsl_extension/__init__.py +3 -0
- bead/simulation/noise_models/__init__.py +13 -0
- bead/simulation/noise_models/base.py +42 -0
- bead/simulation/noise_models/random_noise.py +82 -0
- bead/simulation/noise_models/systematic.py +132 -0
- bead/simulation/noise_models/temperature.py +86 -0
- bead/simulation/runner.py +144 -0
- bead/simulation/strategies/__init__.py +23 -0
- bead/simulation/strategies/base.py +123 -0
- bead/simulation/strategies/binary.py +103 -0
- bead/simulation/strategies/categorical.py +123 -0
- bead/simulation/strategies/cloze.py +224 -0
- bead/simulation/strategies/forced_choice.py +127 -0
- bead/simulation/strategies/free_text.py +105 -0
- bead/simulation/strategies/magnitude.py +116 -0
- bead/simulation/strategies/multi_select.py +129 -0
- bead/simulation/strategies/ordinal_scale.py +131 -0
- bead/templates/__init__.py +27 -0
- bead/templates/adapters/__init__.py +17 -0
- bead/templates/adapters/base.py +128 -0
- bead/templates/adapters/cache.py +178 -0
- bead/templates/adapters/huggingface.py +312 -0
- bead/templates/combinatorics.py +103 -0
- bead/templates/filler.py +605 -0
- bead/templates/renderers.py +177 -0
- bead/templates/resolver.py +178 -0
- bead/templates/strategies.py +1806 -0
- bead/templates/streaming.py +195 -0
- bead-0.1.0.dist-info/METADATA +212 -0
- bead-0.1.0.dist-info/RECORD +231 -0
- bead-0.1.0.dist-info/WHEEL +4 -0
- bead-0.1.0.dist-info/entry_points.txt +2 -0
- bead-0.1.0.dist-info/licenses/LICENSE +21 -0
bead/cli/shell.py
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"""Interactive CLI shell using Click and Prompt Toolkit.
|
|
2
|
+
|
|
3
|
+
This module provides an interactive REPL shell for the bead CLI with
|
|
4
|
+
autocomplete, command history, and rich formatting. Commands are executed
|
|
5
|
+
through Click's CLI system, providing full integration with all bead commands.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import shlex
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
import click
|
|
15
|
+
from prompt_toolkit import PromptSession
|
|
16
|
+
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|
17
|
+
from prompt_toolkit.completion import Completer, Completion
|
|
18
|
+
from prompt_toolkit.history import FileHistory
|
|
19
|
+
from prompt_toolkit.lexers import PygmentsLexer
|
|
20
|
+
from prompt_toolkit.styles import Style
|
|
21
|
+
from pygments.lexers.shell import BashLexer
|
|
22
|
+
from rich.console import Console
|
|
23
|
+
from rich.markdown import Markdown
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from collections.abc import Iterable
|
|
27
|
+
|
|
28
|
+
console = Console()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Create shell command group
|
|
32
|
+
@click.group()
|
|
33
|
+
def shell() -> None:
|
|
34
|
+
r"""Interactive shell for bead CLI.
|
|
35
|
+
|
|
36
|
+
Provides an interactive REPL with autocomplete, history, and rich formatting.
|
|
37
|
+
"""
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class BeadCompleter(Completer):
|
|
42
|
+
"""Command completer for bead shell."""
|
|
43
|
+
|
|
44
|
+
def __init__(self, commands: list[str]) -> None:
|
|
45
|
+
"""Initialize completer with available commands.
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
commands : list[str]
|
|
50
|
+
List of available commands.
|
|
51
|
+
"""
|
|
52
|
+
self.commands = commands
|
|
53
|
+
# Initialize subcommands dict - will be populated lazily
|
|
54
|
+
self.subcommands: dict[str, list[str]] = {}
|
|
55
|
+
self._subcommands_loaded = False
|
|
56
|
+
|
|
57
|
+
def get_completions(
|
|
58
|
+
self, document: object, complete_event: object
|
|
59
|
+
) -> Iterable[Completion]:
|
|
60
|
+
"""Get completions for current input.
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
document : object
|
|
65
|
+
Current document/input.
|
|
66
|
+
complete_event : object
|
|
67
|
+
Completion event.
|
|
68
|
+
|
|
69
|
+
Yields
|
|
70
|
+
------
|
|
71
|
+
Completion
|
|
72
|
+
Completion suggestions.
|
|
73
|
+
"""
|
|
74
|
+
# Access text_before_cursor attribute safely
|
|
75
|
+
text = getattr(document, "text_before_cursor", "")
|
|
76
|
+
words = text.split()
|
|
77
|
+
|
|
78
|
+
# Lazy load subcommands to avoid circular import
|
|
79
|
+
if not self._subcommands_loaded:
|
|
80
|
+
try:
|
|
81
|
+
from bead.cli.main import cli # noqa: PLC0415
|
|
82
|
+
|
|
83
|
+
for cmd_name, cmd_obj in cli.commands.items():
|
|
84
|
+
if hasattr(cmd_obj, "commands"):
|
|
85
|
+
# It's a group, get its subcommands
|
|
86
|
+
self.subcommands[cmd_name] = list(cmd_obj.commands.keys())
|
|
87
|
+
self._subcommands_loaded = True
|
|
88
|
+
except Exception:
|
|
89
|
+
# Fallback to hardcoded list if import fails
|
|
90
|
+
self.subcommands = {
|
|
91
|
+
"resources": ["create", "list", "validate", "import"],
|
|
92
|
+
"templates": ["fill", "list", "validate"],
|
|
93
|
+
"items": ["create", "list", "validate", "stats"],
|
|
94
|
+
"lists": ["partition", "list", "validate"],
|
|
95
|
+
"deployment": ["generate", "validate", "export"],
|
|
96
|
+
"training": ["train", "evaluate", "predict"],
|
|
97
|
+
"active-learning": ["select-items", "run", "monitor-convergence"],
|
|
98
|
+
"config": ["show", "validate", "edit"],
|
|
99
|
+
"workflow": ["run", "status", "resume", "rollback"],
|
|
100
|
+
}
|
|
101
|
+
self._subcommands_loaded = True
|
|
102
|
+
|
|
103
|
+
if len(words) == 0:
|
|
104
|
+
# Complete main commands
|
|
105
|
+
for cmd in self.commands:
|
|
106
|
+
if cmd.startswith(text):
|
|
107
|
+
yield Completion(cmd, start_position=-len(text))
|
|
108
|
+
elif len(words) == 1:
|
|
109
|
+
# Complete subcommands
|
|
110
|
+
cmd = words[0]
|
|
111
|
+
if cmd in self.subcommands:
|
|
112
|
+
for subcmd in self.subcommands[cmd]:
|
|
113
|
+
yield Completion(subcmd, start_position=0)
|
|
114
|
+
else:
|
|
115
|
+
# File path completion
|
|
116
|
+
last_word = words[-1]
|
|
117
|
+
if "/" in last_word or last_word.startswith("."):
|
|
118
|
+
try:
|
|
119
|
+
path = Path(last_word).parent if "/" in last_word else Path(".")
|
|
120
|
+
prefix = Path(last_word).name
|
|
121
|
+
if path.exists():
|
|
122
|
+
for item in path.iterdir():
|
|
123
|
+
if item.name.startswith(prefix):
|
|
124
|
+
suffix = "/" if item.is_dir() else ""
|
|
125
|
+
yield Completion(
|
|
126
|
+
str(item.name) + suffix,
|
|
127
|
+
start_position=-len(prefix),
|
|
128
|
+
)
|
|
129
|
+
except Exception:
|
|
130
|
+
pass
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# Shell style
|
|
134
|
+
shell_style = Style.from_dict(
|
|
135
|
+
{
|
|
136
|
+
"prompt": "bold cyan",
|
|
137
|
+
"command": "bold green",
|
|
138
|
+
"error": "bold red",
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
_DEFAULT_HISTORY_FILE = Path.home() / ".bead_history"
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@shell.command()
|
|
147
|
+
@click.option(
|
|
148
|
+
"--history",
|
|
149
|
+
type=click.Path(path_type=Path),
|
|
150
|
+
default=_DEFAULT_HISTORY_FILE,
|
|
151
|
+
help="Path to history file",
|
|
152
|
+
)
|
|
153
|
+
def repl(history_file: Path) -> None:
|
|
154
|
+
"""Start interactive REPL shell.
|
|
155
|
+
|
|
156
|
+
Provides an interactive command-line interface with:
|
|
157
|
+
- Command autocomplete
|
|
158
|
+
- Command history
|
|
159
|
+
- Rich formatting
|
|
160
|
+
- Multi-line input support
|
|
161
|
+
|
|
162
|
+
Parameters
|
|
163
|
+
----------
|
|
164
|
+
history_file : Path
|
|
165
|
+
Path to history file for command persistence.
|
|
166
|
+
|
|
167
|
+
Examples
|
|
168
|
+
--------
|
|
169
|
+
Start shell:
|
|
170
|
+
$ bead shell
|
|
171
|
+
|
|
172
|
+
Start shell with custom history:
|
|
173
|
+
$ bead shell --history ~/.my_bead_history
|
|
174
|
+
"""
|
|
175
|
+
console.print("[bold cyan]bead Interactive Shell[/bold cyan]")
|
|
176
|
+
console.print("[dim]Type 'help' for available commands, 'exit' to quit[/dim]\n")
|
|
177
|
+
|
|
178
|
+
# Available commands - lazy import to avoid circular dependency
|
|
179
|
+
commands: list[str]
|
|
180
|
+
try:
|
|
181
|
+
# Import here to avoid circular import at module level
|
|
182
|
+
from bead.cli.main import cli as main_cli # noqa: PLC0415
|
|
183
|
+
|
|
184
|
+
commands = list(main_cli.commands.keys()) + ["help", "exit", "quit", "clear"]
|
|
185
|
+
except Exception:
|
|
186
|
+
# Fallback to hardcoded list if import fails
|
|
187
|
+
commands = [
|
|
188
|
+
"resources",
|
|
189
|
+
"templates",
|
|
190
|
+
"items",
|
|
191
|
+
"lists",
|
|
192
|
+
"deployment",
|
|
193
|
+
"training",
|
|
194
|
+
"active-learning",
|
|
195
|
+
"config",
|
|
196
|
+
"workflow",
|
|
197
|
+
"help",
|
|
198
|
+
"exit",
|
|
199
|
+
"quit",
|
|
200
|
+
]
|
|
201
|
+
|
|
202
|
+
# Create completer
|
|
203
|
+
completer = BeadCompleter(commands)
|
|
204
|
+
|
|
205
|
+
# Create history
|
|
206
|
+
history = FileHistory(str(history_file)) if history_file else None
|
|
207
|
+
|
|
208
|
+
# Create session
|
|
209
|
+
session = PromptSession(
|
|
210
|
+
history=history,
|
|
211
|
+
completer=completer,
|
|
212
|
+
auto_suggest=AutoSuggestFromHistory(),
|
|
213
|
+
lexer=PygmentsLexer(BashLexer),
|
|
214
|
+
style=shell_style,
|
|
215
|
+
complete_while_typing=True,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Main loop
|
|
219
|
+
while True:
|
|
220
|
+
try:
|
|
221
|
+
# Get user input
|
|
222
|
+
text = session.prompt("bead> ")
|
|
223
|
+
|
|
224
|
+
if not text.strip():
|
|
225
|
+
continue
|
|
226
|
+
|
|
227
|
+
# Handle built-in commands
|
|
228
|
+
if text.strip() in ("exit", "quit"):
|
|
229
|
+
console.print("[green]Goodbye![/green]")
|
|
230
|
+
break
|
|
231
|
+
elif text.strip() == "help":
|
|
232
|
+
_show_help()
|
|
233
|
+
continue
|
|
234
|
+
elif text.strip().startswith("clear"):
|
|
235
|
+
console.clear()
|
|
236
|
+
continue
|
|
237
|
+
|
|
238
|
+
# Execute command
|
|
239
|
+
_execute_command(text)
|
|
240
|
+
|
|
241
|
+
except KeyboardInterrupt:
|
|
242
|
+
console.print("\n[yellow]Interrupted. Type 'exit' to quit.[/yellow]")
|
|
243
|
+
except EOFError:
|
|
244
|
+
console.print("\n[green]Goodbye![/green]")
|
|
245
|
+
break
|
|
246
|
+
except Exception as e:
|
|
247
|
+
console.print(f"[red]Error: {e}[/red]")
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _show_help() -> None:
|
|
251
|
+
"""Show help message."""
|
|
252
|
+
help_text = """
|
|
253
|
+
# bead Interactive Shell
|
|
254
|
+
|
|
255
|
+
## Available Commands
|
|
256
|
+
|
|
257
|
+
- **resources** - Manage lexicons and templates
|
|
258
|
+
- **templates** - Fill and manage templates
|
|
259
|
+
- **items** - Create and manage experimental items
|
|
260
|
+
- **lists** - Partition items into experiment lists
|
|
261
|
+
- **deployment** - Generate and deploy experiments
|
|
262
|
+
- **training** - Train models with active learning
|
|
263
|
+
- **active-learning** - Active learning commands
|
|
264
|
+
- **config** - Configuration management
|
|
265
|
+
- **workflow** - End-to-end pipeline workflows
|
|
266
|
+
|
|
267
|
+
## Built-in Commands
|
|
268
|
+
|
|
269
|
+
- **help** - Show this help message
|
|
270
|
+
- **exit** / **quit** - Exit the shell
|
|
271
|
+
- **clear** - Clear the screen
|
|
272
|
+
|
|
273
|
+
## Usage
|
|
274
|
+
|
|
275
|
+
Type commands as you would in the regular CLI, but without the 'bead' prefix:
|
|
276
|
+
|
|
277
|
+
bead> resources list
|
|
278
|
+
bead> templates fill --strategy exhaustive
|
|
279
|
+
bead> items create --template template.jsonl
|
|
280
|
+
|
|
281
|
+
## Features
|
|
282
|
+
|
|
283
|
+
- **Autocomplete**: Press TAB to autocomplete commands
|
|
284
|
+
- **History**: Use arrow keys to navigate command history
|
|
285
|
+
- **Multi-line**: Use backslash for line continuation
|
|
286
|
+
"""
|
|
287
|
+
console.print(Markdown(help_text))
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def _execute_command(text: str) -> None:
|
|
291
|
+
"""Execute a command using Click's CLI system.
|
|
292
|
+
|
|
293
|
+
Parameters
|
|
294
|
+
----------
|
|
295
|
+
text : str
|
|
296
|
+
Command text to execute.
|
|
297
|
+
"""
|
|
298
|
+
if not text.strip():
|
|
299
|
+
return
|
|
300
|
+
|
|
301
|
+
# Parse command using shlex to handle quoted arguments properly
|
|
302
|
+
try:
|
|
303
|
+
parts = shlex.split(text)
|
|
304
|
+
except ValueError as e:
|
|
305
|
+
console.print(f"[red]Error parsing command: {e}[/red]")
|
|
306
|
+
return
|
|
307
|
+
|
|
308
|
+
if not parts:
|
|
309
|
+
return
|
|
310
|
+
|
|
311
|
+
# Import main CLI group
|
|
312
|
+
from bead.cli.main import cli # noqa: PLC0415
|
|
313
|
+
|
|
314
|
+
# Create a context with default options
|
|
315
|
+
ctx_obj: dict[str, object] = {
|
|
316
|
+
"config_file": None,
|
|
317
|
+
"profile": "default",
|
|
318
|
+
"verbose": False,
|
|
319
|
+
"quiet": False,
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
# Build command line arguments
|
|
323
|
+
# Click expects sys.argv format, so we need to prepend the program name
|
|
324
|
+
# and handle the command parts
|
|
325
|
+
try:
|
|
326
|
+
# Create a context for the main CLI group
|
|
327
|
+
with cli.make_context("bead", list(parts), obj=ctx_obj) as ctx:
|
|
328
|
+
# Invoke the command
|
|
329
|
+
cli.invoke(ctx)
|
|
330
|
+
except click.exceptions.Exit as e:
|
|
331
|
+
# Click commands use ctx.exit() which raises Exit
|
|
332
|
+
# Exit code 0 is success, non-zero is error
|
|
333
|
+
if e.exit_code != 0:
|
|
334
|
+
console.print(f"[red]Command failed with exit code {e.exit_code}[/red]")
|
|
335
|
+
except click.exceptions.ClickException as e:
|
|
336
|
+
# Click-specific exceptions (e.g., BadParameter, UsageError)
|
|
337
|
+
console.print(f"[red]{e.format_message()}[/red]")
|
|
338
|
+
except SystemExit as e:
|
|
339
|
+
# Some commands may call sys.exit()
|
|
340
|
+
if e.code and e.code != 0:
|
|
341
|
+
console.print(f"[red]Command exited with code {e.code}[/red]")
|
|
342
|
+
except Exception as e:
|
|
343
|
+
# Catch-all for other exceptions
|
|
344
|
+
console.print(f"[red]Error executing command: {e}[/red]")
|
|
345
|
+
if ctx_obj.get("verbose", False):
|
|
346
|
+
import traceback # noqa: PLC0415
|
|
347
|
+
|
|
348
|
+
console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
# Register repl command
|
|
352
|
+
shell.add_command(repl)
|
|
353
|
+
|
|
354
|
+
# Entry point for direct execution
|
|
355
|
+
if __name__ == "__main__":
|
|
356
|
+
shell()
|