@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.
Files changed (142) hide show
  1. package/bin/dev.js +1 -49
  2. package/bin/run.js +42 -49
  3. package/dist/cli/commands/login.js +26 -0
  4. package/dist/cli/commands/project/add.d.ts +0 -1
  5. package/dist/cli/commands/project/add.js +16 -52
  6. package/dist/cli/commands/project/list.js +13 -93
  7. package/dist/cli/commands/project/remove.d.ts +0 -2
  8. package/dist/cli/commands/project/remove.js +11 -28
  9. package/dist/cli/commands/session/list.js +3 -12
  10. package/dist/cli/commands/session/mark-done.js +1 -7
  11. package/dist/cli/commands/session/start.d.ts +0 -1
  12. package/dist/cli/commands/session/start.js +5 -7
  13. package/dist/lib/active-sessions.d.ts +0 -12
  14. package/dist/lib/active-sessions.js +6 -175
  15. package/dist/lib/project-path.d.ts +6 -0
  16. package/dist/lib/project-path.js +21 -0
  17. package/dist/lib.d.ts +1 -2
  18. package/dist/lib.js +2 -4
  19. package/oclif.manifest.json +2569 -6368
  20. package/package.json +1 -1
  21. package/dist/cli/commands/backlog/add.d.ts +0 -22
  22. package/dist/cli/commands/backlog/add.js +0 -65
  23. package/dist/cli/commands/backlog/claim.d.ts +0 -19
  24. package/dist/cli/commands/backlog/claim.js +0 -45
  25. package/dist/cli/commands/backlog/complete.d.ts +0 -18
  26. package/dist/cli/commands/backlog/complete.js +0 -42
  27. package/dist/cli/commands/backlog/list.d.ts +0 -20
  28. package/dist/cli/commands/backlog/list.js +0 -91
  29. package/dist/cli/commands/backlog/pick.d.ts +0 -18
  30. package/dist/cli/commands/backlog/pick.js +0 -42
  31. package/dist/cli/commands/backlog/sync.d.ts +0 -24
  32. package/dist/cli/commands/backlog/sync.js +0 -109
  33. package/dist/cli/commands/daemon.d.ts +0 -56
  34. package/dist/cli/commands/daemon.js +0 -1465
  35. package/dist/cli/commands/docs/lint.d.ts +0 -18
  36. package/dist/cli/commands/docs/lint.js +0 -82
  37. package/dist/cli/commands/docs/sync.d.ts +0 -19
  38. package/dist/cli/commands/docs/sync.js +0 -76
  39. package/dist/cli/commands/gc.d.ts +0 -29
  40. package/dist/cli/commands/gc.js +0 -211
  41. package/dist/cli/commands/index.d.ts +0 -36
  42. package/dist/cli/commands/index.js +0 -228
  43. package/dist/cli/commands/panes/broker.d.ts +0 -17
  44. package/dist/cli/commands/panes/broker.js +0 -57
  45. package/dist/cli/commands/panes/pipe-sink.d.ts +0 -17
  46. package/dist/cli/commands/panes/pipe-sink.js +0 -90
  47. package/dist/cli/commands/panes/snapshot.d.ts +0 -20
  48. package/dist/cli/commands/panes/snapshot.js +0 -125
  49. package/dist/cli/commands/preview/init.d.ts +0 -25
  50. package/dist/cli/commands/preview/init.js +0 -159
  51. package/dist/cli/commands/preview/sync.d.ts +0 -23
  52. package/dist/cli/commands/preview/sync.js +0 -144
  53. package/dist/cli/commands/preview/watch.d.ts +0 -24
  54. package/dist/cli/commands/preview/watch.js +0 -153
  55. package/dist/cli/commands/resource/acquire.d.ts +0 -21
  56. package/dist/cli/commands/resource/acquire.js +0 -90
  57. package/dist/cli/commands/resource/list.d.ts +0 -15
  58. package/dist/cli/commands/resource/list.js +0 -61
  59. package/dist/cli/commands/resource/release.d.ts +0 -18
  60. package/dist/cli/commands/resource/release.js +0 -50
  61. package/dist/cli/commands/resource/wait.d.ts +0 -21
  62. package/dist/cli/commands/resource/wait.js +0 -73
  63. package/dist/cli/commands/session/view.d.ts +0 -24
  64. package/dist/cli/commands/session/view.js +0 -145
  65. package/dist/cli/commands/start.d.ts +0 -37
  66. package/dist/cli/commands/start.js +0 -234
  67. package/dist/cli/commands/triage/claim.d.ts +0 -23
  68. package/dist/cli/commands/triage/claim.js +0 -186
  69. package/dist/cli/commands/triage/list.d.ts +0 -22
  70. package/dist/cli/commands/triage/list.js +0 -112
  71. package/dist/cli/commands/triage/next.d.ts +0 -18
  72. package/dist/cli/commands/triage/next.js +0 -63
  73. package/dist/cli/commands/triage/pull.d.ts +0 -19
  74. package/dist/cli/commands/triage/pull.js +0 -82
  75. package/dist/cli/commands/triage/stats.d.ts +0 -16
  76. package/dist/cli/commands/triage/stats.js +0 -69
  77. package/dist/cli/commands/tunnel/list.d.ts +0 -16
  78. package/dist/cli/commands/tunnel/list.js +0 -98
  79. package/dist/cli/commands/tunnel/start.d.ts +0 -24
  80. package/dist/cli/commands/tunnel/start.js +0 -107
  81. package/dist/cli/commands/tunnel/stop.d.ts +0 -20
  82. package/dist/cli/commands/tunnel/stop.js +0 -90
  83. package/dist/cli/commands/tunnel/url.d.ts +0 -21
  84. package/dist/cli/commands/tunnel/url.js +0 -70
  85. package/dist/cli/commands/windows/context.d.ts +0 -18
  86. package/dist/cli/commands/windows/context.js +0 -326
  87. package/dist/cli/commands/windows/focus.d.ts +0 -17
  88. package/dist/cli/commands/windows/focus.js +0 -103
  89. package/dist/cli/commands/windows/list.d.ts +0 -21
  90. package/dist/cli/commands/windows/list.js +0 -172
  91. package/dist/cli/commands/windows/map.d.ts +0 -17
  92. package/dist/cli/commands/windows/map.js +0 -168
  93. package/dist/cli/commands/windows/read.d.ts +0 -21
  94. package/dist/cli/commands/windows/read.js +0 -241
  95. package/dist/cli/commands/windows/search.d.ts +0 -24
  96. package/dist/cli/commands/windows/search.js +0 -171
  97. package/dist/cli/commands/windows/show.d.ts +0 -19
  98. package/dist/cli/commands/windows/show.js +0 -165
  99. package/dist/cli/commands/windows/watch.d.ts +0 -19
  100. package/dist/cli/commands/windows/watch.js +0 -241
  101. package/dist/lib/managed-session.d.ts +0 -27
  102. package/dist/lib/managed-session.js +0 -105
  103. package/dist/lib/panes/broker.d.ts +0 -130
  104. package/dist/lib/panes/broker.js +0 -97
  105. package/dist/lib/panes/index.d.ts +0 -2
  106. package/dist/lib/panes/index.js +0 -1
  107. package/dist/lib/panes/server.d.ts +0 -17
  108. package/dist/lib/panes/server.js +0 -308
  109. package/dist/lib/preview/manager.d.ts +0 -77
  110. package/dist/lib/preview/manager.js +0 -369
  111. package/dist/lib/preview/schema.d.ts +0 -2
  112. package/dist/lib/preview/schema.js +0 -32
  113. package/dist/lib/preview/sprite.d.ts +0 -85
  114. package/dist/lib/preview/sprite.js +0 -321
  115. package/dist/lib/preview/watcher.d.ts +0 -63
  116. package/dist/lib/preview/watcher.js +0 -185
  117. package/dist/lib/project-identity.d.ts +0 -16
  118. package/dist/lib/project-identity.js +0 -75
  119. package/dist/lib/tmux/bridge.d.ts +0 -133
  120. package/dist/lib/tmux/bridge.js +0 -315
  121. package/dist/lib/tmux/context.d.ts +0 -82
  122. package/dist/lib/tmux/context.js +0 -239
  123. package/dist/lib/tmux/index.d.ts +0 -8
  124. package/dist/lib/tmux/index.js +0 -11
  125. package/dist/lib/tmux/map.d.ts +0 -57
  126. package/dist/lib/tmux/map.js +0 -198
  127. package/dist/lib/tmux/panes.d.ts +0 -27
  128. package/dist/lib/tmux/panes.js +0 -151
  129. package/dist/lib/tmux/redaction.d.ts +0 -57
  130. package/dist/lib/tmux/redaction.js +0 -152
  131. package/dist/lib/web/analytics.d.ts +0 -63
  132. package/dist/lib/web/analytics.js +0 -168
  133. package/dist/lib/web/server.d.ts +0 -26
  134. package/dist/lib/web/server.js +0 -697
  135. package/dist/lib/web/tmux-bridge.d.ts +0 -7
  136. package/dist/lib/web/tmux-bridge.js +0 -7
  137. package/dist/lib/windows/index.d.ts +0 -3
  138. package/dist/lib/windows/index.js +0 -2
  139. package/dist/lib/windows/inventory.d.ts +0 -21
  140. package/dist/lib/windows/inventory.js +0 -263
  141. package/dist/lib/windows/types.d.ts +0 -46
  142. 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