Files
clide/app/lib/builtin/claude/src/extension.dart
T
jpmschweitzerandClaude b9fbcd43a2
test / unit + widget + golden + a11y (push) Failing after 45s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
implement builtin.claude per D-041
Tier-0 stub flipped to the real Claude pane. Primary-per-repo
semantics: session name is `clide-claude-<hash>` where <hash> is
FNV-1a over the workspace root path, so reopening clide attaches
to the same `claude` process through `tmux new-session -A`.

Primary has no close button — closing the tab disposes the widget
but deliberately does NOT call pane.close, so the tmux session
survives until the user actually exits claude or clide is shut
down. Secondary sessions (spawned via the claude.new-secondary
command registered here, UI wiring lands next) close normally and
the pane.close cascades into tmux kill-session.

Graceful fallback when tmux isn't on PATH: retries the spawn with
argv=['claude'], surfaces "no-tmux · fresh every launch" in the
header subtitle so the user knows persistence is off.

Session-naming unit tests cover determinism + uniqueness per repo.
Full app suite: 174 tests passing.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:40:30 +02:00

53 lines
1.8 KiB
Dart

import 'package:clide/clide.dart';
import 'package:clide_app/builtin/claude/src/claude_pane.dart';
import 'package:clide_app/extension/extension.dart';
import 'package:clide_app/kernel/kernel.dart';
/// Claude pane. Primary per repo (tmux-persisted per D-041); optional
/// secondaries spawned via the `claude.new-secondary` command.
class ClaudeExtension extends ClideExtension {
@override
String get id => 'builtin.claude';
@override
String get title => 'Claude';
@override
String get version => '0.1.0';
@override
List<String> get dependsOn => const [];
@override
List<ContributionPoint> get contributions => [
TabContribution(
id: 'claude.primary',
slot: Slots.workspace,
title: 'Claude',
titleKey: 'tab.title',
i18nNamespace: id,
priority: 90, // just before terminal (100)
build: (_) => const ClaudePane(isPrimary: true),
),
CommandContribution(
id: 'claude.new-secondary',
command: 'claude.new-secondary',
title: 'Claude: open a secondary session',
run: (_) async {
// Secondary spawn is a UI-side concern (tab creation in
// the workspace slot). Returning OK signals the palette
// that the command exists; wiring the workspace-slot tab
// manager to open `ClaudePane(isPrimary: false,
// secondaryIndex: N)` on this command lands in a follow-up.
// D-041 policy is captured in the decision record either
// way.
return IpcResponse.ok(
id: '',
data: const {
'status': 'accepted',
'note': 'UI-side tab manager wires this up in a '
'follow-up commit.',
},
);
},
),
];
}