@parall/daemon 1.31.0 → 1.32.0

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 (52) hide show
  1. package/bundle/manifest.json +16 -11
  2. package/bundle/package.json +1 -0
  3. package/bundle/parall-claude-agent.js +27556 -339
  4. package/bundle/parall-codex-agent.js +27603 -372
  5. package/bundle/parall-daemon.js +30204 -1760
  6. package/bundle/parall-openclaw-agent.js +49 -24
  7. package/dist/cli.d.ts +1 -1
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +83 -83
  10. package/dist/clip-runtime/clip-installer.d.ts +44 -0
  11. package/dist/clip-runtime/clip-installer.d.ts.map +1 -0
  12. package/dist/clip-runtime/clip-installer.js +501 -0
  13. package/dist/clip-runtime/clip-provider.d.ts +76 -0
  14. package/dist/clip-runtime/clip-provider.d.ts.map +1 -0
  15. package/dist/clip-runtime/clip-provider.js +402 -0
  16. package/dist/clip-runtime/index.d.ts +7 -0
  17. package/dist/clip-runtime/index.d.ts.map +1 -0
  18. package/dist/clip-runtime/index.js +5 -0
  19. package/dist/clip-runtime/ipc.d.ts +94 -0
  20. package/dist/clip-runtime/ipc.d.ts.map +1 -0
  21. package/dist/clip-runtime/ipc.js +98 -0
  22. package/dist/clip-runtime/manifest.d.ts +74 -0
  23. package/dist/clip-runtime/manifest.d.ts.map +1 -0
  24. package/dist/clip-runtime/manifest.js +181 -0
  25. package/dist/clip-runtime/process-manager.d.ts +57 -0
  26. package/dist/clip-runtime/process-manager.d.ts.map +1 -0
  27. package/dist/clip-runtime/process-manager.js +354 -0
  28. package/dist/clip-runtime/process.d.ts +59 -0
  29. package/dist/clip-runtime/process.d.ts.map +1 -0
  30. package/dist/clip-runtime/process.js +350 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +24 -24
  33. package/dist/filesystem.d.ts +1 -1
  34. package/dist/filesystem.d.ts.map +1 -1
  35. package/dist/filesystem.js +51 -53
  36. package/dist/index.js +20 -15
  37. package/dist/runtimes.d.ts +3 -2
  38. package/dist/runtimes.d.ts.map +1 -1
  39. package/dist/runtimes.js +24 -20
  40. package/dist/supervisor.d.ts +9 -4
  41. package/dist/supervisor.d.ts.map +1 -1
  42. package/dist/supervisor.js +244 -76
  43. package/dist/updater-manifest.d.ts +2 -0
  44. package/dist/updater-manifest.d.ts.map +1 -1
  45. package/dist/updater-manifest.js +6 -6
  46. package/dist/updater.d.ts +2 -2
  47. package/dist/updater.d.ts.map +1 -1
  48. package/dist/updater.js +55 -37
  49. package/dist/workspace.d.ts +2 -2
  50. package/dist/workspace.d.ts.map +1 -1
  51. package/dist/workspace.js +112 -112
  52. package/package.json +6 -6
