cuekit 0.0.12

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.
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "cuekit",
3
+ "version": "0.0.12",
4
+ "description": "cuekit — delegation substrate for coding agents",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./src/index.ts"
8
+ },
9
+ "bin": {
10
+ "cuekit": "./bin/cuekit.js"
11
+ },
12
+ "files": [
13
+ "bin/",
14
+ "src/",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "typecheck": "tsc --noEmit",
19
+ "test": "bun test"
20
+ },
21
+ "dependencies": {},
22
+ "engines": {
23
+ "bun": ">=1.2.0"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "keywords": [
29
+ "ai",
30
+ "agent",
31
+ "cli",
32
+ "mcp",
33
+ "coding-agent",
34
+ "orchestration"
35
+ ],
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/takemo101/cuekit.git"
40
+ },
41
+ "homepage": "https://github.com/takemo101/cuekit#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/takemo101/cuekit/issues"
44
+ },
45
+ "optionalDependencies": {
46
+ "@opentui/core-darwin-arm64": "0.2.1",
47
+ "@opentui/core-darwin-x64": "0.2.1",
48
+ "@opentui/core-linux-arm64": "0.2.1",
49
+ "@opentui/core-linux-x64": "0.2.1",
50
+ "@opentui/core-win32-arm64": "0.2.1",
51
+ "@opentui/core-win32-x64": "0.2.1"
52
+ }
53
+ }
package/src/bin.ts ADDED
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env bun
2
+ import type { Database } from "bun:sqlite";
3
+ import { existsSync, statSync } from "node:fs";
4
+ import {
5
+ type AdapterRegistry,
6
+ buildAdapterRegistry,
7
+ buildMultiplexerBackend,
8
+ type MultiplexerBackend,
9
+ } from "@cuekit/adapters";
10
+ import { findProjectRoot } from "@cuekit/agent-profiles";
11
+ import { createStderrLogger, parseLogLevel, silentLogger } from "@cuekit/core";
12
+ import { createTuiContext, runCuekitMcpBin } from "@cuekit/mcp";
13
+ import { loadProjectConfig } from "@cuekit/project-config";
14
+ import { openDatabase, runMigrations } from "@cuekit/store";
15
+ import {
16
+ classifyCuekitCommand,
17
+ printDoctorHelp,
18
+ printMainHelp,
19
+ printUpdateHelp,
20
+ } from "./dispatch.ts";
21
+ import { runDoctor } from "./doctor.ts";
22
+ import {
23
+ printTuiHelp,
24
+ runInitCommand,
25
+ runJcodeMcpAddCommand,
26
+ runPiMcpAddCommand,
27
+ } from "./human-commands.ts";
28
+ import { runUpdate } from "./update.ts";
29
+
30
+ function closeQuietly(db: Database): void {
31
+ try {
32
+ db.close();
33
+ } catch {
34
+ // ignore close errors on shutdown
35
+ }
36
+ }
37
+
38
+ // Re-export the canonical adapter-registry factory under a TUI-specific
39
+ // name to preserve the existing call sites and regression-test imports.
40
+ // The actual build-out lives in `@cuekit/adapters/build-registry` so it
41
+ // can be shared between `cuekit --mcp` (the MCP server) and
42
+ // `cuekit tui` (this binary). See #382 for the unification rationale.
43
+ export const buildTuiAdapterRegistry: (
44
+ db: Database,
45
+ panes: MultiplexerBackend,
46
+ options?: { logger?: import("@cuekit/core").Logger },
47
+ ) => AdapterRegistry = buildAdapterRegistry;
48
+
49
+ async function runTuiCommand(): Promise<void> {
50
+ const logLevel = parseLogLevel(process.env.CUEKIT_LOG_LEVEL);
51
+ const logger = createStderrLogger({ minLevel: logLevel });
52
+ const tuiLogger = silentLogger;
53
+ let db: Database | undefined;
54
+ try {
55
+ const dbPath = process.env.CUEKIT_DB_PATH;
56
+ const useCustomPath = dbPath !== undefined && dbPath.length > 0;
57
+ db = openDatabase(useCustomPath ? { path: dbPath } : {});
58
+ runMigrations(db);
59
+
60
+ const { runTuiLoop } = await import("@cuekit/tui");
61
+ const all = process.argv.includes("--all");
62
+ const pathScope = process.argv.includes("--path");
63
+ const projectRoot = findProjectRoot(process.cwd(), { existsSync, statSync });
64
+ const loadedConfig = all || pathScope ? undefined : loadProjectConfig(process.cwd());
65
+ if (loadedConfig && !loadedConfig.ok) {
66
+ throw new Error(loadedConfig.error);
67
+ }
68
+ const built = await buildMultiplexerBackend(
69
+ loadedConfig?.ok ? loadedConfig.config : undefined,
70
+ { logger: tuiLogger },
71
+ );
72
+ const panes = built.backend;
73
+ const registry = buildTuiAdapterRegistry(db, panes, { logger: tuiLogger });
74
+ await runTuiLoop(
75
+ createTuiContext(
76
+ { db, registry, panes },
77
+ {
78
+ all,
79
+ ...(loadedConfig?.ok && loadedConfig.discovery.source === "config"
80
+ ? loadedConfig.config.tui?.scope === "path"
81
+ ? { projectRoot }
82
+ : {
83
+ projectScope: {
84
+ project_uid: loadedConfig.identity.project_uid,
85
+ project_root: loadedConfig.discovery.configRoot,
86
+ },
87
+ }
88
+ : { projectRoot }),
89
+ },
90
+ ) as never,
91
+ );
92
+ closeQuietly(db);
93
+ } catch (err) {
94
+ if (db) closeQuietly(db);
95
+ logger.error("tui startup failed", {
96
+ reason: err instanceof Error ? err.message : String(err),
97
+ });
98
+ process.exit(1);
99
+ }
100
+ }
101
+
102
+ export async function runCuekitCliBin(): Promise<void> {
103
+ const argv = process.argv.slice(2);
104
+ const classification = classifyCuekitCommand(argv);
105
+ if (classification.kind === "help") {
106
+ process.stdout.write(printMainHelp());
107
+ return;
108
+ }
109
+ if (classification.kind === "init") {
110
+ const result = runInitCommand(argv.slice(1));
111
+ process.stdout.write(result.stdout);
112
+ if (result.stderr) process.stderr.write(result.stderr);
113
+ if (result.exitCode !== 0) process.exit(result.exitCode);
114
+ return;
115
+ }
116
+ if (classification.kind === "tui" && (argv.includes("--help") || argv.includes("-h"))) {
117
+ process.stdout.write(printTuiHelp());
118
+ return;
119
+ }
120
+ if (classification.kind === "tui") {
121
+ await runTuiCommand();
122
+ return;
123
+ }
124
+ if (classification.kind === "mcp-add") {
125
+ const jcodeResult = runJcodeMcpAddCommand(argv.slice(2));
126
+ const result = jcodeResult.shouldDelegate ? runPiMcpAddCommand(argv.slice(2)) : jcodeResult;
127
+ process.stdout.write(result.stdout);
128
+ if (result.stderr) process.stderr.write(result.stderr);
129
+ if (result.exitCode !== 0) process.exit(result.exitCode);
130
+ if (!result.shouldDelegate) return;
131
+ process.argv = [process.argv[0] ?? "bun", process.argv[1] ?? "cuekit", ...result.delegateArgv];
132
+ }
133
+ if (classification.kind === "doctor") {
134
+ if (argv.includes("--help") || argv.includes("-h")) {
135
+ process.stdout.write(printDoctorHelp());
136
+ return;
137
+ }
138
+ const result = await runDoctor({ fix: argv.includes("--fix") });
139
+ process.stdout.write(result.stdout);
140
+ if (result.stderr) process.stderr.write(result.stderr);
141
+ process.exit(result.exitCode);
142
+ }
143
+ if (classification.kind === "update") {
144
+ if (argv.includes("--help") || argv.includes("-h")) {
145
+ process.stdout.write(printUpdateHelp());
146
+ return;
147
+ }
148
+ const result = await runUpdate();
149
+ process.stdout.write(result.stdout);
150
+ if (result.stderr) process.stderr.write(result.stderr);
151
+ process.exit(result.exitCode);
152
+ }
153
+ await runCuekitMcpBin();
154
+ }
155
+
156
+ if (import.meta.main) {
157
+ await runCuekitCliBin();
158
+ }
@@ -0,0 +1,93 @@
1
+ export type CuekitCommandClassification =
2
+ | { kind: "help" }
3
+ | { kind: "doctor" }
4
+ | { kind: "update" }
5
+ | { kind: "init" }
6
+ | { kind: "tui" }
7
+ | { kind: "mcp-config" }
8
+ | { kind: "mcp-add" }
9
+ | { kind: "delegate" };
10
+
11
+ export function classifyCuekitCommand(argv: string[]): CuekitCommandClassification {
12
+ const command = argv[0];
13
+ if (command === undefined || command === "--help" || command === "-h") {
14
+ return { kind: "help" };
15
+ }
16
+ if (command === "init") {
17
+ return { kind: "init" };
18
+ }
19
+ if (command === "tui") {
20
+ return { kind: "tui" };
21
+ }
22
+ if (command === "mcp" && argv[1] === "config") {
23
+ return { kind: "mcp-config" };
24
+ }
25
+ if (command === "mcp" && argv[1] === "add") {
26
+ return { kind: "mcp-add" };
27
+ }
28
+ if (command === "doctor") {
29
+ return { kind: "doctor" };
30
+ }
31
+ if (command === "update") {
32
+ return { kind: "update" };
33
+ }
34
+ return { kind: "delegate" };
35
+ }
36
+
37
+ export function printMainHelp(): string {
38
+ return [
39
+ "cuekit — delegation substrate for coding agents",
40
+ "",
41
+ "Usage: cuekit <command> [options]",
42
+ "",
43
+ "Human-only commands:",
44
+ " cuekit init Create .cuekit.yaml and update .gitignore",
45
+ " cuekit tui Open the interactive task cockpit",
46
+ " cuekit doctor Diagnose local cuekit setup",
47
+ " cuekit update Show the latest Bun/GitHub install command",
48
+ "",
49
+ "Command groups:",
50
+ " task, team, adapter, agent, session, tool, mcp",
51
+ "",
52
+ "Use 'cuekit init --help' or 'cuekit tui --help' for human-only command help.",
53
+ "",
54
+ ].join("\n");
55
+ }
56
+
57
+ export function printDoctorHelp(): string {
58
+ return [
59
+ "cuekit doctor — diagnose local cuekit setup",
60
+ "",
61
+ "Usage: cuekit doctor [options]",
62
+ "",
63
+ "Options:",
64
+ " -h, --help Show this help message",
65
+ " --fix Repair safe state DB issues such as SQLite-formatted task timestamps",
66
+ "",
67
+ "Checks:",
68
+ " cuekit version, bun, tmux, state db, project config, MCP config helper, update",
69
+ "",
70
+ "Exit codes:",
71
+ " 0 All required checks pass (warnings are non-blocking)",
72
+ " 1 One or more required checks failed",
73
+ "",
74
+ ].join("\n");
75
+ }
76
+
77
+ export function printUpdateHelp(): string {
78
+ return [
79
+ "cuekit update — check for a newer cuekit release",
80
+ "",
81
+ "Usage: cuekit update [options]",
82
+ "",
83
+ "Options:",
84
+ " -h, --help Show this help message",
85
+ "",
86
+ "Prints the current installed version and the latest stable release tag from",
87
+ "GitHub, then shows the exact bun command to upgrade.",
88
+ "",
89
+ "Update is advisory only: it never runs bun install automatically.",
90
+ "After upgrading, restart any MCP client that uses cuekit.",
91
+ "",
92
+ ].join("\n");
93
+ }