feat(cli): clide instances / instance verbs for instance discovery (T-247)

Closes the observability half of T-247: a way to find and identify running
clides. `clide instances` scans the runtime socket dir, probes each live
*.sock, and prints its identity (version/pid/workspace/socketPath) as jsonl;
dead sockets are skipped. `clide instance` reports the one you're connected
to. Combined with CLIDE_SOCK honoring (this same ticket), you can now list
instances and pin the CLI to a chosen one.

Server: a new `instance` dispatcher command (registered in buildDispatcher
with the live workspace/pid/socket) returns the identity map; added to the
argv translator's umbrella set so a bare `instance` token routes to it.
Client: a POSIX dir-scan in clide.c (Windows stub until it ships).

Tests: e2e `instances` lists the live test server with its identity; a
cc-free unit test covers the `instance` command shape.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-27 15:51:13 +02:00
co-authored by Claude Opus 4.8
parent ceab497ba8
commit 679b5ba9d9
9 changed files with 144 additions and 3 deletions
+7 -1
View File
@@ -32,14 +32,16 @@ import 'package:clide/builtin/vim/vim.dart';
import 'package:clide/builtin/tickets/tickets.dart';
import 'package:clide/builtin/todos/todos.dart';
import 'package:clide/builtin/welcome/welcome.dart';
import 'dart:io' show Directory, File, Platform;
import 'dart:io' show Directory, File, Platform, pid;
import 'package:clide/kernel/kernel.dart';
import 'package:clide/clide.dart' show clideVersion;
import 'package:clide/src/daemon/dispatcher.dart';
import 'package:clide/src/daemon/editor_commands.dart';
import 'package:clide/src/daemon/files_commands.dart';
import 'package:clide/src/daemon/git_commands.dart';
import 'package:clide/src/daemon/image_commands.dart';
import 'package:clide/src/daemon/instance_command.dart';
import 'package:clide/src/daemon/log_commands.dart';
import 'package:clide/src/daemon/pane_commands.dart';
import 'package:clide/src/daemon/status_command.dart';
@@ -286,6 +288,10 @@ Future<void> main() async {
// visible to `pane list` by snapshotting the kernel PanelRegistry +
// LayoutArrangement at request time — no mirrored state to drift.
registerPaneCommands(dispatcher, paneRegistry, viewPanes: () => snapshotViewPanes(panels, arrangement));
// `clide instance` — this instance's identity (version/pid/workspace/socket)
// so `clide instances` can list every live instance and a human/agent can
// tell which one a socket belongs to (T-247).
registerInstanceCommand(dispatcher, version: clideVersion, pid: pid, workspace: workRoot.path, socketPath: workspaceSocketPath(workRoot.path));
// `clide log level [<level>]` — the live verbosity toggle's CLI half (T-433,
// D-6 parity with the output-dock Level chip). Persists via the kernel
// settings, captured post-boot.