@@ -37,13 +37,7 @@ if (fs.existsSync(pluginArchive)) {
37
37
  fs.rmSync(legacyExtDir, { recursive: true, force: true });
38
38
  log.info(`Installing Parall plugin from ${pluginArchive}...`);
39
39
  try {
40
- execFileSync("openclaw", [
41
- "plugins",
42
- "install",
43
- pluginArchive,
44
- "--force",
45
- "--dangerously-force-unsafe-install"
46
- ], {
40
+ execFileSync("openclaw", ["plugins", "install", pluginArchive, "--force", "--dangerously-force-unsafe-install"], {
47
41
  env: { ...process.env, OPENCLAW_STATE_DIR: openclawStateDir },
48
42
  stdio: "inherit",
49
43
  timeout: 6e4
@@ -136,39 +130,70 @@ async function preseedPlatformConfig() {
136
130
  }
137
131
  const ALLOWED_DEFAULTS = /* @__PURE__ */ new Set(["model", "compaction", "memorySearch"]);
138
132
  const platformDefaults = pc.agents?.defaults;
133
+ const agents = cfg.agents && typeof cfg.agents === "object" ? cfg.agents : {};
134
+ const existing = agents.defaults && typeof agents.defaults === "object" ? agents.defaults : {};
135
+ const hadModel = "model" in existing;
136
+ delete existing.model;
139
137
  if (platformDefaults && typeof platformDefaults === "object") {
140
- const agents = cfg.agents && typeof cfg.agents === "object" ? cfg.agents : {};
141
- const existing = agents.defaults && typeof agents.defaults === "object" ? agents.defaults : {};
142
138
  for (const [k, v] of Object.entries(platformDefaults)) {
143
139
  if (ALLOWED_DEFAULTS.has(k))
144
140
  existing[k] = v;
145
141
  }
142
+ }
143
+ if (hadModel || platformDefaults && typeof platformDefaults === "object") {
146
144
  agents.defaults = existing;
147
145
  cfg.agents = agents;
148
146
  }
149
147
  const ALLOWED_MODEL_KEYS = /* @__PURE__ */ new Set(["id", "name", "contextWindow", "maxTokens"]);
150
148
  const platformModels = pc.models?.providers;
151
- const platformParall = platformModels?.parall;
152
- if (platformParall && typeof platformParall === "object") {
149
+ if (platformModels && typeof platformModels === "object") {
153
150
  const models = cfg.models && typeof cfg.models === "object" ? cfg.models : {};
154
151
  const providers = models.providers && typeof models.providers === "object" ? models.providers : {};
155
- const existingParall = providers.parall && typeof providers.parall === "object" ? providers.parall : {};
156
- const merged = { ...existingParall, ...platformParall };
157
- if (Array.isArray(merged.models)) {
158
- merged.models = merged.models.filter((m) => m && typeof m === "object").map((m) => {
159
- const clean = {};
160
- for (const [k, v] of Object.entries(m)) {
161
- if (ALLOWED_MODEL_KEYS.has(k))
162
- clean[k] = v;
163
- }
164
- return clean;
165
- });
152
+ for (const providerName of ["parall", "parall-anthropic"]) {
153
+ const platformProvider = platformModels[providerName];
154
+ if (!platformProvider || typeof platformProvider !== "object") {
155
+ if (providerName !== "parall")
156
+ delete providers[providerName];
157
+ continue;
158
+ }
159
+ const existing2 = providers[providerName] && typeof providers[providerName] === "object" ? providers[providerName] : {};
160
+ const merged = { ...existing2, ...platformProvider };
161
+ if (Array.isArray(merged.models)) {
162
+ merged.models = merged.models.filter((m) => m && typeof m === "object").map((m) => {
163
+ const clean = {};
164
+ for (const [k, v] of Object.entries(m)) {
165
+ if (ALLOWED_MODEL_KEYS.has(k))
166
+ clean[k] = v;
167
+ }
168
+ return clean;
169
+ });
170
+ }
171
+ merged.apiKey = PRLL_API_KEY;
172
+ providers[providerName] = merged;
166
173
  }
167
- merged.apiKey = PRLL_API_KEY;
168
- providers.parall = merged;
169
174
  models.providers = providers;
170
175
  cfg.models = models;
171
176
  }
177
+ const agentsCfg = cfg.agents && typeof cfg.agents === "object" ? cfg.agents : {};
178
+ const defaultsCfg = agentsCfg.defaults && typeof agentsCfg.defaults === "object" ? agentsCfg.defaults : {};
179
+ if (typeof defaultsCfg.model === "string") {
180
+ const modelStr = defaultsCfg.model;
181
+ if (platformModels?.["parall-anthropic"]) {
182
+ const fwd = modelStr.match(/^parall\/(anthropic\/.+)$/);
183
+ if (fwd) {
184
+ defaultsCfg.model = `parall-anthropic/${fwd[1]}`;
185
+ agentsCfg.defaults = defaultsCfg;
186
+ cfg.agents = agentsCfg;
187
+ }
188
+ } else {
189
+ const rev = modelStr.match(/^parall-anthropic\/(anthropic\/.+)$/);
190
+ if (rev) {
191
+ defaultsCfg.model = `parall/${rev[1]}`;
192
+ agentsCfg.defaults = defaultsCfg;
193
+ cfg.agents = agentsCfg;
194
+ }
195
+ }
196
+ }
172
197
  const tmp = configPath + ".tmp";
173
198
  fs.writeFileSync(tmp, JSON.stringify(cfg, null, 2));
174
199
  fs.renameSync(tmp, configPath);
package/dist/cli.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare function runCLI(args: string[]): Promise<"run-daemon" | "handled">;
1
+ export declare function runCLI(args: string[]): Promise<'run-daemon' | 'handled'>;
2
2
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAiSA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAuD9E"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA0SA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAuD9E"}
package/dist/cli.js CHANGED
@@ -1,14 +1,14 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import * as os from "node:os";
4
- import * as readline from "node:readline";
5
- import { spawn, execSync } from "node:child_process";
6
- import { daemonConfigDir, daemonConfigPath } from "./config.js";
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import * as readline from 'node:readline';
5
+ import { spawn, execSync } from 'node:child_process';
6
+ import { daemonConfigDir, daemonConfigPath } from './config.js';
7
7
  const CONFIG_DIR = daemonConfigDir();
8
8
  const CONFIG_PATH = daemonConfigPath();
9
9
  function readConfig() {
10
10
  try {
11
- return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
11
+ return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
12
12
  }
13
13
  catch {
14
14
  return null;
@@ -29,28 +29,28 @@ function prompt(question) {
29
29
  });
30
30
  }
31
31
  function isMacOS() {
32
- return process.platform === "darwin";
32
+ return process.platform === 'darwin';
33
33
  }
34
34
  function isLinux() {
35
- return process.platform === "linux";
35
+ return process.platform === 'linux';
36
36
  }
37
- const PLIST_LABEL = "com.parall.daemon";
37
+ const PLIST_LABEL = 'com.parall.daemon';
38
38
  function plistPath() {
39
- return path.join(os.homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
39
+ return path.join(os.homedir(), 'Library', 'LaunchAgents', `${PLIST_LABEL}.plist`);
40
40
  }
41
41
  function systemdUnitPath() {
42
- return path.join(os.homedir(), ".config", "systemd", "user", "parall-daemon.service");
42
+ return path.join(os.homedir(), '.config', 'systemd', 'user', 'parall-daemon.service');
43
43
  }
44
44
  function getDaemonBin() {
45
45
  try {
46
- return execSync("which parall-daemon", { encoding: "utf-8", stdio: "pipe" }).trim();
46
+ return execSync('which parall-daemon', { encoding: 'utf-8', stdio: 'pipe' }).trim();
47
47
  }
48
48
  catch {
49
- return process.argv[1] ?? "parall-daemon";
49
+ return process.argv[1] ?? 'parall-daemon';
50
50
  }
51
51
  }
52
52
  function generatePlist(daemonBin) {
53
- const logPath = path.join(os.homedir(), "Library", "Logs", "parall-daemon.log");
53
+ const logPath = path.join(os.homedir(), 'Library', 'Logs', 'parall-daemon.log');
54
54
  // Use a shell wrapper so the service manager loads the self-updated overlay
55
55
  // bundle when it exists, falling back to the original npm-installed binary.
56
56
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -98,7 +98,7 @@ WantedBy=default.target`;
98
98
  function installService() {
99
99
  const config = readConfig();
100
100
  if (!config) {
101
- console.error("No config found. Run `parall-daemon init` first.");
101
+ console.error('No config found. Run `parall-daemon init` first.');
102
102
  process.exit(1);
103
103
  }
104
104
  const bin = getDaemonBin();
@@ -114,142 +114,142 @@ function installService() {
114
114
  const dir = path.dirname(systemdUnitPath());
115
115
  fs.mkdirSync(dir, { recursive: true });
116
116
  fs.writeFileSync(systemdUnitPath(), generateSystemdUnit(bin));
117
- execSync("systemctl --user daemon-reload");
118
- execSync("systemctl --user enable --now parall-daemon");
117
+ execSync('systemctl --user daemon-reload');
118
+ execSync('systemctl --user enable --now parall-daemon');
119
119
  console.log(`systemd service installed: ${systemdUnitPath()}`);
120
120
  }
121
121
  else {
122
- console.log("Unsupported platform. Run `parall-daemon` manually.");
122
+ console.log('Unsupported platform. Run `parall-daemon` manually.');
123
123
  }
124
124
  }
125
125
  async function cmdInit() {
126
126
  const existing = readConfig();
127
- const defaultUrl = existing?.api_url || "https://api.parall.com";
127
+ const defaultUrl = existing?.api_url || 'https://api.parall.com';
128
128
  const apiUrl = (await prompt(`API URL [${defaultUrl}]: `)) || defaultUrl;
129
- const apiKey = await prompt("Machine key (mck_...): ");
130
- if (!apiKey.startsWith("mck_")) {
129
+ const apiKey = await prompt('Machine key (mck_...): ');
130
+ if (!apiKey.startsWith('mck_')) {
131
131
  console.error('Error: Machine key must start with "mck_"');
132
132
  process.exit(1);
133
133
  }
134
134
  writeConfig({ api_url: apiUrl, api_key: apiKey });
135
135
  console.log(`Config written to ${CONFIG_PATH}`);
136
- const install = await prompt("Install as background service? (Y/n): ");
137
- if (install.toLowerCase() !== "n") {
136
+ const install = await prompt('Install as background service? (Y/n): ');
137
+ if (install.toLowerCase() !== 'n') {
138
138
  installService();
139
139
  }
140
140
  }
141
141
  function cmdStatus() {
142
142
  const config = readConfig();
143
- console.log(`Config: ${config ? CONFIG_PATH : "not configured"}`);
143
+ console.log(`Config: ${config ? CONFIG_PATH : 'not configured'}`);
144
144
  if (isMacOS()) {
145
145
  try {
146
146
  const output = execSync(`launchctl print gui/$(id -u)/${PLIST_LABEL} 2>&1`, {
147
- encoding: "utf-8",
147
+ encoding: 'utf-8',
148
148
  });
149
- const running = output.includes("state = running");
150
- console.log(`Service: ${running ? "running" : "stopped"}`);
149
+ const running = output.includes('state = running');
150
+ console.log(`Service: ${running ? 'running' : 'stopped'}`);
151
151
  const pidMatch = output.match(/pid\s*=\s*(\d+)/);
152
152
  if (pidMatch)
153
153
  console.log(`PID: ${pidMatch[1]}`);
154
154
  }
155
155
  catch {
156
- console.log("Service: not installed");
156
+ console.log('Service: not installed');
157
157
  }
158
158
  }
159
159
  else if (isLinux()) {
160
160
  try {
161
- execSync("systemctl --user is-active parall-daemon", { encoding: "utf-8", stdio: "pipe" });
162
- console.log("Service: running");
161
+ execSync('systemctl --user is-active parall-daemon', { encoding: 'utf-8', stdio: 'pipe' });
162
+ console.log('Service: running');
163
163
  }
164
164
  catch {
165
- console.log("Service: stopped or not installed");
165
+ console.log('Service: stopped or not installed');
166
166
  }
167
167
  }
168
168
  }
169
169
  function cmdStop() {
170
170
  if (isMacOS()) {
171
171
  execSync(`launchctl bootout gui/$(id -u) ${plistPath()} 2>/dev/null || true`, {
172
- stdio: "inherit",
172
+ stdio: 'inherit',
173
173
  });
174
174
  }
175
175
  else if (isLinux()) {
176
- execSync("systemctl --user stop parall-daemon", { stdio: "inherit" });
176
+ execSync('systemctl --user stop parall-daemon', { stdio: 'inherit' });
177
177
  }
178
- console.log("Daemon stopped.");
178
+ console.log('Daemon stopped.');
179
179
  }
180
180
  function cmdLogs(lines) {
181
181
  if (isLinux()) {
182
- const child = spawn("journalctl", ["--user-unit", "parall-daemon", "-n", lines, "-f"], {
183
- stdio: "inherit",
182
+ const child = spawn('journalctl', ['--user-unit', 'parall-daemon', '-n', lines, '-f'], {
183
+ stdio: 'inherit',
184
184
  });
185
- child.on("exit", (code) => process.exit(code ?? 0));
185
+ child.on('exit', (code) => process.exit(code ?? 0));
186
186
  return;
187
187
  }
188
- const logPath = path.join(os.homedir(), "Library", "Logs", "parall-daemon.log");
188
+ const logPath = path.join(os.homedir(), 'Library', 'Logs', 'parall-daemon.log');
189
189
  if (!fs.existsSync(logPath)) {
190
- console.log("No log file found at", logPath);
190
+ console.log('No log file found at', logPath);
191
191
  return;
192
192
  }
193
- const child = spawn("tail", ["-n", lines, "-f", logPath], { stdio: "inherit" });
194
- child.on("exit", (code) => process.exit(code ?? 0));
193
+ const child = spawn('tail', ['-n', lines, '-f', logPath], { stdio: 'inherit' });
194
+ child.on('exit', (code) => process.exit(code ?? 0));
195
195
  }
196
196
  function cmdServiceUninstall() {
197
197
  if (isMacOS()) {
198
198
  execSync(`launchctl bootout gui/$(id -u) ${plistPath()} 2>/dev/null || true`);
199
199
  if (fs.existsSync(plistPath()))
200
200
  fs.unlinkSync(plistPath());
201
- console.log("launchd agent uninstalled.");
201
+ console.log('launchd agent uninstalled.');
202
202
  }
203
203
  else if (isLinux()) {
204
- execSync("systemctl --user stop parall-daemon 2>/dev/null || true");
205
- execSync("systemctl --user disable parall-daemon 2>/dev/null || true");
204
+ execSync('systemctl --user stop parall-daemon 2>/dev/null || true');
205
+ execSync('systemctl --user disable parall-daemon 2>/dev/null || true');
206
206
  if (fs.existsSync(systemdUnitPath()))
207
207
  fs.unlinkSync(systemdUnitPath());
208
- execSync("systemctl --user daemon-reload");
209
- console.log("systemd service uninstalled.");
208
+ execSync('systemctl --user daemon-reload');
209
+ console.log('systemd service uninstalled.');
210
210
  }
211
211
  else {
212
- console.log("Unsupported platform.");
212
+ console.log('Unsupported platform.');
213
213
  }
214
214
  }
215
215
  async function cmdUpdate(checkOnly) {
216
- const { resolveClaudeDaemonConfig, resolveBundleDir } = await import("./config.js");
217
- const { DaemonUpdater } = await import("./updater.js");
216
+ const { resolveClaudeDaemonConfig, resolveBundleDir } = await import('./config.js');
217
+ const { DaemonUpdater } = await import('./updater.js');
218
218
  const config = resolveClaudeDaemonConfig(process.env);
219
219
  const bundleDir = resolveBundleDir(process.env);
220
- const signingEnabled = !!process.env.PRLL_DAEMON_SIGNING_PUBLIC_KEY;
220
+ const signingEnabled = process.env.PRLL_DAEMON_SIGNING_DISABLED !== '1';
221
221
  const updater = new DaemonUpdater(bundleDir, config.updateCdnUrl, {
222
222
  info: (msg) => console.log(msg),
223
223
  warn: (msg) => console.warn(msg),
224
224
  error: (msg) => console.error(msg),
225
225
  }, signingEnabled);
226
226
  const local = updater.getLocalVersion();
227
- console.log(`Current version: ${local ?? "unknown"}`);
227
+ console.log(`Current version: ${local ?? 'unknown'}`);
228
228
  console.log(`CDN: ${config.updateCdnUrl}`);
229
229
  console.log(`Bundle dir: ${bundleDir}`);
230
230
  if (checkOnly) {
231
- console.log("\nChecking for updates...");
231
+ console.log('\nChecking for updates...');
232
232
  const result = await updater.checkAvailable();
233
233
  if (result.available) {
234
- console.log(`Update available: ${result.currentVersion ?? "unknown"} → ${result.remoteVersion}`);
234
+ console.log(`Update available: ${result.currentVersion ?? 'unknown'} → ${result.remoteVersion}`);
235
235
  }
236
236
  else if (result.remoteVersion) {
237
237
  console.log(`Already up to date (${result.currentVersion}).`);
238
238
  }
239
239
  else {
240
- console.log("Could not check for updates.");
240
+ console.log('Could not check for updates.');
241
241
  }
242
242
  return;
243
243
  }
244
244
  else {
245
- console.log("\nChecking and applying updates...");
245
+ console.log('\nChecking and applying updates...');
246
246
  }
247
247
  const applied = await updater.checkAndApply();
248
248
  if (applied) {
249
- console.log("Update applied. Restart the daemon to use the new version.");
249
+ console.log('Update applied. Restart the daemon to use the new version.');
250
250
  }
251
251
  else {
252
- console.log("Already up to date.");
252
+ console.log('Already up to date.');
253
253
  }
254
254
  }
255
255
  function printUsage() {
@@ -271,57 +271,57 @@ Usage:
271
271
  export async function runCLI(args) {
272
272
  const cmd = args[0];
273
273
  switch (cmd) {
274
- case "init":
274
+ case 'init':
275
275
  await cmdInit();
276
- return "handled";
277
- case "status":
276
+ return 'handled';
277
+ case 'status':
278
278
  cmdStatus();
279
- return "handled";
280
- case "stop":
279
+ return 'handled';
280
+ case 'stop':
281
281
  cmdStop();
282
- return "handled";
283
- case "logs": {
284
- let lines = "50";
285
- if (args[1] === "-n") {
282
+ return 'handled';
283
+ case 'logs': {
284
+ let lines = '50';
285
+ if (args[1] === '-n') {
286
286
  const n = Number(args[2]);
287
287
  if (!Number.isInteger(n) || n <= 0) {
288
- console.error("Error: -n requires a positive integer");
288
+ console.error('Error: -n requires a positive integer');
289
289
  process.exit(1);
290
290
  }
291
291
  lines = String(n);
292
292
  }
293
293
  cmdLogs(lines);
294
- return "handled";
294
+ return 'handled';
295
295
  }
296
- case "update":
297
- await cmdUpdate(args.includes("--check"));
298
- return "handled";
299
- case "service": {
296
+ case 'update':
297
+ await cmdUpdate(args.includes('--check'));
298
+ return 'handled';
299
+ case 'service': {
300
300
  const sub = args[1];
301
- if (sub === "install") {
301
+ if (sub === 'install') {
302
302
  installService();
303
303
  }
304
- else if (sub === "uninstall") {
304
+ else if (sub === 'uninstall') {
305
305
  cmdServiceUninstall();
306
306
  }
307
307
  else {
308
- console.error(`Unknown service command: ${sub ?? "(none)"}`);
309
- console.log("Usage: parall-daemon service [install|uninstall]");
308
+ console.error(`Unknown service command: ${sub ?? '(none)'}`);
309
+ console.log('Usage: parall-daemon service [install|uninstall]');
310
310
  process.exit(1);
311
311
  }
312
- return "handled";
312
+ return 'handled';
313
313
  }
314
- case "help":
315
- case "--help":
316
- case "-h":
314
+ case 'help':
315
+ case '--help':
316
+ case '-h':
317
317
  printUsage();
318
- return "handled";
318
+ return 'handled';
319
319
  default:
320
320
  if (cmd) {
321
321
  console.error(`Unknown command: ${cmd}`);
322
322
  printUsage();
323
323
  process.exit(1);
324
324
  }
325
- return "run-daemon";
325
+ return 'run-daemon';
326
326
  }
327
327
  }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * ClipInstaller — Downloads and installs clips from the Pinix registry.
3
+ *
4
+ * Flow: parse source → resolve version → download tarball → verify checksum →
5
+ * extract to clipsDir/{alias}/ → install deps → return result.
6
+ *
7
+ * Uses only Node.js built-ins (no external npm packages).
8
+ */
9
+ export interface InstallOptions {
10
+ /** e.g., "@pinix/github-tools" or "@pinix/github-tools@1.0.0" */
11
+ source: string;
12
+ /** Override alias (default: derived from package name) */
13
+ alias?: string;
14
+ /** Directory to install clips into */
15
+ clipsDir: string;
16
+ /** Pinix registry REST base (package metadata + tarballs). Default: https://api.pinixai.com (env: PRLL_PINIX_REGISTRY_URL) */
17
+ registryUrl?: string;
18
+ }
19
+ export interface InstallResult {
20
+ alias: string;
21
+ name: string;
22
+ version: string;
23
+ /** Filesystem path of the installed clip */
24
+ path: string;
25
+ }
26
+ interface ParsedSource {
27
+ scope: string | null;
28
+ name: string;
29
+ /** Full package name including scope, e.g. "@pinix/github-tools" */
30
+ fullName: string;
31
+ version: string | null;
32
+ }
33
+ /**
34
+ * Parse a source string into scope, name, and optional version.
35
+ * "@scope/name" → scope="scope", name="name", version=null
36
+ * "@scope/name@1.0.0" → scope="scope", name="name", version="1.0.0"
37
+ * "name" → scope=null, name="name", version=null
38
+ * "name@1.0.0" → scope=null, name="name", version="1.0.0"
39
+ */
40
+ export declare function parseSource(source: string): ParsedSource;
41
+ export declare function installClip(opts: InstallOptions): Promise<InstallResult>;
42
+ export declare function removeClip(clipsDir: string, alias: string): Promise<void>;
43
+ export {};
44
+ //# sourceMappingURL=clip-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clip-installer.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/clip-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAcH,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,8HAA8H;IAC9H,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAcD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAgCxD;AAicD,wBAAsB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAiE9E;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/E"}