@creativeintelligence/abbie 0.1.6 → 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 (141) hide show
  1. package/bin/dev.js +1 -49
  2. package/bin/run.js +42 -49
  3. package/dist/cli/commands/project/add.d.ts +0 -1
  4. package/dist/cli/commands/project/add.js +16 -52
  5. package/dist/cli/commands/project/list.js +13 -93
  6. package/dist/cli/commands/project/remove.d.ts +0 -2
  7. package/dist/cli/commands/project/remove.js +11 -28
  8. package/dist/cli/commands/session/list.js +3 -12
  9. package/dist/cli/commands/session/mark-done.js +1 -7
  10. package/dist/cli/commands/session/start.d.ts +0 -1
  11. package/dist/cli/commands/session/start.js +5 -7
  12. package/dist/lib/active-sessions.d.ts +0 -12
  13. package/dist/lib/active-sessions.js +6 -175
  14. package/dist/lib/project-path.d.ts +6 -0
  15. package/dist/lib/project-path.js +21 -0
  16. package/dist/lib.d.ts +1 -2
  17. package/dist/lib.js +2 -4
  18. package/oclif.manifest.json +2569 -6368
  19. package/package.json +1 -1
  20. package/dist/cli/commands/backlog/add.d.ts +0 -22
  21. package/dist/cli/commands/backlog/add.js +0 -65
  22. package/dist/cli/commands/backlog/claim.d.ts +0 -19
  23. package/dist/cli/commands/backlog/claim.js +0 -45
  24. package/dist/cli/commands/backlog/complete.d.ts +0 -18
  25. package/dist/cli/commands/backlog/complete.js +0 -42
  26. package/dist/cli/commands/backlog/list.d.ts +0 -20
  27. package/dist/cli/commands/backlog/list.js +0 -91
  28. package/dist/cli/commands/backlog/pick.d.ts +0 -18
  29. package/dist/cli/commands/backlog/pick.js +0 -42
  30. package/dist/cli/commands/backlog/sync.d.ts +0 -24
  31. package/dist/cli/commands/backlog/sync.js +0 -109
  32. package/dist/cli/commands/daemon.d.ts +0 -56
  33. package/dist/cli/commands/daemon.js +0 -1465
  34. package/dist/cli/commands/docs/lint.d.ts +0 -18
  35. package/dist/cli/commands/docs/lint.js +0 -82
  36. package/dist/cli/commands/docs/sync.d.ts +0 -19
  37. package/dist/cli/commands/docs/sync.js +0 -76
  38. package/dist/cli/commands/gc.d.ts +0 -29
  39. package/dist/cli/commands/gc.js +0 -211
  40. package/dist/cli/commands/index.d.ts +0 -36
  41. package/dist/cli/commands/index.js +0 -228
  42. package/dist/cli/commands/panes/broker.d.ts +0 -17
  43. package/dist/cli/commands/panes/broker.js +0 -57
  44. package/dist/cli/commands/panes/pipe-sink.d.ts +0 -17
  45. package/dist/cli/commands/panes/pipe-sink.js +0 -90
  46. package/dist/cli/commands/panes/snapshot.d.ts +0 -20
  47. package/dist/cli/commands/panes/snapshot.js +0 -125
  48. package/dist/cli/commands/preview/init.d.ts +0 -25
  49. package/dist/cli/commands/preview/init.js +0 -159
  50. package/dist/cli/commands/preview/sync.d.ts +0 -23
  51. package/dist/cli/commands/preview/sync.js +0 -144
  52. package/dist/cli/commands/preview/watch.d.ts +0 -24
  53. package/dist/cli/commands/preview/watch.js +0 -153
  54. package/dist/cli/commands/resource/acquire.d.ts +0 -21
  55. package/dist/cli/commands/resource/acquire.js +0 -90
  56. package/dist/cli/commands/resource/list.d.ts +0 -15
  57. package/dist/cli/commands/resource/list.js +0 -61
  58. package/dist/cli/commands/resource/release.d.ts +0 -18
  59. package/dist/cli/commands/resource/release.js +0 -50
  60. package/dist/cli/commands/resource/wait.d.ts +0 -21
  61. package/dist/cli/commands/resource/wait.js +0 -73
  62. package/dist/cli/commands/session/view.d.ts +0 -24
  63. package/dist/cli/commands/session/view.js +0 -145
  64. package/dist/cli/commands/start.d.ts +0 -37
  65. package/dist/cli/commands/start.js +0 -234
  66. package/dist/cli/commands/triage/claim.d.ts +0 -23
  67. package/dist/cli/commands/triage/claim.js +0 -186
  68. package/dist/cli/commands/triage/list.d.ts +0 -22
  69. package/dist/cli/commands/triage/list.js +0 -112
  70. package/dist/cli/commands/triage/next.d.ts +0 -18
  71. package/dist/cli/commands/triage/next.js +0 -63
  72. package/dist/cli/commands/triage/pull.d.ts +0 -19
  73. package/dist/cli/commands/triage/pull.js +0 -82
  74. package/dist/cli/commands/triage/stats.d.ts +0 -16
  75. package/dist/cli/commands/triage/stats.js +0 -69
  76. package/dist/cli/commands/tunnel/list.d.ts +0 -16
  77. package/dist/cli/commands/tunnel/list.js +0 -98
  78. package/dist/cli/commands/tunnel/start.d.ts +0 -24
  79. package/dist/cli/commands/tunnel/start.js +0 -107
  80. package/dist/cli/commands/tunnel/stop.d.ts +0 -20
  81. package/dist/cli/commands/tunnel/stop.js +0 -90
  82. package/dist/cli/commands/tunnel/url.d.ts +0 -21
  83. package/dist/cli/commands/tunnel/url.js +0 -70
  84. package/dist/cli/commands/windows/context.d.ts +0 -18
  85. package/dist/cli/commands/windows/context.js +0 -326
  86. package/dist/cli/commands/windows/focus.d.ts +0 -17
  87. package/dist/cli/commands/windows/focus.js +0 -103
  88. package/dist/cli/commands/windows/list.d.ts +0 -21
  89. package/dist/cli/commands/windows/list.js +0 -172
  90. package/dist/cli/commands/windows/map.d.ts +0 -17
  91. package/dist/cli/commands/windows/map.js +0 -168
  92. package/dist/cli/commands/windows/read.d.ts +0 -21
  93. package/dist/cli/commands/windows/read.js +0 -241
  94. package/dist/cli/commands/windows/search.d.ts +0 -24
  95. package/dist/cli/commands/windows/search.js +0 -171
  96. package/dist/cli/commands/windows/show.d.ts +0 -19
  97. package/dist/cli/commands/windows/show.js +0 -165
  98. package/dist/cli/commands/windows/watch.d.ts +0 -19
  99. package/dist/cli/commands/windows/watch.js +0 -241
  100. package/dist/lib/managed-session.d.ts +0 -27
  101. package/dist/lib/managed-session.js +0 -105
  102. package/dist/lib/panes/broker.d.ts +0 -130
  103. package/dist/lib/panes/broker.js +0 -97
  104. package/dist/lib/panes/index.d.ts +0 -2
  105. package/dist/lib/panes/index.js +0 -1
  106. package/dist/lib/panes/server.d.ts +0 -17
  107. package/dist/lib/panes/server.js +0 -308
  108. package/dist/lib/preview/manager.d.ts +0 -77
  109. package/dist/lib/preview/manager.js +0 -369
  110. package/dist/lib/preview/schema.d.ts +0 -2
  111. package/dist/lib/preview/schema.js +0 -32
  112. package/dist/lib/preview/sprite.d.ts +0 -85
  113. package/dist/lib/preview/sprite.js +0 -321
  114. package/dist/lib/preview/watcher.d.ts +0 -63
  115. package/dist/lib/preview/watcher.js +0 -185
  116. package/dist/lib/project-identity.d.ts +0 -16
  117. package/dist/lib/project-identity.js +0 -75
  118. package/dist/lib/tmux/bridge.d.ts +0 -133
  119. package/dist/lib/tmux/bridge.js +0 -315
  120. package/dist/lib/tmux/context.d.ts +0 -82
  121. package/dist/lib/tmux/context.js +0 -239
  122. package/dist/lib/tmux/index.d.ts +0 -8
  123. package/dist/lib/tmux/index.js +0 -11
  124. package/dist/lib/tmux/map.d.ts +0 -57
  125. package/dist/lib/tmux/map.js +0 -198
  126. package/dist/lib/tmux/panes.d.ts +0 -27
  127. package/dist/lib/tmux/panes.js +0 -151
  128. package/dist/lib/tmux/redaction.d.ts +0 -57
  129. package/dist/lib/tmux/redaction.js +0 -152
  130. package/dist/lib/web/analytics.d.ts +0 -63
  131. package/dist/lib/web/analytics.js +0 -168
  132. package/dist/lib/web/server.d.ts +0 -26
  133. package/dist/lib/web/server.js +0 -697
  134. package/dist/lib/web/tmux-bridge.d.ts +0 -7
  135. package/dist/lib/web/tmux-bridge.js +0 -7
  136. package/dist/lib/windows/index.d.ts +0 -3
  137. package/dist/lib/windows/index.js +0 -2
  138. package/dist/lib/windows/inventory.d.ts +0 -21
  139. package/dist/lib/windows/inventory.js +0 -263
  140. package/dist/lib/windows/types.d.ts +0 -46
  141. package/dist/lib/windows/types.js +0 -1
