@creativeintelligence/abbie 0.1.5 → 0.1.7
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/bin/dev.js +1 -49
- package/bin/run.js +42 -49
- package/dist/cli/commands/login.js +26 -0
- package/dist/cli/commands/project/add.d.ts +0 -1
- package/dist/cli/commands/project/add.js +16 -52
- package/dist/cli/commands/project/list.js +13 -93
- package/dist/cli/commands/project/remove.d.ts +0 -2
- package/dist/cli/commands/project/remove.js +11 -28
- package/dist/cli/commands/session/list.js +3 -12
- package/dist/cli/commands/session/mark-done.js +1 -7
- package/dist/cli/commands/session/start.d.ts +0 -1
- package/dist/cli/commands/session/start.js +5 -7
- package/dist/lib/active-sessions.d.ts +0 -12
- package/dist/lib/active-sessions.js +6 -175
- package/dist/lib/project-path.d.ts +6 -0
- package/dist/lib/project-path.js +21 -0
- package/dist/lib.d.ts +1 -2
- package/dist/lib.js +2 -4
- package/oclif.manifest.json +2569 -6368
- package/package.json +1 -1
- package/dist/cli/commands/backlog/add.d.ts +0 -22
- package/dist/cli/commands/backlog/add.js +0 -65
- package/dist/cli/commands/backlog/claim.d.ts +0 -19
- package/dist/cli/commands/backlog/claim.js +0 -45
- package/dist/cli/commands/backlog/complete.d.ts +0 -18
- package/dist/cli/commands/backlog/complete.js +0 -42
- package/dist/cli/commands/backlog/list.d.ts +0 -20
- package/dist/cli/commands/backlog/list.js +0 -91
- package/dist/cli/commands/backlog/pick.d.ts +0 -18
- package/dist/cli/commands/backlog/pick.js +0 -42
- package/dist/cli/commands/backlog/sync.d.ts +0 -24
- package/dist/cli/commands/backlog/sync.js +0 -109
- package/dist/cli/commands/daemon.d.ts +0 -56
- package/dist/cli/commands/daemon.js +0 -1465
- package/dist/cli/commands/docs/lint.d.ts +0 -18
- package/dist/cli/commands/docs/lint.js +0 -82
- package/dist/cli/commands/docs/sync.d.ts +0 -19
- package/dist/cli/commands/docs/sync.js +0 -76
- package/dist/cli/commands/gc.d.ts +0 -29
- package/dist/cli/commands/gc.js +0 -211
- package/dist/cli/commands/index.d.ts +0 -36
- package/dist/cli/commands/index.js +0 -228
- package/dist/cli/commands/panes/broker.d.ts +0 -17
- package/dist/cli/commands/panes/broker.js +0 -57
- package/dist/cli/commands/panes/pipe-sink.d.ts +0 -17
- package/dist/cli/commands/panes/pipe-sink.js +0 -90
- package/dist/cli/commands/panes/snapshot.d.ts +0 -20
- package/dist/cli/commands/panes/snapshot.js +0 -125
- package/dist/cli/commands/preview/init.d.ts +0 -25
- package/dist/cli/commands/preview/init.js +0 -159
- package/dist/cli/commands/preview/sync.d.ts +0 -23
- package/dist/cli/commands/preview/sync.js +0 -144
- package/dist/cli/commands/preview/watch.d.ts +0 -24
- package/dist/cli/commands/preview/watch.js +0 -153
- package/dist/cli/commands/resource/acquire.d.ts +0 -21
- package/dist/cli/commands/resource/acquire.js +0 -90
- package/dist/cli/commands/resource/list.d.ts +0 -15
- package/dist/cli/commands/resource/list.js +0 -61
- package/dist/cli/commands/resource/release.d.ts +0 -18
- package/dist/cli/commands/resource/release.js +0 -50
- package/dist/cli/commands/resource/wait.d.ts +0 -21
- package/dist/cli/commands/resource/wait.js +0 -73
- package/dist/cli/commands/session/view.d.ts +0 -24
- package/dist/cli/commands/session/view.js +0 -145
- package/dist/cli/commands/start.d.ts +0 -37
- package/dist/cli/commands/start.js +0 -234
- package/dist/cli/commands/triage/claim.d.ts +0 -23
- package/dist/cli/commands/triage/claim.js +0 -186
- package/dist/cli/commands/triage/list.d.ts +0 -22
- package/dist/cli/commands/triage/list.js +0 -112
- package/dist/cli/commands/triage/next.d.ts +0 -18
- package/dist/cli/commands/triage/next.js +0 -63
- package/dist/cli/commands/triage/pull.d.ts +0 -19
- package/dist/cli/commands/triage/pull.js +0 -82
- package/dist/cli/commands/triage/stats.d.ts +0 -16
- package/dist/cli/commands/triage/stats.js +0 -69
- package/dist/cli/commands/tunnel/list.d.ts +0 -16
- package/dist/cli/commands/tunnel/list.js +0 -98
- package/dist/cli/commands/tunnel/start.d.ts +0 -24
- package/dist/cli/commands/tunnel/start.js +0 -107
- package/dist/cli/commands/tunnel/stop.d.ts +0 -20
- package/dist/cli/commands/tunnel/stop.js +0 -90
- package/dist/cli/commands/tunnel/url.d.ts +0 -21
- package/dist/cli/commands/tunnel/url.js +0 -70
- package/dist/cli/commands/windows/context.d.ts +0 -18
- package/dist/cli/commands/windows/context.js +0 -326
- package/dist/cli/commands/windows/focus.d.ts +0 -17
- package/dist/cli/commands/windows/focus.js +0 -103
- package/dist/cli/commands/windows/list.d.ts +0 -21
- package/dist/cli/commands/windows/list.js +0 -172
- package/dist/cli/commands/windows/map.d.ts +0 -17
- package/dist/cli/commands/windows/map.js +0 -168
- package/dist/cli/commands/windows/read.d.ts +0 -21
- package/dist/cli/commands/windows/read.js +0 -241
- package/dist/cli/commands/windows/search.d.ts +0 -24
- package/dist/cli/commands/windows/search.js +0 -171
- package/dist/cli/commands/windows/show.d.ts +0 -19
- package/dist/cli/commands/windows/show.js +0 -165
- package/dist/cli/commands/windows/watch.d.ts +0 -19
- package/dist/cli/commands/windows/watch.js +0 -241
- package/dist/lib/managed-session.d.ts +0 -27
- package/dist/lib/managed-session.js +0 -105
- package/dist/lib/panes/broker.d.ts +0 -130
- package/dist/lib/panes/broker.js +0 -97
- package/dist/lib/panes/index.d.ts +0 -2
- package/dist/lib/panes/index.js +0 -1
- package/dist/lib/panes/server.d.ts +0 -17
- package/dist/lib/panes/server.js +0 -308
- package/dist/lib/preview/manager.d.ts +0 -77
- package/dist/lib/preview/manager.js +0 -369
- package/dist/lib/preview/schema.d.ts +0 -2
- package/dist/lib/preview/schema.js +0 -32
- package/dist/lib/preview/sprite.d.ts +0 -85
- package/dist/lib/preview/sprite.js +0 -321
- package/dist/lib/preview/watcher.d.ts +0 -63
- package/dist/lib/preview/watcher.js +0 -185
- package/dist/lib/project-identity.d.ts +0 -16
- package/dist/lib/project-identity.js +0 -75
- package/dist/lib/tmux/bridge.d.ts +0 -133
- package/dist/lib/tmux/bridge.js +0 -315
- package/dist/lib/tmux/context.d.ts +0 -82
- package/dist/lib/tmux/context.js +0 -239
- package/dist/lib/tmux/index.d.ts +0 -8
- package/dist/lib/tmux/index.js +0 -11
- package/dist/lib/tmux/map.d.ts +0 -57
- package/dist/lib/tmux/map.js +0 -198
- package/dist/lib/tmux/panes.d.ts +0 -27
- package/dist/lib/tmux/panes.js +0 -151
- package/dist/lib/tmux/redaction.d.ts +0 -57
- package/dist/lib/tmux/redaction.js +0 -152
- package/dist/lib/web/analytics.d.ts +0 -63
- package/dist/lib/web/analytics.js +0 -168
- package/dist/lib/web/server.d.ts +0 -26
- package/dist/lib/web/server.js +0 -697
- package/dist/lib/web/tmux-bridge.d.ts +0 -7
- package/dist/lib/web/tmux-bridge.js +0 -7
- package/dist/lib/windows/index.d.ts +0 -3
- package/dist/lib/windows/index.js +0 -2
- package/dist/lib/windows/inventory.d.ts +0 -21
- package/dist/lib/windows/inventory.js +0 -263
- package/dist/lib/windows/types.d.ts +0 -46
- package/dist/lib/windows/types.js +0 -1
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* abbie (default command) — the single entry point.
|
|
3
|
-
*
|
|
4
|
-
* First run:
|
|
5
|
-
* 1. Check Pi → not found → auto-install
|
|
6
|
-
* 2. Install Abbie Pi extension
|
|
7
|
-
* 3. Open browser for Clerk auth
|
|
8
|
-
* 4. Launch Pi (extension auto-starts bridge)
|
|
9
|
-
*
|
|
10
|
-
* Subsequent runs:
|
|
11
|
-
* Launch Pi directly (extension handles bridge)
|
|
12
|
-
*/
|
|
13
|
-
import { existsSync, mkdirSync, cpSync, readFileSync } from "node:fs";
|
|
14
|
-
import { homedir } from "node:os";
|
|
15
|
-
import { join, dirname } from "node:path";
|
|
16
|
-
import { fileURLToPath } from "node:url";
|
|
17
|
-
import { spawnSync, spawn, execSync } from "node:child_process";
|
|
18
|
-
import { Flags } from "@oclif/core";
|
|
19
|
-
import { BaseCommand } from "../base-command.js";
|
|
20
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
-
const __dirname = dirname(__filename);
|
|
22
|
-
const PI_PACKAGE = "@mariozechner/pi-coding-agent";
|
|
23
|
-
const ABBIE_HOME = join(homedir(), ".abbie");
|
|
24
|
-
const PI_AGENT_DIR = join(homedir(), ".pi", "agent");
|
|
25
|
-
const PI_EXT_DIR = join(PI_AGENT_DIR, "extensions", "abbie");
|
|
26
|
-
function piInstalled() {
|
|
27
|
-
try {
|
|
28
|
-
const result = spawnSync("pi", ["--version"], { encoding: "utf8", timeout: 5000 });
|
|
29
|
-
if (result.status === 0 && result.stdout?.trim()) {
|
|
30
|
-
return { installed: true, version: result.stdout.trim(), path: "pi" };
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
catch { /* not found */ }
|
|
34
|
-
return { installed: false };
|
|
35
|
-
}
|
|
36
|
-
function abbieConfigured() {
|
|
37
|
-
const configPath = join(ABBIE_HOME, "config.json");
|
|
38
|
-
if (!existsSync(configPath))
|
|
39
|
-
return false;
|
|
40
|
-
try {
|
|
41
|
-
const cfg = JSON.parse(readFileSync(configPath, "utf8"));
|
|
42
|
-
return Boolean(cfg.clerkId || cfg.convexUrl);
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function extensionInstalled() {
|
|
49
|
-
return existsSync(join(PI_EXT_DIR, "index.ts")) || existsSync(join(PI_EXT_DIR, "index.js"));
|
|
50
|
-
}
|
|
51
|
-
export default class DefaultCommand extends BaseCommand {
|
|
52
|
-
static id = "";
|
|
53
|
-
static summary = "Launch Abbie";
|
|
54
|
-
static description = `Start an agent session powered by Pi with cloud sync via Abbie.
|
|
55
|
-
|
|
56
|
-
On first run, walks you through setup:
|
|
57
|
-
• Installs Pi (the coding agent runtime) if needed
|
|
58
|
-
• Installs the Abbie extension into Pi
|
|
59
|
-
• Authenticates with your Abbie account
|
|
60
|
-
• Launches Pi with the bridge auto-connected
|
|
61
|
-
|
|
62
|
-
After setup, just run \`abbie\` to start working.`;
|
|
63
|
-
static examples = [
|
|
64
|
-
"$ abbie",
|
|
65
|
-
"$ abbie --setup",
|
|
66
|
-
"$ abbie --status",
|
|
67
|
-
];
|
|
68
|
-
static flags = {
|
|
69
|
-
...BaseCommand.baseFlags,
|
|
70
|
-
setup: Flags.boolean({
|
|
71
|
-
description: "Force re-run the setup wizard",
|
|
72
|
-
default: false,
|
|
73
|
-
}),
|
|
74
|
-
status: Flags.boolean({
|
|
75
|
-
description: "Show setup status and exit",
|
|
76
|
-
default: false,
|
|
77
|
-
}),
|
|
78
|
-
};
|
|
79
|
-
// Pass-through: any extra args go to pi
|
|
80
|
-
static strict = false;
|
|
81
|
-
async execute() {
|
|
82
|
-
const { flags, argv } = await this.parse(DefaultCommand);
|
|
83
|
-
this.parsedFlags = flags;
|
|
84
|
-
const pi = piInstalled();
|
|
85
|
-
const configured = abbieConfigured();
|
|
86
|
-
const extOk = extensionInstalled();
|
|
87
|
-
// --status: show state and exit
|
|
88
|
-
if (flags.status) {
|
|
89
|
-
this.log("");
|
|
90
|
-
this.log(" abbie status");
|
|
91
|
-
this.log("");
|
|
92
|
-
this.log(` pi: ${pi.installed ? `✓ ${pi.version}` : "✗ not installed"}`);
|
|
93
|
-
this.log(` extension: ${extOk ? "✓ installed" : "✗ not installed"}`);
|
|
94
|
-
this.log(` auth: ${configured ? "✓ configured" : "✗ not configured"}`);
|
|
95
|
-
this.log("");
|
|
96
|
-
return { pi: pi.installed, extension: extOk, auth: configured };
|
|
97
|
-
}
|
|
98
|
-
// Setup needed?
|
|
99
|
-
const needsSetup = flags.setup || !pi.installed || !configured || !extOk;
|
|
100
|
-
if (needsSetup) {
|
|
101
|
-
await this.runSetup(pi, configured, extOk);
|
|
102
|
-
// Re-check after setup
|
|
103
|
-
const piNow = piInstalled();
|
|
104
|
-
if (!piNow.installed) {
|
|
105
|
-
this.error("Pi installation failed. Install manually:\n\n npm install -g @mariozechner/pi-coding-agent\n");
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// Launch Pi with any pass-through args
|
|
109
|
-
this.log("");
|
|
110
|
-
this.log(" launching pi...");
|
|
111
|
-
this.log("");
|
|
112
|
-
const piArgs = argv.length > 0 ? argv : [];
|
|
113
|
-
const child = spawn("pi", piArgs, {
|
|
114
|
-
stdio: "inherit",
|
|
115
|
-
env: process.env,
|
|
116
|
-
cwd: process.cwd(),
|
|
117
|
-
});
|
|
118
|
-
process.on("SIGINT", () => child.kill("SIGINT"));
|
|
119
|
-
process.on("SIGTERM", () => child.kill("SIGTERM"));
|
|
120
|
-
return new Promise((resolve) => {
|
|
121
|
-
child.on("exit", (code) => {
|
|
122
|
-
resolve({ exitCode: code ?? 0 });
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
async runSetup(pi, configured, extOk) {
|
|
127
|
-
this.log("");
|
|
128
|
-
this.log(" abbie setup");
|
|
129
|
-
this.log(" ──────────");
|
|
130
|
-
this.log("");
|
|
131
|
-
// Step 1: Install Pi
|
|
132
|
-
if (!pi.installed) {
|
|
133
|
-
this.log(" [1/3] installing pi...");
|
|
134
|
-
this.log(` npm install -g ${PI_PACKAGE}`);
|
|
135
|
-
this.log("");
|
|
136
|
-
try {
|
|
137
|
-
execSync(`npm install -g ${PI_PACKAGE}`, {
|
|
138
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
139
|
-
encoding: "utf8",
|
|
140
|
-
timeout: 120_000,
|
|
141
|
-
});
|
|
142
|
-
const check = piInstalled();
|
|
143
|
-
if (check.installed) {
|
|
144
|
-
this.log(` ✓ pi ${check.version} installed`);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
this.error("Pi install completed but binary not found. Check your PATH.");
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch (err) {
|
|
151
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
152
|
-
this.logWarn(`auto-install failed: ${msg}`);
|
|
153
|
-
this.log("");
|
|
154
|
-
this.log(" install manually:");
|
|
155
|
-
this.log(` npm install -g ${PI_PACKAGE}`);
|
|
156
|
-
this.log("");
|
|
157
|
-
this.error("Pi is required to continue.");
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
this.log(` [1/3] pi ${pi.version} ✓`);
|
|
162
|
-
}
|
|
163
|
-
this.log("");
|
|
164
|
-
// Step 2: Install Abbie extension
|
|
165
|
-
if (!extOk) {
|
|
166
|
-
this.log(" [2/3] installing abbie extension...");
|
|
167
|
-
// Find the bundled extension
|
|
168
|
-
const extSource = this.findExtensionSource();
|
|
169
|
-
if (extSource) {
|
|
170
|
-
mkdirSync(PI_EXT_DIR, { recursive: true });
|
|
171
|
-
cpSync(extSource, PI_EXT_DIR, { recursive: true });
|
|
172
|
-
this.log(" ✓ extension installed");
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
this.logWarn("extension source not found — the abbie tools won't be available in Pi");
|
|
176
|
-
this.logWarn("this is non-fatal; you can install it manually later");
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
this.log(" [2/3] extension ✓");
|
|
181
|
-
}
|
|
182
|
-
this.log("");
|
|
183
|
-
// Step 3: Authenticate
|
|
184
|
-
if (!configured) {
|
|
185
|
-
this.log(" [3/3] authenticating...");
|
|
186
|
-
this.log(" opening browser for login...");
|
|
187
|
-
this.log("");
|
|
188
|
-
// Delegate to the login command
|
|
189
|
-
try {
|
|
190
|
-
await this.config.runCommand("login", []);
|
|
191
|
-
}
|
|
192
|
-
catch {
|
|
193
|
-
this.logWarn("login failed or was cancelled — you can run `abbie login` later");
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
this.log(" [3/3] authenticated ✓");
|
|
198
|
-
}
|
|
199
|
-
this.log("");
|
|
200
|
-
this.log(" setup complete");
|
|
201
|
-
this.log("");
|
|
202
|
-
this.log(" tip: open Pi and type /login to connect an AI provider");
|
|
203
|
-
this.log(" (Anthropic, OpenAI, Google, or GitHub Copilot)");
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Find the bundled extension source directory.
|
|
207
|
-
* Looks in several locations depending on how the CLI is installed.
|
|
208
|
-
*/
|
|
209
|
-
findExtensionSource() {
|
|
210
|
-
const candidates = [
|
|
211
|
-
// When installed globally via npm — extension bundled in package
|
|
212
|
-
join(__dirname, "..", "..", "..", "extensions", "abbie"),
|
|
213
|
-
// When running from the monorepo
|
|
214
|
-
join(process.cwd(), "extensions", "abbie"),
|
|
215
|
-
// The canonical location (might already exist from manual setup)
|
|
216
|
-
join(homedir(), ".pi", "agent", "extensions", "abbie"),
|
|
217
|
-
];
|
|
218
|
-
for (const candidate of candidates) {
|
|
219
|
-
if (existsSync(join(candidate, "index.ts")) || existsSync(join(candidate, "index.js"))) {
|
|
220
|
-
// Don't "find" the target as a source — that's circular
|
|
221
|
-
if (candidate === PI_EXT_DIR)
|
|
222
|
-
continue;
|
|
223
|
-
return candidate;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
return null;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from "../../base-command.js";
|
|
2
|
-
export default class PanesBrokerCommand extends BaseCommand {
|
|
3
|
-
static summary: string;
|
|
4
|
-
static hidden: boolean;
|
|
5
|
-
static examples: string[];
|
|
6
|
-
static flags: {
|
|
7
|
-
socket: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
fps: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
"json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
-
};
|
|
15
|
-
protected execute(): Promise<unknown>;
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=broker.d.ts.map
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { Flags } from "@oclif/core";
|
|
4
|
-
import { startPanesBroker } from "../../../lib/panes/server.js";
|
|
5
|
-
import { BaseCommand } from "../../base-command.js";
|
|
6
|
-
export default class PanesBrokerCommand extends BaseCommand {
|
|
7
|
-
static summary = "Run local panes broker (event-driven tmux streaming)";
|
|
8
|
-
static hidden = false;
|
|
9
|
-
static examples = [
|
|
10
|
-
"$ abbie panes broker",
|
|
11
|
-
"$ abbie panes broker --socket ~/.abbie/run/panes-broker.sock",
|
|
12
|
-
"$ abbie panes broker --fps 30",
|
|
13
|
-
];
|
|
14
|
-
static flags = {
|
|
15
|
-
...BaseCommand.baseFlags,
|
|
16
|
-
socket: Flags.string({
|
|
17
|
-
description: "Unix socket path for the broker",
|
|
18
|
-
required: false,
|
|
19
|
-
}),
|
|
20
|
-
fps: Flags.integer({
|
|
21
|
-
description: "Max snapshots per second (throttled)",
|
|
22
|
-
default: 30,
|
|
23
|
-
}),
|
|
24
|
-
force: Flags.boolean({
|
|
25
|
-
description: "Override any existing tmux pipe-pane for a pane",
|
|
26
|
-
default: false,
|
|
27
|
-
}),
|
|
28
|
-
};
|
|
29
|
-
async execute() {
|
|
30
|
-
const { flags } = await this.parse(PanesBrokerCommand);
|
|
31
|
-
this.parsedFlags = flags;
|
|
32
|
-
const devBin = join(this.config.root, "bin", "dev.js");
|
|
33
|
-
const runBin = join(this.config.root, "bin", "run.js");
|
|
34
|
-
const agentsBinPath = existsSync(devBin) ? devBin : runBin;
|
|
35
|
-
const broker = await startPanesBroker({
|
|
36
|
-
socketPath: flags.socket,
|
|
37
|
-
fps: flags.fps,
|
|
38
|
-
forcePipe: flags.force,
|
|
39
|
-
}, {
|
|
40
|
-
agentsBinPath,
|
|
41
|
-
logInfo: (m) => this.logInfo(m),
|
|
42
|
-
logWarn: (m) => this.logWarn(m),
|
|
43
|
-
});
|
|
44
|
-
// Block forever until killed.
|
|
45
|
-
await new Promise((resolve) => {
|
|
46
|
-
const onStop = async () => {
|
|
47
|
-
process.off("SIGINT", onStop);
|
|
48
|
-
process.off("SIGTERM", onStop);
|
|
49
|
-
await broker.stop();
|
|
50
|
-
resolve();
|
|
51
|
-
};
|
|
52
|
-
process.on("SIGINT", onStop);
|
|
53
|
-
process.on("SIGTERM", onStop);
|
|
54
|
-
});
|
|
55
|
-
return { socketPath: broker.socketPath };
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from "../../base-command.js";
|
|
2
|
-
export default class PanesPipeSinkCommand extends BaseCommand {
|
|
3
|
-
static summary: string;
|
|
4
|
-
static hidden: boolean;
|
|
5
|
-
static args: {
|
|
6
|
-
pane: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
static flags: {
|
|
9
|
-
sock: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
"json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
-
};
|
|
15
|
-
protected execute(): Promise<unknown>;
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=pipe-sink.d.ts.map
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { createConnection } from "node:net";
|
|
2
|
-
import { Args, Flags } from "@oclif/core";
|
|
3
|
-
import { createNdjsonLineParser, getDefaultPanesBrokerSocketPath, } from "../../../lib/panes/broker.js";
|
|
4
|
-
import { BaseCommand } from "../../base-command.js";
|
|
5
|
-
export default class PanesPipeSinkCommand extends BaseCommand {
|
|
6
|
-
static summary = "Internal: tmux pipe-pane sink (stdin <-> broker)";
|
|
7
|
-
static hidden = true;
|
|
8
|
-
static args = {
|
|
9
|
-
pane: Args.string({
|
|
10
|
-
description: "tmux pane id (e.g. %3)",
|
|
11
|
-
required: true,
|
|
12
|
-
}),
|
|
13
|
-
};
|
|
14
|
-
static flags = {
|
|
15
|
-
...BaseCommand.baseFlags,
|
|
16
|
-
sock: Flags.string({
|
|
17
|
-
description: "Broker socket path",
|
|
18
|
-
required: false,
|
|
19
|
-
}),
|
|
20
|
-
};
|
|
21
|
-
async execute() {
|
|
22
|
-
const { args, flags } = await this.parse(PanesPipeSinkCommand);
|
|
23
|
-
this.parsedFlags = flags;
|
|
24
|
-
const paneId = args.pane;
|
|
25
|
-
const socketPath = flags.sock ?? getDefaultPanesBrokerSocketPath();
|
|
26
|
-
// Connect to broker. If broker isn't running, exit quietly so tmux isn't spammed.
|
|
27
|
-
const socket = createConnection({ path: socketPath });
|
|
28
|
-
const parser = createNdjsonLineParser();
|
|
29
|
-
socket.on("data", (chunk) => parser.pushChunk(chunk));
|
|
30
|
-
const send = (msg) => {
|
|
31
|
-
socket.write(`${JSON.stringify(msg)}\n`);
|
|
32
|
-
};
|
|
33
|
-
const done = new Promise((resolve) => {
|
|
34
|
-
const finish = () => resolve();
|
|
35
|
-
socket.on("error", finish);
|
|
36
|
-
socket.on("close", finish);
|
|
37
|
-
});
|
|
38
|
-
// Identify as a pipe client for this pane.
|
|
39
|
-
send({
|
|
40
|
-
type: "client.hello",
|
|
41
|
-
at: new Date().toISOString(),
|
|
42
|
-
clientId: `pipe:${paneId}`,
|
|
43
|
-
version: 1,
|
|
44
|
-
pid: process.pid,
|
|
45
|
-
});
|
|
46
|
-
send({ type: "panes.pipe.hello", at: new Date().toISOString(), paneId });
|
|
47
|
-
parser.onMessage((msg) => {
|
|
48
|
-
if (msg.type !== "panes.pipe.input")
|
|
49
|
-
return;
|
|
50
|
-
if (msg.paneId !== paneId)
|
|
51
|
-
return;
|
|
52
|
-
const data = typeof msg.data === "string" ? msg.data : null;
|
|
53
|
-
if (!data)
|
|
54
|
-
return;
|
|
55
|
-
try {
|
|
56
|
-
const bytes = Buffer.from(data, "base64");
|
|
57
|
-
process.stdout.write(bytes);
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// ignore
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
// Forward raw pane output to broker as base64 chunks.
|
|
64
|
-
process.stdin.on("data", (chunk) => {
|
|
65
|
-
try {
|
|
66
|
-
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
|
|
67
|
-
send({
|
|
68
|
-
type: "panes.pipe.chunk",
|
|
69
|
-
at: new Date().toISOString(),
|
|
70
|
-
paneId,
|
|
71
|
-
data: buf.toString("base64"),
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
// ignore
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
// If stdin ends, exit.
|
|
79
|
-
process.stdin.on("end", () => {
|
|
80
|
-
try {
|
|
81
|
-
socket.end();
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
// ignore
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
await done;
|
|
88
|
-
return { ok: true };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from "../../base-command.js";
|
|
2
|
-
export default class PanesSnapshotCommand extends BaseCommand {
|
|
3
|
-
static summary: string;
|
|
4
|
-
static hidden: boolean;
|
|
5
|
-
static examples: string[];
|
|
6
|
-
static args: {
|
|
7
|
-
ref: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
-
};
|
|
9
|
-
static flags: {
|
|
10
|
-
lines: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
ansi: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
redact: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
-
"json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
-
ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
|
-
};
|
|
18
|
-
protected execute(): Promise<unknown>;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from "@oclif/core";
|
|
2
|
-
import { capturePane, capturePaneWithAnsi } from "../../../lib/tmux/bridge.js";
|
|
3
|
-
import { isRunning } from "../../../lib/tmux/index.js";
|
|
4
|
-
import { redactContent } from "../../../lib/tmux/redaction.js";
|
|
5
|
-
import * as windows from "../../../lib/windows/index.js";
|
|
6
|
-
import { BaseCommand } from "../../base-command.js";
|
|
7
|
-
function paneRef(window) {
|
|
8
|
-
return `${window.session}:${window.window}.${window.pane}`;
|
|
9
|
-
}
|
|
10
|
-
export default class PanesSnapshotCommand extends BaseCommand {
|
|
11
|
-
static summary = "Capture tmux pane scrollback snapshot";
|
|
12
|
-
static hidden = false;
|
|
13
|
-
static examples = [
|
|
14
|
-
"$ abbie panes snapshot",
|
|
15
|
-
"$ abbie panes snapshot %3 --lines 200",
|
|
16
|
-
"$ abbie panes snapshot work:0.0 --lines 500 --ansi",
|
|
17
|
-
"$ abbie panes snapshot --json",
|
|
18
|
-
];
|
|
19
|
-
static args = {
|
|
20
|
-
ref: Args.string({
|
|
21
|
-
description: "Pane ID (e.g. %3) or session:window.pane (e.g. work:0.0)",
|
|
22
|
-
required: false,
|
|
23
|
-
}),
|
|
24
|
-
};
|
|
25
|
-
static flags = {
|
|
26
|
-
...BaseCommand.baseFlags,
|
|
27
|
-
lines: Flags.integer({
|
|
28
|
-
description: "Number of lines to capture from the bottom",
|
|
29
|
-
default: 200,
|
|
30
|
-
}),
|
|
31
|
-
ansi: Flags.boolean({
|
|
32
|
-
description: "Preserve ANSI escape codes",
|
|
33
|
-
default: false,
|
|
34
|
-
}),
|
|
35
|
-
redact: Flags.boolean({
|
|
36
|
-
description: "Enable redaction",
|
|
37
|
-
default: true,
|
|
38
|
-
allowNo: true,
|
|
39
|
-
}),
|
|
40
|
-
};
|
|
41
|
-
async execute() {
|
|
42
|
-
const { args, flags } = await this.parse(PanesSnapshotCommand);
|
|
43
|
-
this.parsedFlags = flags;
|
|
44
|
-
const tmuxRunning = await isRunning();
|
|
45
|
-
if (!tmuxRunning) {
|
|
46
|
-
const result = {
|
|
47
|
-
tmuxRunning: false,
|
|
48
|
-
window: null,
|
|
49
|
-
ref: null,
|
|
50
|
-
paneId: null,
|
|
51
|
-
encoding: flags.ansi ? "ansi" : "text",
|
|
52
|
-
lines: Math.max(1, flags.lines),
|
|
53
|
-
content: "",
|
|
54
|
-
redacted: flags.redact,
|
|
55
|
-
wasRedacted: false,
|
|
56
|
-
};
|
|
57
|
-
if (!this.jsonEnabled?.()) {
|
|
58
|
-
this.log("tmux is not running");
|
|
59
|
-
}
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
const maxLines = Math.max(1, flags.lines);
|
|
63
|
-
const state = args.ref
|
|
64
|
-
? await windows.getWindowState(args.ref, {
|
|
65
|
-
includeNvim: false,
|
|
66
|
-
includeAgent: false,
|
|
67
|
-
includeBuffers: false,
|
|
68
|
-
})
|
|
69
|
-
: await windows.getFocusedWindow({
|
|
70
|
-
includeNvim: false,
|
|
71
|
-
includeAgent: false,
|
|
72
|
-
includeBuffers: false,
|
|
73
|
-
});
|
|
74
|
-
if (!state) {
|
|
75
|
-
const result = {
|
|
76
|
-
tmuxRunning: true,
|
|
77
|
-
window: null,
|
|
78
|
-
ref: null,
|
|
79
|
-
paneId: null,
|
|
80
|
-
encoding: flags.ansi ? "ansi" : "text",
|
|
81
|
-
lines: maxLines,
|
|
82
|
-
content: "",
|
|
83
|
-
redacted: flags.redact,
|
|
84
|
-
wasRedacted: false,
|
|
85
|
-
};
|
|
86
|
-
if (!this.jsonEnabled?.()) {
|
|
87
|
-
this.log("Pane not found");
|
|
88
|
-
}
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
91
|
-
const encoding = flags.ansi ? "ansi" : "text";
|
|
92
|
-
const paneId = state.window.paneId || `${state.window.session}:${state.window.window}.${state.window.pane}`;
|
|
93
|
-
const raw = encoding === "ansi"
|
|
94
|
-
? await capturePaneWithAnsi(state.window.window, state.window.pane, {
|
|
95
|
-
session: state.window.session,
|
|
96
|
-
lines: maxLines,
|
|
97
|
-
})
|
|
98
|
-
: await capturePane(state.window.window, state.window.pane, {
|
|
99
|
-
session: state.window.session,
|
|
100
|
-
lines: maxLines,
|
|
101
|
-
});
|
|
102
|
-
let content = raw;
|
|
103
|
-
let wasRedacted = false;
|
|
104
|
-
if (flags.redact) {
|
|
105
|
-
const redaction = redactContent(raw, "balanced");
|
|
106
|
-
content = redaction.content;
|
|
107
|
-
wasRedacted = redaction.wasRedacted;
|
|
108
|
-
}
|
|
109
|
-
const result = {
|
|
110
|
-
tmuxRunning: true,
|
|
111
|
-
window: state.window,
|
|
112
|
-
ref: paneRef(state.window),
|
|
113
|
-
paneId,
|
|
114
|
-
encoding,
|
|
115
|
-
lines: maxLines,
|
|
116
|
-
content,
|
|
117
|
-
redacted: flags.redact,
|
|
118
|
-
wasRedacted,
|
|
119
|
-
};
|
|
120
|
-
if (!this.jsonEnabled?.()) {
|
|
121
|
-
this.log(content);
|
|
122
|
-
}
|
|
123
|
-
return result;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from "../../base-command.js";
|
|
2
|
-
/**
|
|
3
|
-
* Initialize a sprite for a project: create sprite, make URL public, register in SQLite
|
|
4
|
-
*/
|
|
5
|
-
export default class PreviewInit extends BaseCommand {
|
|
6
|
-
static description: string;
|
|
7
|
-
static hidden: boolean;
|
|
8
|
-
static examples: string[];
|
|
9
|
-
static args: {
|
|
10
|
-
project: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
11
|
-
};
|
|
12
|
-
static flags: {
|
|
13
|
-
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
"dev-command": import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
-
port: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
-
"doppler-project": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
-
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
|
-
format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
-
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
20
|
-
"json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
21
|
-
ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
22
|
-
};
|
|
23
|
-
protected execute(): Promise<unknown>;
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=init.d.ts.map
|