ttsd-colabcli 1.0.2 → 1.0.4

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 (3) hide show
  1. package/cli.js +20 -17
  2. package/core/daemon.py +25 -2
  3. package/package.json +1 -1
package/cli.js CHANGED
@@ -2,12 +2,19 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
+ const os = require('os');
5
6
  const { spawn, execSync } = require('child_process');
6
7
 
8
+ const HOME_DIR = path.join(os.homedir(), '.colabcli');
9
+ if (!fs.existsSync(HOME_DIR)) {
10
+ fs.mkdirSync(HOME_DIR, { recursive: true });
11
+ }
12
+
7
13
  const CMD = process.argv[2] || 'start';
8
- const ENV_PATH = path.join(__dirname, '.env');
14
+ const ENV_PATH = path.join(HOME_DIR, '.env');
9
15
  const CORE_DIR = path.join(__dirname, 'core');
10
- const PID_FILE = path.join(__dirname, '.daemon.pid');
16
+ const PID_FILE = path.join(HOME_DIR, '.daemon.pid');
17
+ const VENV_DIR = path.join(HOME_DIR, 'venv');
11
18
 
12
19
  async function promptConfig() {
13
20
  const inquirer = require('inquirer');
@@ -35,21 +42,20 @@ async function promptConfig() {
35
42
  }
36
43
 
37
44
  function setupPythonEnv() {
38
- const venvDir = path.join(CORE_DIR, 'venv');
39
- if (!fs.existsSync(venvDir)) {
45
+ if (!fs.existsSync(VENV_DIR)) {
40
46
  console.log('Creating Python virtual environment...');
41
47
  try {
42
- execSync(`python3 -m venv "${venvDir}"`, { stdio: 'inherit' });
48
+ execSync(`python3 -m venv "${VENV_DIR}"`, { stdio: 'inherit' });
43
49
  } catch (e) {
44
50
  console.log('python3 not found, trying python...');
45
- execSync(`python -m venv "${venvDir}"`, { stdio: 'inherit' });
51
+ execSync(`python -m venv "${VENV_DIR}"`, { stdio: 'inherit' });
46
52
  }
47
53
  }
48
54
 
49
55
  console.log('Installing dependencies...');
50
56
  const pip = process.platform === 'win32'
51
- ? path.join(venvDir, 'Scripts', 'pip')
52
- : path.join(venvDir, 'bin', 'pip');
57
+ ? path.join(VENV_DIR, 'Scripts', 'pip')
58
+ : path.join(VENV_DIR, 'bin', 'pip');
53
59
  execSync(`"${pip}" install -r "${path.join(CORE_DIR, 'requirements.txt')}" -q`, { stdio: 'inherit' });
54
60
  }
55
61
 
@@ -75,17 +81,14 @@ async function start() {
75
81
  console.log('Starting Satellite Daemon in background...');
76
82
 
77
83
  const pythonBin = process.platform === 'win32'
78
- ? path.join(CORE_DIR, 'venv', 'Scripts', 'python')
79
- : path.join(CORE_DIR, 'venv', 'bin', 'python');
80
-
81
- // Copy .env to core dir so daemon.py can load it
82
- fs.copyFileSync(ENV_PATH, path.join(CORE_DIR, '.env'));
84
+ ? path.join(VENV_DIR, 'Scripts', 'python')
85
+ : path.join(VENV_DIR, 'bin', 'python');
83
86
 
84
- const out = fs.openSync(path.join(__dirname, 'daemon.log'), 'a');
85
- const err = fs.openSync(path.join(__dirname, 'daemon.error.log'), 'a');
87
+ const out = fs.openSync(path.join(HOME_DIR, 'daemon.log'), 'a');
88
+ const err = fs.openSync(path.join(HOME_DIR, 'daemon.error.log'), 'a');
86
89
 
87
- const child = spawn(pythonBin, ['daemon.py'], {
88
- cwd: CORE_DIR,
90
+ const child = spawn(pythonBin, [path.join(CORE_DIR, 'daemon.py')], {
91
+ cwd: HOME_DIR,
89
92
  detached: true,
90
93
  stdio: ['ignore', out, err]
91
94
  });
package/core/daemon.py CHANGED
@@ -106,7 +106,19 @@ async def launch_worker(email: str, public_url: str):
106
106
 
107
107
  try:
108
108
  from app.colab_cli.runtime import ColabRuntime
109
- _worker_bytes = open(os.path.join(os.path.dirname(__file__), "../colab/worker.py"), "rb").read()
109
+ # Try local first (satellite_node/daemon.py), fallback to packaged structure
110
+ possible_paths = [
111
+ os.path.join(os.path.dirname(__file__), "../colab/worker.py"),
112
+ os.path.join(os.path.dirname(__file__), "colab", "worker.py")
113
+ ]
114
+ _worker_bytes = None
115
+ for p in possible_paths:
116
+ if os.path.exists(p):
117
+ _worker_bytes = open(p, "rb").read()
118
+ break
119
+ if not _worker_bytes:
120
+ raise FileNotFoundError(f"Could not find worker.py in {possible_paths}")
121
+
110
122
  _worker_b64 = base64.b64encode(_worker_bytes).decode()
111
123
 
112
124
  _rt = ColabRuntime(url, token, session_name=name)
@@ -133,7 +145,18 @@ print("DEPLOYED PID=" + str(proc.pid) + " ALIVE=" + str(ret is None), flush=True
133
145
  await loop.run_in_executor(None, lambda: _rt.execute_code(_deploy_code, timeout=300))
134
146
  logger.info("Worker deployed on Colab runtime for %s", email)
135
147
  except Exception as e:
136
- logger.error("Worker deploy failed: %s", e)
148
+ logger.error("Worker deploy failed: %s, cleaning up Colab assignment", e)
149
+ # Rollback: unassign the runtime so quota isn't wasted
150
+ try:
151
+ from app.colab_cli.common import kill_process
152
+ if pid:
153
+ kill_process(pid)
154
+ except Exception:
155
+ pass
156
+ try:
157
+ await loop.run_in_executor(None, _client.unassign, endpoint)
158
+ except Exception:
159
+ pass
137
160
  await report_status(email, "FAILED", error=str(e))
138
161
  return
139
162
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ttsd-colabcli",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Satellite Node CLI for TTS Dubbing Distributed Architecture",
5
5
  "main": "cli.js",
6
6
  "bin": {