@@ -1,159 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { basename, resolve } from "node:path";
3
- import { Args, Flags } from "@oclif/core";
4
- import { detectProject } from "../../../lib/preview/detect.js";
5
- import { PreviewManager } from "../../../lib/preview/manager.js";
6
- import { createSprite, destroySprite, getSpriteUrl, makeUrlPublic, } from "../../../lib/preview/sprite.js";
7
- import { BaseCommand } from "../../base-command.js";
8
- /**
9
- * Initialize a sprite for a project: create sprite, make URL public, register in SQLite
10
- */
11
- export default class PreviewInit extends BaseCommand {
12
- static description = "Initialize a sprite for a project";
13
- static hidden = false;
14
- static examples = [
15
- "<%= config.bin %> preview init",
16
- "<%= config.bin %> preview init --project my-app",
17
- "<%= config.bin %> preview init -p ./path/to/project --force",
18
- "<%= config.bin %> preview init --json",
19
- ];
20
- static args = {
21
- project: Args.string({
22
- description: "Project name (optional, defaults to basename of project path)",
23
- }),
24
- };
25
- static flags = {
26
- ...BaseCommand.baseFlags,
27
- project: Flags.string({
28
- char: "p",
29
- description: "Project path (defaults to current directory)",
30
- }),
31
- "dev-command": Flags.string({
32
- char: "c",
33
- description: "Dev command to run (default: bun run dev)",
34
- default: "bun run dev",
35
- }),
36
- port: Flags.integer({
37
- description: "Port the dev server runs on (default: 8080)",
38
- default: 8080,
39
- }),
40
- "doppler-project": Flags.string({
41
- char: "d",
42
- description: "Doppler project for secrets",
43
- }),
44
- force: Flags.boolean({
45
- char: "f",
46
- description: "Force recreate sprite even if it exists",
47
- default: false,
48
- }),
49
- };
50
- async execute() {
51
- const { args, flags } = await this.parse(PreviewInit);
52
- this.parsedFlags = flags;
53
- const manager = new PreviewManager();
54
- const isJson = flags.json || flags.format === "json";
55
- let projectPath;
56
- let projectName;
57
- // Support custom project names:
58
- // abbie preview init <name> -p <path>
59
- const hasNameAndPath = Boolean(args.project && flags.project);
60
- if (hasNameAndPath) {
61
- projectName = args.project;
62
- projectPath = resolve(flags.project);
63
- }
64
- else {
65
- // Resolve project path and name (name may be derived from path basename)
66
- const projectInput = flags.project || args.project || process.cwd();
67
- const existingSprite = manager.getSprite(projectInput);
68
- if (existingSprite) {
69
- projectPath = existingSprite.project_path;
70
- projectName = existingSprite.project_name;
71
- }
72
- else {
73
- projectPath = resolve(projectInput);
74
- projectName = basename(projectPath);
75
- }
76
- }
77
- if (!existsSync(projectPath)) {
78
- this.error(`Project path does not exist: ${projectPath}`);
79
- }
80
- // Check if sprite already exists
81
- const existingSprite = manager.getSprite(projectName);
82
- if (existingSprite && !flags.force) {
83
- if (isJson) {
84
- return {
85
- success: true,
86
- already_exists: true,
87
- sprite: existingSprite,
88
- };
89
- }
90
- this.logInfo(`Sprite already exists for ${projectName}: ${existingSprite.sprite_name}`);
91
- this.logInfo(`Use --force to recreate`);
92
- return { success: true, already_exists: true, sprite: existingSprite };
93
- }
94
- // Delete existing if forcing
95
- if (existingSprite && flags.force) {
96
- this.logInfo(`Deleting existing sprite ${existingSprite.sprite_name}...`);
97
- await destroySprite(existingSprite.sprite_name);
98
- manager.deleteSprite(projectName);
99
- }
100
- // Auto-detect project type and dev command
101
- const projectInfo = detectProject(projectPath);
102
- const devCommand = flags["dev-command"] !== "bun run dev"
103
- ? flags["dev-command"] // User override
104
- : projectInfo.devCommand; // Auto-detected
105
- if (projectInfo.type === "monorepo") {
106
- this.logInfo(`Detected ${projectInfo.packageManager} monorepo (${projectInfo.appDir})`);
107
- }
108
- const spriteName = `preview-${projectName}`;
109
- this.logInfo(`Creating sprite ${spriteName}...`);
110
- // Create sprite via sprite CLI
111
- const createResult = await createSprite(spriteName);
112
- if (!createResult.success) {
113
- this.error(`Failed to create sprite: ${createResult.error}`);
114
- }
115
- // Make URL public
116
- this.logInfo(`Making URL public...`);
117
- await makeUrlPublic(spriteName);
118
- // Get the sprite URL
119
- const spriteUrl = await getSpriteUrl(spriteName);
120
- if (!spriteUrl) {
121
- this.logWarn("Failed to get public URL, sprite may not be accessible");
122
- }
123
- // Register in database
124
- const sprite = manager.registerSprite(projectName, projectPath, spriteName, {
125
- spriteUrl: spriteUrl ?? undefined,
126
- dopplerProject: flags["doppler-project"],
127
- devCommand,
128
- port: flags.port,
129
- });
130
- const result = {
131
- success: true,
132
- project: projectName,
133
- project_path: projectPath,
134
- sprite_name: spriteName,
135
- sprite_url: spriteUrl,
136
- port: flags.port,
137
- dev_command: devCommand,
138
- project_type: projectInfo.type,
139
- package_manager: projectInfo.packageManager,
140
- app_dir: projectInfo.appDir,
141
- doppler_project: flags["doppler-project"],
142
- sprite_id: sprite.id,
143
- };
144
- if (isJson) {
145
- return result;
146
- }
147
- this.log("");
148
- this.log(`✓ Initialized sprite: ${spriteName}`);
149
- this.log(` URL: ${spriteUrl || "Not available"}`);
150
- this.log(` Port: ${flags.port}`);
151
- this.log(` Dev command: ${flags["dev-command"]}`);
152
- if (flags["doppler-project"]) {
153
- this.log(` Doppler: ${flags["doppler-project"]}`);
154
- }
155
- this.log("");
156
- this.log(`Next: abbie preview sync ${projectName}`);
157
- return result;
158
- }
159
- }
@@ -1,23 +0,0 @@
1
- import { BaseCommand } from "../../base-command.js";
2
- /**
3
- * Sync project files to sprite: tar project, upload to sprite, optionally install deps
4
- */
5
- export default class PreviewSync 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
- "no-install": import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
- "npm-token": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
- format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
- quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
- "json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
- ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
- };
21
- protected execute(): Promise<unknown>;
22
- }
23
- //# sourceMappingURL=sync.d.ts.map
@@ -1,144 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { basename, resolve } from "node:path";
3
- import { Args, Flags } from "@oclif/core";
4
- import { detectProject, getInstallCommand } from "../../../lib/preview/detect.js";
5
- import { PreviewManager } from "../../../lib/preview/manager.js";
6
- import { execOnSprite, syncToSprite } from "../../../lib/preview/sprite.js";
7
- import { BaseCommand } from "../../base-command.js";
8
- /**
9
- * Sync project files to sprite: tar project, upload to sprite, optionally install deps
10
- */
11
- export default class PreviewSync extends BaseCommand {
12
- static description = "Sync project files to sprite and install dependencies";
13
- static hidden = false;
14
- static examples = [
15
- "<%= config.bin %> preview sync",
16
- "<%= config.bin %> preview sync --project my-app",
17
- "<%= config.bin %> preview sync -p ./path/to/project --no-install",
18
- "<%= config.bin %> preview sync --json",
19
- ];
20
- static args = {
21
- project: Args.string({
22
- description: "Project name or path (defaults to current directory)",
23
- }),
24
- };
25
- static flags = {
26
- ...BaseCommand.baseFlags,
27
- project: Flags.string({
28
- char: "p",
29
- description: "Project name or path",
30
- }),
31
- "no-install": Flags.boolean({
32
- description: "Skip npm install after sync",
33
- default: false,
34
- }),
35
- "npm-token": Flags.string({
36
- description: "NPM token for private packages (or set NPM_TOKEN env)",
37
- env: "NPM_TOKEN",
38
- }),
39
- };
40
- async execute() {
41
- const { args, flags } = await this.parse(PreviewSync);
42
- this.parsedFlags = flags;
43
- const manager = new PreviewManager();
44
- const isJson = flags.json || flags.format === "json";
45
- // Resolve project path and name
46
- const projectInput = flags.project || args.project || process.cwd();
47
- const existingSprite = manager.getSprite(projectInput);
48
- let projectPath;
49
- let projectName;
50
- if (existingSprite) {
51
- projectPath = existingSprite.project_path;
52
- projectName = existingSprite.project_name;
53
- }
54
- else {
55
- projectPath = resolve(projectInput);
56
- projectName = basename(projectPath);
57
- }
58
- if (!existsSync(projectPath)) {
59
- this.error(`Project path does not exist: ${projectPath}`);
60
- }
61
- // Get sprite from database
62
- const sprite = existingSprite ?? manager.getSprite(projectName);
63
- if (!sprite) {
64
- this.error(`No sprite found for ${projectName}. Run 'abbie preview init' first.`);
65
- }
66
- // Record deployment start
67
- const deployment = manager.recordDeployment(sprite.id, "syncing");
68
- // Step 1: Sync project files
69
- this.logInfo(`Syncing ${projectName} to ${sprite.sprite_name}...`);
70
- const syncResult = await syncToSprite(sprite.sprite_name, projectPath, "/app");
71
- if (!syncResult.success) {
72
- manager.updateDeployment(deployment.id, {
73
- status: "failed",
74
- error: `Sync failed: ${syncResult.error}`,
75
- syncDurationMs: syncResult.syncDurationMs,
76
- });
77
- this.error(`Failed to sync: ${syncResult.error}`);
78
- }
79
- manager.updateDeployment(deployment.id, {
80
- status: "installing",
81
- syncDurationMs: syncResult.syncDurationMs,
82
- });
83
- // Step 2: Install dependencies (unless skipped)
84
- let installDuration = 0;
85
- if (!flags["no-install"]) {
86
- // Auto-detect package manager
87
- const projectInfo = detectProject(projectPath);
88
- this.logInfo(`Installing dependencies (${projectInfo.packageManager})...`);
89
- const installStart = Date.now();
90
- // Build install command based on detected package manager
91
- let installCmd = getInstallCommand(projectInfo.packageManager);
92
- const env = {};
93
- // Add NPM_TOKEN for private packages
94
- const npmToken = flags["npm-token"];
95
- if (npmToken) {
96
- env.NPM_TOKEN = npmToken;
97
- }
98
- if (sprite.doppler_project) {
99
- installCmd = `doppler run -p ${sprite.doppler_project} -c dev -- ${installCmd}`;
100
- }
101
- const installResult = await execOnSprite(sprite.sprite_name, installCmd, {
102
- dir: "/app",
103
- env,
104
- });
105
- installDuration = Date.now() - installStart;
106
- if (!installResult.success) {
107
- manager.updateDeployment(deployment.id, {
108
- status: "failed",
109
- error: `Install failed: ${installResult.error}`,
110
- installDurationMs: installDuration,
111
- });
112
- this.error(`Failed to install dependencies: ${installResult.error}`);
113
- }
114
- }
115
- manager.updateDeployment(deployment.id, {
116
- status: "stopped",
117
- installDurationMs: installDuration,
118
- });
119
- const result = {
120
- success: true,
121
- project: projectName,
122
- sprite: sprite.sprite_name,
123
- deployment_id: deployment.id,
124
- timings: {
125
- sync_ms: syncResult.syncDurationMs || 0,
126
- install_ms: installDuration,
127
- total_ms: (syncResult.syncDurationMs || 0) + installDuration,
128
- },
129
- };
130
- if (isJson) {
131
- return result;
132
- }
133
- this.log("");
134
- this.log(`✓ Synced ${projectName} to ${sprite.sprite_name}`);
135
- this.log(` Sync: ${((syncResult.syncDurationMs || 0) / 1000).toFixed(1)}s`);
136
- if (!flags["no-install"]) {
137
- this.log(` Install: ${(installDuration / 1000).toFixed(1)}s`);
138
- }
139
- this.log(` Total: ${(result.timings.total_ms / 1000).toFixed(1)}s`);
140
- this.log("");
141
- this.log(`Next: abbie preview (to start server)`);
142
- return result;
143
- }
144
- }
@@ -1,24 +0,0 @@
1
- import { BaseCommand } from "../../base-command.js";
2
- /**
3
- * Watch project files and auto-sync changes to sprite.
4
- */
5
- export default class PreviewWatch 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
- debounce: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
15
- "no-install": import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
- "npm-token": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
- format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
- quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
- "json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
- ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
21
- };
22
- protected execute(): Promise<unknown>;
23
- }
24
- //# sourceMappingURL=watch.d.ts.map
@@ -1,153 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { basename, resolve } from "node:path";
3
- import { Args, Flags } from "@oclif/core";
4
- import { detectProject } from "../../../lib/preview/detect.js";
5
- import { PreviewManager } from "../../../lib/preview/manager.js";
6
- import { isProcessRunning } from "../../../lib/preview/sprite.js";
7
- import { startWatcher } from "../../../lib/preview/watcher.js";
8
- import { BaseCommand } from "../../base-command.js";
9
- /**
10
- * Watch project files and auto-sync changes to sprite.
11
- */
12
- export default class PreviewWatch extends BaseCommand {
13
- static description = "Watch project files and auto-sync to sprite";
14
- static hidden = false;
15
- static examples = [
16
- "<%= config.bin %> preview watch",
17
- "<%= config.bin %> preview watch --project my-app",
18
- "<%= config.bin %> preview watch --debounce 2000",
19
- "<%= config.bin %> preview watch --no-install",
20
- "<%= config.bin %> preview watch --json",
21
- ];
22
- static args = {
23
- project: Args.string({
24
- description: "Project name or path (defaults to current directory)",
25
- }),
26
- };
27
- static flags = {
28
- ...BaseCommand.baseFlags,
29
- project: Flags.string({
30
- char: "p",
31
- description: "Project name or path",
32
- }),
33
- debounce: Flags.integer({
34
- description: "Debounce delay in milliseconds",
35
- default: 1500,
36
- }),
37
- "no-install": Flags.boolean({
38
- description: "Skip auto-install when lockfiles change",
39
- default: false,
40
- }),
41
- "npm-token": Flags.string({
42
- description: "NPM token for private packages (or set NPM_TOKEN env)",
43
- env: "NPM_TOKEN",
44
- }),
45
- };
46
- async execute() {
47
- const { args, flags } = await this.parse(PreviewWatch);
48
- this.parsedFlags = flags;
49
- const manager = new PreviewManager();
50
- const isJson = flags.json || flags.format === "json";
51
- const isTTY = process.stdout.isTTY ?? false;
52
- // Resolve project path and name (same pattern as sync.ts)
53
- const projectInput = flags.project || args.project || process.cwd();
54
- const existingSprite = manager.getSprite(projectInput);
55
- let projectPath;
56
- let projectName;
57
- if (existingSprite) {
58
- projectPath = existingSprite.project_path;
59
- projectName = existingSprite.project_name;
60
- }
61
- else {
62
- projectPath = resolve(projectInput);
63
- projectName = basename(projectPath);
64
- }
65
- if (!existsSync(projectPath)) {
66
- this.error(`Project path does not exist: ${projectPath}`);
67
- }
68
- // Get sprite from database
69
- const sprite = existingSprite ?? manager.getSprite(projectName);
70
- if (!sprite) {
71
- this.error(`No sprite found for ${projectName}. Run 'abbie preview init' first.`);
72
- }
73
- // Detect project type
74
- const projectInfo = detectProject(projectPath);
75
- // Check if dev server is running
76
- const serverRunning = await isProcessRunning(sprite.sprite_name, "next dev|bun run dev|node.*dev");
77
- if (!serverRunning) {
78
- this.logWarn("Dev server not detected on sprite. Run 'abbie preview' to start it.");
79
- }
80
- // Wire shutdown
81
- const controller = new AbortController();
82
- const onSignal = () => controller.abort();
83
- process.on("SIGINT", onSignal);
84
- process.on("SIGTERM", onSignal);
85
- // Start watcher
86
- const watcher = startWatcher({
87
- projectPath,
88
- spriteName: sprite.sprite_name,
89
- debounceMs: flags.debounce,
90
- autoInstall: !flags["no-install"],
91
- packageManager: projectInfo.packageManager,
92
- dopplerProject: sprite.doppler_project ?? undefined,
93
- npmToken: flags["npm-token"],
94
- signal: controller.signal,
95
- }, (event) => {
96
- if (isJson) {
97
- // Write directly to stdout — oclif's --json flag suppresses this.log()
98
- process.stdout.write(`${JSON.stringify({ ...event, timestamp: new Date().toISOString() })}\n`);
99
- return;
100
- }
101
- if (flags.quiet && event.type !== "sync_error")
102
- return;
103
- switch (event.type) {
104
- case "started":
105
- this.log(`Watching ${projectName} -> ${sprite.sprite_name}`);
106
- this.log(`Debounce: ${flags.debounce}ms | Auto-install: ${!flags["no-install"]} | ${projectInfo.packageManager}`);
107
- this.log("Press Ctrl+C to stop\n");
108
- break;
109
- case "sync_start": {
110
- const msg = `[syncing] ${event.fileCount} file(s) changed${event.needsInstall ? " (+install)" : ""}...`;
111
- if (isTTY) {
112
- process.stdout.write(`\r${msg}`);
113
- }
114
- else {
115
- this.log(msg);
116
- }
117
- break;
118
- }
119
- case "sync_complete": {
120
- const s = watcher.stats();
121
- const installNote = event.installMs > 0 ? ` (install: ${(event.installMs / 1000).toFixed(1)}s)` : "";
122
- const line = `[watching] synced in ${(event.totalMs / 1000).toFixed(1)}s${installNote} | syncs: ${s.totalSyncs}`;
123
- if (isTTY) {
124
- process.stdout.write(`\r${line}${" ".repeat(20)}\n`);
125
- }
126
- else {
127
- this.log(line);
128
- }
129
- break;
130
- }
131
- case "sync_error":
132
- this.logWarn(`[error] ${event.error}`);
133
- break;
134
- case "stopped": {
135
- const finalStats = watcher.stats();
136
- this.log(`\nWatch stopped. ${finalStats.totalSyncs} sync(s) completed.`);
137
- break;
138
- }
139
- }
140
- });
141
- // Block until shutdown
142
- await watcher.done;
143
- process.off("SIGINT", onSignal);
144
- process.off("SIGTERM", onSignal);
145
- const finalStats = watcher.stats();
146
- return {
147
- success: true,
148
- project: projectName,
149
- sprite: sprite.sprite_name,
150
- stats: finalStats,
151
- };
152
- }
153
- }
@@ -1,21 +0,0 @@
1
- import { BaseCommand } from "../../base-command.js";
2
- export default class ResourceAcquire extends BaseCommand {
3
- static description: string;
4
- static hidden: boolean;
5
- static examples: string[];
6
- static args: {
7
- resource: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
8
- session_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
9
- };
10
- static flags: {
11
- agent: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
- ttl: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
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
- private getExpiresIn;
20
- }
21
- //# sourceMappingURL=acquire.d.ts.map
@@ -1,90 +0,0 @@
1
- import { Args, Flags } from "@oclif/core";
2
- import { createEvent, EventStore } from "../../../lib/events.js";
3
- import { createResourceManager, DEFAULT_RESOURCES } from "../../../lib/resources.js";
4
- import { AGENTS } from "../../../lib/types.js";
5
- import { BaseCommand } from "../../base-command.js";
6
- export default class ResourceAcquire extends BaseCommand {
7
- static description = "Acquire a resource lease";
8
- static hidden = false;
9
- static examples = [
10
- "<%= config.bin %> resource acquire codex_api SESSION_ID --agent claude",
11
- "<%= config.bin %> resource acquire ngrok_tunnel SESSION_ID --agent codex --ttl 3600000",
12
- "<%= config.bin %> resource acquire codex_api SESSION_ID --agent claude --json",
13
- ];
14
- static args = {
15
- resource: Args.string({
16
- description: "Resource name (codex_api, cursor_agent, ngrok_tunnel, linear_api, slack_api)",
17
- required: true,
18
- options: Object.keys(DEFAULT_RESOURCES),
19
- }),
20
- session_id: Args.string({
21
- description: "Session ID requesting the resource",
22
- required: true,
23
- }),
24
- };
25
- static flags = {
26
- ...BaseCommand.baseFlags,
27
- agent: Flags.string({
28
- char: "a",
29
- description: "Agent type",
30
- required: true,
31
- options: [...AGENTS],
32
- }),
33
- ttl: Flags.integer({
34
- char: "t",
35
- description: "Time-to-live in milliseconds",
36
- }),
37
- };
38
- async execute() {
39
- const { args, flags } = await this.parse(ResourceAcquire);
40
- this.parsedFlags = flags;
41
- const resources = createResourceManager();
42
- const events = new EventStore();
43
- const lease = resources.acquire(args.resource, args.session_id, flags.agent, flags.ttl);
44
- if (!lease) {
45
- const availability = resources.getAvailability(args.resource);
46
- if (flags.json || flags.format === "json") {
47
- return {
48
- success: false,
49
- reason: "No slots available",
50
- availability,
51
- };
52
- }
53
- this.logInfo(`No ${args.resource} slots available (${availability.available}/${availability.total})`);
54
- if (availability.leases.length > 0) {
55
- this.log("\nActive leases:");
56
- for (const l of availability.leases) {
57
- const expiresIn = this.getExpiresIn(l.expires_at);
58
- this.log(` ${l.session_id} (${l.agent}) - expires ${expiresIn}`);
59
- }
60
- }
61
- return { success: false };
62
- }
63
- // Emit resource acquired event
64
- events.append(createEvent.resourceAcquired(args.session_id, flags.agent, {
65
- resource: args.resource,
66
- lease_id: lease.lease_id,
67
- expires_at: lease.expires_at,
68
- }));
69
- if (flags.json || flags.format === "json") {
70
- return { success: true, lease };
71
- }
72
- this.log(lease.lease_id);
73
- return { success: true, lease };
74
- }
75
- getExpiresIn(expiresAt) {
76
- const ms = new Date(expiresAt).getTime() - Date.now();
77
- if (ms < 0)
78
- return "expired";
79
- const seconds = Math.floor(ms / 1000);
80
- const minutes = Math.floor(seconds / 60);
81
- const hours = Math.floor(minutes / 60);
82
- if (hours > 0) {
83
- return `in ${hours}h ${minutes % 60}m`;
84
- }
85
- if (minutes > 0) {
86
- return `in ${minutes}m`;
87
- }
88
- return `in ${seconds}s`;
89
- }
90
- }
@@ -1,15 +0,0 @@
1
- import { BaseCommand } from "../../base-command.js";
2
- export default class ResourceList extends BaseCommand {
3
- static description: string;
4
- static hidden: boolean;
5
- static examples: string[];
6
- static flags: {
7
- format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
- quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- "json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
- };
12
- protected execute(): Promise<unknown>;
13
- private getExpiresIn;
14
- }
15
- //# sourceMappingURL=list.d.ts.map