Skip to content

Commit 61d60e8

Browse files
committed
Restore tikalk customizations from upstream merge 59806bc
- Restore orange theme (ACCENT_COLOR=#f47721, BANNER_COLORS) lost during merge - Replace all 'cyan' with ACCENT_COLOR in UI panels (40+ replacements) - Add Pre-Installed Extensions panel after enhancements panel - Fix malformed [/] closing tags (2 instances) - Change speckit.* to spec.* in user-facing command references - Fix StepTracker render() to use ACCENT_COLOR for tree title and running symbol - Fix select_with_arrows() table column and border styles
1 parent 44795ad commit 61d60e8

1 file changed

Lines changed: 106 additions & 45 deletions

File tree

src/specify_cli/__init__.py

Lines changed: 106 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ def _maybe_refresh(self):
773773
pass
774774

775775
def render(self):
776-
tree = Tree(f"[cyan]{self.title}[/cyan]", guide_style="grey50")
776+
tree = Tree(Text(self.title, style=ACCENT_COLOR), guide_style="grey50")
777777
for step in self.steps:
778778
label = step["label"]
779779
detail_text = step["detail"].strip() if step["detail"] else ""
@@ -784,7 +784,7 @@ def render(self):
784784
elif status == "pending":
785785
symbol = "[green dim]○[/green dim]"
786786
elif status == "running":
787-
symbol = "[cyan]○[/cyan]"
787+
symbol = f"[{ACCENT_COLOR}]○[/{ACCENT_COLOR}]"
788788
elif status == "error":
789789
symbol = "[red]●[/red]"
790790
elif status == "skipped":
@@ -859,14 +859,20 @@ def select_with_arrows(
859859
def create_selection_panel():
860860
"""Create the selection panel with current selection highlighted."""
861861
table = Table.grid(padding=(0, 2))
862-
table.add_column(style="cyan", justify="left", width=3)
862+
table.add_column(style=ACCENT_COLOR, justify="left", width=3)
863863
table.add_column(style="white", justify="left")
864864

865865
for i, key in enumerate(option_keys):
866866
if i == selected_index:
867-
table.add_row("▶", f"[cyan]{key}[/cyan] [dim]({options[key]})[/dim]")
867+
table.add_row(
868+
"▶",
869+
f"[{ACCENT_COLOR}]{key}[/{ACCENT_COLOR}] [dim]({options[key]})[/dim]",
870+
)
868871
else:
869-
table.add_row(" ", f"[cyan]{key}[/cyan] [dim]({options[key]})[/dim]")
872+
table.add_row(
873+
" ",
874+
f"[{ACCENT_COLOR}]{key}[/{ACCENT_COLOR}] [dim]({options[key]})[/dim]",
875+
)
870876

871877
table.add_row("", "")
872878
table.add_row(
@@ -876,7 +882,7 @@ def create_selection_panel():
876882
return Panel(
877883
table,
878884
title=f"[bold]{prompt_text}[/bold]",
879-
border_style="cyan",
885+
border_style=ACCENT_COLOR,
880886
padding=(1, 2),
881887
)
882888

@@ -1796,7 +1802,9 @@ def init_git_repo(
17961802
try:
17971803
os.chdir(project_path)
17981804
if not quiet:
1799-
console.print("[cyan]Initializing git repository...[/cyan]")
1805+
console.print(
1806+
f"[{ACCENT_COLOR}]Initializing git repository...[/{ACCENT_COLOR}]"
1807+
)
18001808
subprocess.run(["git", "init"], check=True, capture_output=True, text=True)
18011809
subprocess.run(["git", "add", "."], check=True, capture_output=True, text=True)
18021810
subprocess.run(
@@ -1987,7 +1995,9 @@ def deep_merge_polite(
19871995
return None
19881996

19891997
if verbose:
1990-
console.print(f"[cyan]Merged JSON file:[/cyan] {existing_path.name}")
1998+
console.print(
1999+
f"[{ACCENT_COLOR}]Merged JSON file:[/{ACCENT_COLOR}] {existing_path.name}"
2000+
)
19912001

19922002
return merged
19932003

@@ -2009,7 +2019,9 @@ def download_template_from_github(
20092019
client = httpx.Client(verify=ssl_context)
20102020

20112021
if verbose:
2012-
console.print("[cyan]Fetching latest release information...[/cyan]")
2022+
console.print(
2023+
f"[{ACCENT_COLOR}]Fetching latest release information...[/{ACCENT_COLOR}]"
2024+
)
20132025
api_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/releases/latest"
20142026

20152027
try:
@@ -2066,13 +2078,15 @@ def download_template_from_github(
20662078
file_size = asset["size"]
20672079

20682080
if verbose:
2069-
console.print(f"[cyan]Found template:[/cyan] {filename}")
2070-
console.print(f"[cyan]Size:[/cyan] {file_size:,} bytes")
2071-
console.print(f"[cyan]Release:[/cyan] {release_data['tag_name']}")
2081+
console.print(f"[{ACCENT_COLOR}]Found template:[/{ACCENT_COLOR}] {filename}")
2082+
console.print(f"[{ACCENT_COLOR}]Size:[/{ACCENT_COLOR}] {file_size:,} bytes")
2083+
console.print(
2084+
f"[{ACCENT_COLOR}]Release:[/{ACCENT_COLOR}] {release_data['tag_name']}"
2085+
)
20722086

20732087
zip_path = download_dir / filename
20742088
if verbose:
2075-
console.print("[cyan]Downloading template...[/cyan]")
2089+
console.print(f"[{ACCENT_COLOR}]Downloading template...[/{ACCENT_COLOR}]")
20762090

20772091
try:
20782092
with client.stream(
@@ -2190,7 +2204,9 @@ def download_and_extract_template(
21902204
tracker.start("zip-list")
21912205
tracker.complete("zip-list", f"{len(zip_contents)} entries")
21922206
elif verbose:
2193-
console.print(f"[cyan]ZIP contains {len(zip_contents)} items[/cyan]")
2207+
console.print(
2208+
f"[{ACCENT_COLOR}]ZIP contains {len(zip_contents)} items[/{ACCENT_COLOR}]"
2209+
)
21942210

21952211
if is_current_dir:
21962212
with tempfile.TemporaryDirectory() as temp_dir:
@@ -2205,7 +2221,7 @@ def download_and_extract_template(
22052221
)
22062222
elif verbose:
22072223
console.print(
2208-
f"[cyan]Extracted {len(extracted_items)} items to temp location[/cyan]"
2224+
f"[{ACCENT_COLOR}]Extracted {len(extracted_items)} items to temp location[/{ACCENT_COLOR}]"
22092225
)
22102226

22112227
source_dir = temp_path
@@ -2216,7 +2232,7 @@ def download_and_extract_template(
22162232
tracker.complete("flatten")
22172233
elif verbose:
22182234
console.print(
2219-
"[cyan]Found nested directory structure[/cyan]"
2235+
f"[{ACCENT_COLOR}]Found nested directory structure[/{ACCENT_COLOR}]"
22202236
)
22212237

22222238
for item in source_dir.iterdir():
@@ -2258,7 +2274,7 @@ def download_and_extract_template(
22582274
shutil.copy2(item, dest_path)
22592275
if verbose and not tracker:
22602276
console.print(
2261-
"[cyan]Template files merged into current directory[/cyan]"
2277+
f"[{ACCENT_COLOR}]Template files merged into current directory[/{ACCENT_COLOR}]"
22622278
)
22632279
else:
22642280
zip_ref.extractall(project_path)
@@ -2271,7 +2287,7 @@ def download_and_extract_template(
22712287
)
22722288
elif verbose:
22732289
console.print(
2274-
f"[cyan]Extracted {len(extracted_items)} items to {project_path}:[/cyan]"
2290+
f"[{ACCENT_COLOR}]Extracted {len(extracted_items)} items to {project_path}:[/{ACCENT_COLOR}]"
22752291
)
22762292
for item in extracted_items:
22772293
console.print(
@@ -2292,7 +2308,7 @@ def download_and_extract_template(
22922308
tracker.complete("flatten")
22932309
elif verbose:
22942310
console.print(
2295-
"[cyan]Flattened nested directory structure[/cyan]"
2311+
f"[{ACCENT_COLOR}]Flattened nested directory structure[/{ACCENT_COLOR}]"
22962312
)
22972313

22982314
except Exception as e:
@@ -2373,7 +2389,7 @@ def ensure_executable_scripts(
23732389
else:
23742390
if updated:
23752391
console.print(
2376-
f"[cyan]Updated execute permissions on {updated} script(s) recursively[/cyan]"
2392+
f"[{ACCENT_COLOR}]Updated execute permissions on {updated} script(s) recursively[/{ACCENT_COLOR}]"
23772393
)
23782394
if failures:
23792395
console.print("[yellow]Some scripts could not be updated:[/yellow]")
@@ -2412,7 +2428,9 @@ def ensure_constitution_from_template(
24122428
tracker.add("constitution", "Constitution setup")
24132429
tracker.complete("constitution", "copied from template")
24142430
else:
2415-
console.print("[cyan]Initialized constitution from template[/cyan]")
2431+
console.print(
2432+
f"[{ACCENT_COLOR}]Initialized constitution from template[/{ACCENT_COLOR}]"
2433+
)
24162434
except Exception as e:
24172435
if tracker:
24182436
tracker.add("constitution", "Constitution setup")
@@ -3256,7 +3274,7 @@ def init(
32563274
)
32573275
if force:
32583276
console.print(
3259-
"[cyan]--force supplied: skipping confirmation and proceeding with merge[/cyan]"
3277+
f"[{ACCENT_COLOR}]--force supplied: skipping confirmation and proceeding with merge[/{ACCENT_COLOR}]"
32603278
)
32613279
else:
32623280
response = typer.confirm("Do you want to continue?")
@@ -3329,7 +3347,7 @@ def init(
33293347
current_dir = Path.cwd()
33303348

33313349
setup_lines = [
3332-
"[cyan]Specify Project Setup[/cyan]",
3350+
f"[{ACCENT_COLOR}]Specify Project Setup[/{ACCENT_COLOR}]",
33333351
"",
33343352
f"{'Project':<15} [green]{project_path.name}[/green]",
33353353
f"{'Working Path':<15} [dim]{current_dir}[/dim]",
@@ -3338,7 +3356,9 @@ def init(
33383356
if not here:
33393357
setup_lines.append(f"{'Target Path':<15} [dim]{project_path}[/dim]")
33403358

3341-
console.print(Panel("\n".join(setup_lines), border_style="cyan", padding=(1, 2)))
3359+
console.print(
3360+
Panel("\n".join(setup_lines), border_style=ACCENT_COLOR, padding=(1, 2))
3361+
)
33423362

33433363
should_init_git = False
33443364
if not no_git:
@@ -3354,10 +3374,10 @@ def init(
33543374
install_url = agent_config["install_url"]
33553375
if not check_tool(selected_ai):
33563376
error_panel = Panel(
3357-
f"[cyan]{selected_ai}[/cyan] not found\n"
3358-
f"Install from: [cyan]{install_url}[/cyan]\n"
3377+
f"[{ACCENT_COLOR}]{selected_ai}[/{ACCENT_COLOR}] not found\n"
3378+
f"Install from: [{ACCENT_COLOR}]{install_url}[/{ACCENT_COLOR}]\n"
33593379
f"{agent_config['name']} is required to continue with this project type.\n\n"
3360-
"Tip: Use [cyan]--ignore-agent-tools[/cyan] to skip this check",
3380+
f"Tip: Use [{ACCENT_COLOR}]--ignore-agent-tools[/{ACCENT_COLOR}] to skip this check",
33613381
title="[red]Agent Detection Error[/red]",
33623382
border_style="red",
33633383
padding=(1, 2),
@@ -3385,8 +3405,12 @@ def init(
33853405
else:
33863406
selected_script = default_script
33873407

3388-
console.print(f"[cyan]Selected AI assistant:[/cyan] {selected_ai}")
3389-
console.print(f"[cyan]Selected script type:[/cyan] {selected_script}")
3408+
console.print(
3409+
f"[{ACCENT_COLOR}]Selected AI assistant:[/{ACCENT_COLOR}] {selected_ai}"
3410+
)
3411+
console.print(
3412+
f"[{ACCENT_COLOR}]Selected script type:[/{ACCENT_COLOR}] {selected_script}"
3413+
)
33903414

33913415
tracker = StepTracker("Initialize Specify Project")
33923416

@@ -3638,10 +3662,10 @@ def init(
36383662
f"[yellow]Warning:[/yellow] Git repository initialization failed\n\n"
36393663
f"{git_error_message}\n\n"
36403664
f"[dim]You can initialize git manually later with:[/dim]\n"
3641-
f"[cyan]cd {project_path if not here else '.'}[/cyan]\n"
3642-
f"[cyan]git init[/cyan]\n"
3643-
f"[cyan]git add .[/cyan]\n"
3644-
f'[cyan]git commit -m "Initial commit"[/cyan]',
3665+
f"[{ACCENT_COLOR}]cd {project_path if not here else '.'}[/{ACCENT_COLOR}]\n"
3666+
f"[{ACCENT_COLOR}]git init[/{ACCENT_COLOR}]\n"
3667+
f"[{ACCENT_COLOR}]git add .[/{ACCENT_COLOR}]\n"
3668+
f'[{ACCENT_COLOR}]git commit -m "Initial commit"[/{ACCENT_COLOR}]',
36453669
title="[red]Git Initialization Failed[/red]",
36463670
border_style="red",
36473671
padding=(1, 2),
@@ -3685,44 +3709,79 @@ def init(
36853709
cmd = f"export CODEX_HOME={quoted_path}"
36863710

36873711
steps_lines.append(
3688-
f"{step_num}. Set [cyan]CODEX_HOME[/cyan] environment variable before running Codex: [cyan]{cmd}[/cyan]"
3712+
f"{step_num}. Set [{ACCENT_COLOR}]CODEX_HOME[/{ACCENT_COLOR}] environment variable before running Codex: [{ACCENT_COLOR}]{cmd}[/{ACCENT_COLOR}]"
36893713
)
36903714
step_num += 1
36913715

36923716
steps_lines.append(f"{step_num}. Start using slash commands with your AI agent:")
36933717

36943718
steps_lines.append(
3695-
" 2.1 [cyan]/speckit.constitution[/] - Establish project principles"
3719+
f" 2.1 [{ACCENT_COLOR}]/spec.constitution[/] - Establish project principles"
3720+
)
3721+
steps_lines.append(
3722+
f" 2.2 [{ACCENT_COLOR}]/spec.specify[/] - Create baseline specification"
3723+
)
3724+
steps_lines.append(
3725+
f" 2.3 [{ACCENT_COLOR}]/spec.plan[/] - Create implementation plan"
3726+
)
3727+
steps_lines.append(
3728+
f" 2.4 [{ACCENT_COLOR}]/spec.tasks[/] - Generate actionable tasks"
36963729
)
36973730
steps_lines.append(
3698-
" 2.2 [cyan]/speckit.specify[/] - Create baseline specification"
3731+
f" 2.5 [{ACCENT_COLOR}]/spec.implement[/] - Execute implementation"
36993732
)
3700-
steps_lines.append(" 2.3 [cyan]/speckit.plan[/] - Create implementation plan")
3701-
steps_lines.append(" 2.4 [cyan]/speckit.tasks[/] - Generate actionable tasks")
3702-
steps_lines.append(" 2.5 [cyan]/speckit.implement[/] - Execute implementation")
37033733

37043734
steps_panel = Panel(
3705-
"\n".join(steps_lines), title="Next Steps", border_style="cyan", padding=(1, 2)
3735+
"\n".join(steps_lines),
3736+
title="Next Steps",
3737+
border_style=ACCENT_COLOR,
3738+
padding=(1, 2),
37063739
)
37073740
console.print()
37083741
console.print(steps_panel)
37093742

37103743
enhancement_lines = [
37113744
"Optional commands that you can use for your specs [bright_black](improve quality & confidence)[/bright_black]",
37123745
"",
3713-
"○ [cyan]/speckit.clarify[/] [bright_black](optional)[/bright_black] - Ask structured questions to de-risk ambiguous areas before planning (run before [cyan]/speckit.plan[/] if used)",
3714-
"○ [cyan]/speckit.analyze[/] [bright_black](optional)[/bright_black] - Cross-artifact consistency & alignment report (after [cyan]/speckit.tasks[/], before [cyan]/speckit.implement[/])",
3715-
"○ [cyan]/speckit.checklist[/] [bright_black](optional)[/bright_black] - Generate quality checklists to validate requirements completeness, clarity, and consistency (after [cyan]/speckit.plan[/])",
3746+
f"○ [{ACCENT_COLOR}]/spec.clarify[/] [bright_black](optional)[/bright_black] - Ask structured questions to de-risk ambiguous areas before planning (run before [{ACCENT_COLOR}]/spec.plan[/] if used)",
3747+
f"○ [{ACCENT_COLOR}]/spec.analyze[/] [bright_black](optional)[/bright_black] - Cross-artifact consistency & alignment report (after [{ACCENT_COLOR}]/spec.tasks[/], before [{ACCENT_COLOR}]/spec.implement[/])",
3748+
f"○ [{ACCENT_COLOR}]/spec.checklist[/] [bright_black](optional)[/bright_black] - Generate quality checklists to validate requirements completeness, clarity, and consistency (after [{ACCENT_COLOR}]/spec.plan[/])",
37163749
]
37173750
enhancements_panel = Panel(
37183751
"\n".join(enhancement_lines),
37193752
title="Enhancement Commands",
3720-
border_style="cyan",
3753+
border_style=ACCENT_COLOR,
37213754
padding=(1, 2),
37223755
)
37233756
console.print()
37243757
console.print(enhancements_panel)
37253758

3759+
# Show pre-installed extensions with their commands
3760+
preinstalled = get_preinstalled_extensions(project_path)
3761+
if preinstalled:
3762+
ext_lines = []
3763+
for ext in preinstalled:
3764+
ext_lines.append(f"[{ACCENT_COLOR}]📦 {ext['name']}[/{ACCENT_COLOR}]")
3765+
ext_lines.append(f" {ext['description']}")
3766+
ext_lines.append("")
3767+
3768+
for cmd in ext.get("commands", []):
3769+
cmd_display = "/" + cmd.replace(".", ".")
3770+
ext_lines.append(f" [{ACCENT_COLOR}]{cmd_display}[/{ACCENT_COLOR}]")
3771+
3772+
ext_lines.append("")
3773+
3774+
if ext_lines:
3775+
ext_lines = ext_lines[:-1]
3776+
preinstalled_panel = Panel(
3777+
"\n".join(ext_lines),
3778+
title="Pre-Installed Extensions",
3779+
border_style=ACCENT_COLOR,
3780+
padding=(1, 2),
3781+
)
3782+
console.print()
3783+
console.print(preinstalled_panel)
3784+
37263785

37273786
@app.command()
37283787
def check():
@@ -4996,7 +5055,9 @@ def extension_add(
49965055
speckit_version = get_speckit_version()
49975056

49985057
try:
4999-
with console.status(f"[cyan]Installing extension: {extension}[/cyan]"):
5058+
with console.status(
5059+
f"[{ACCENT_COLOR}]Installing extension: {extension}[/{ACCENT_COLOR}]"
5060+
):
50005061
if dev:
50015062
# Install from local directory
50025063
source_path = Path(extension).expanduser().resolve()

0 commit comments

Comments
 (0)