@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.
- package/bin/dev.js +1 -49
- package/bin/run.js +42 -49
- 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,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
|