@letta-ai/dreams 0.0.1 → 0.0.3

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.
@@ -33,30 +33,21 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.stableCliPath = stableCliPath;
36
+ exports.stableCliPath = void 0;
37
37
  exports.ensureManagedInstall = ensureManagedInstall;
38
38
  const node_child_process_1 = require("node:child_process");
39
39
  const crypto = __importStar(require("node:crypto"));
40
40
  const fs = __importStar(require("node:fs"));
41
41
  const path = __importStar(require("node:path"));
42
+ const launcher_1 = require("./launcher");
42
43
  const store_1 = require("./store");
43
44
  const version_1 = require("./version");
45
+ var launcher_2 = require("./launcher");
46
+ Object.defineProperty(exports, "stableCliPath", { enumerable: true, get: function () { return launcher_2.stableCliPath; } });
44
47
  const PACKAGE_NAME = "@letta-ai/dreams";
45
- function stableCliPath(platform = process.platform) {
46
- return path.join((0, store_1.dreamsDir)(), "bin", platform === "win32" ? "dreams.cmd" : "dreams");
47
- }
48
48
  function versionDirectory(version) {
49
49
  return path.join((0, store_1.dreamsDir)(), "cli", version);
50
50
  }
51
- function installedBin(version) {
52
- return path.join(versionDirectory(version), "package", "bin", "dreams.cjs");
53
- }
54
- function completeMarker(version) {
55
- return path.join(versionDirectory(version), ".complete");
56
- }
57
- function installationComplete(version) {
58
- return fs.existsSync(installedBin(version)) && fs.existsSync(completeMarker(version));
59
- }
60
51
  function npmCommand(platform) {
61
52
  return platform === "win32" ? "npm.cmd" : "npm";
62
53
  }
@@ -82,11 +73,11 @@ function defaultInstallPackage(directory, _packageSpec) {
82
73
  function shellQuote(value) {
83
74
  return `'${value.replaceAll("'", `'"'"'`)}'`;
84
75
  }
85
- function launcherContent(platform, nodePath, binPath) {
76
+ function launcherContent(platform, nodePath, controllerPath) {
86
77
  if (platform === "win32") {
87
- return `@echo off\r\n"${nodePath}" "${binPath}" %*\r\n`;
78
+ return `@echo off\r\n"${nodePath}" "${controllerPath}" %*\r\n`;
88
79
  }
89
- return `#!/bin/sh\nexec ${shellQuote(nodePath)} ${shellQuote(binPath)} "$@"\n`;
80
+ return `#!/bin/sh\nexec ${shellQuote(nodePath)} ${shellQuote(controllerPath)} "$@"\n`;
90
81
  }
91
82
  function writeAtomic(file, contents, mode) {
92
83
  try {
@@ -97,7 +88,7 @@ function writeAtomic(file, contents, mode) {
97
88
  }
98
89
  }
99
90
  catch {
100
- // Missing or unreadable launcher: replace it below.
91
+ // Missing or unreadable file: replace it below.
101
92
  }
102
93
  fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
103
94
  const temporary = `${file}.tmp-${process.pid}-${crypto.randomBytes(4).toString("hex")}`;
@@ -111,90 +102,87 @@ function writeAtomic(file, contents, mode) {
111
102
  fs.rmSync(temporary, { force: true });
112
103
  }
113
104
  }
114
- function waitForInstallLock() {
115
- const lock = path.join((0, store_1.dreamsDir)(), "install.lock");
116
- const sleeper = new Int32Array(new SharedArrayBuffer(4));
117
- const deadline = Date.now() + 30_000;
118
- while (true) {
105
+ function installVersionLocked(version, installPackage) {
106
+ if ((0, launcher_1.installationComplete)(version))
107
+ return false;
108
+ const target = versionDirectory(version);
109
+ const nonce = `${process.pid}-${crypto.randomBytes(4).toString("hex")}`;
110
+ const staging = `${target}.tmp-${nonce}`;
111
+ const replaced = `${target}.replaced-${nonce}`;
112
+ fs.mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });
113
+ fs.mkdirSync(staging, { recursive: true, mode: 0o700 });
114
+ try {
115
+ installPackage(staging, `${PACKAGE_NAME}@${version}`);
116
+ const stagedBin = path.join(staging, "package", "bin", "dreams.cjs");
117
+ if (!fs.existsSync(stagedBin)) {
118
+ throw new Error(`Durable Dreams CLI install did not contain ${PACKAGE_NAME}/bin/dreams.cjs`);
119
+ }
120
+ fs.writeFileSync(path.join(staging, ".complete"), JSON.stringify({ package: PACKAGE_NAME, version, installed_at: new Date().toISOString() }) + "\n");
121
+ if (fs.existsSync(target))
122
+ fs.renameSync(target, replaced);
119
123
  try {
120
- const descriptor = fs.openSync(lock, "wx", 0o600);
121
- fs.writeFileSync(descriptor, `${process.pid}\n${new Date().toISOString()}\n`);
122
- return () => {
123
- fs.closeSync(descriptor);
124
- fs.rmSync(lock, { force: true });
125
- };
124
+ fs.renameSync(staging, target);
126
125
  }
127
126
  catch (error) {
128
- if (error.code !== "EEXIST")
129
- throw error;
130
- try {
131
- const age = Date.now() - fs.statSync(lock).mtimeMs;
132
- if (age > 5 * 60_000) {
133
- fs.rmSync(lock, { force: true });
134
- continue;
135
- }
136
- }
137
- catch {
138
- continue;
139
- }
140
- if (Date.now() >= deadline) {
141
- throw new Error("Timed out waiting for another Dreams CLI installation to finish.");
142
- }
143
- Atomics.wait(sleeper, 0, 0, 100);
127
+ if (fs.existsSync(replaced) && !fs.existsSync(target))
128
+ fs.renameSync(replaced, target);
129
+ throw error;
144
130
  }
131
+ fs.rmSync(replaced, { recursive: true, force: true });
132
+ return true;
133
+ }
134
+ finally {
135
+ fs.rmSync(staging, { recursive: true, force: true });
136
+ fs.rmSync(replaced, { recursive: true, force: true });
145
137
  }
146
138
  }
147
- function installVersion(version, installPackage) {
148
- if (installationComplete(version))
149
- return false;
150
- const releaseLock = waitForInstallLock();
139
+ function detectLegacyActiveVersion() {
140
+ if ((0, launcher_1.readActivation)())
141
+ return null;
142
+ let launcher;
151
143
  try {
152
- if (installationComplete(version))
153
- return false;
154
- const target = versionDirectory(version);
155
- const nonce = `${process.pid}-${crypto.randomBytes(4).toString("hex")}`;
156
- const staging = `${target}.tmp-${nonce}`;
157
- const replaced = `${target}.replaced-${nonce}`;
158
- fs.mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });
159
- fs.mkdirSync(staging, { recursive: true, mode: 0o700 });
160
- try {
161
- installPackage(staging, `${PACKAGE_NAME}@${version}`);
162
- const stagedBin = path.join(staging, "package", "bin", "dreams.cjs");
163
- if (!fs.existsSync(stagedBin)) {
164
- throw new Error(`Durable Dreams CLI install did not contain ${PACKAGE_NAME}/bin/dreams.cjs`);
165
- }
166
- fs.writeFileSync(path.join(staging, ".complete"), JSON.stringify({ package: PACKAGE_NAME, version, installed_at: new Date().toISOString() }) + "\n");
167
- if (fs.existsSync(target))
168
- fs.renameSync(target, replaced);
169
- try {
170
- fs.renameSync(staging, target);
171
- }
172
- catch (error) {
173
- if (fs.existsSync(replaced) && !fs.existsSync(target))
174
- fs.renameSync(replaced, target);
175
- throw error;
176
- }
177
- fs.rmSync(replaced, { recursive: true, force: true });
178
- return true;
179
- }
180
- finally {
181
- fs.rmSync(staging, { recursive: true, force: true });
182
- fs.rmSync(replaced, { recursive: true, force: true });
183
- }
144
+ launcher = fs.readFileSync((0, launcher_1.stableCliPath)(), "utf8");
184
145
  }
185
- finally {
186
- releaseLock();
146
+ catch {
147
+ return null;
148
+ }
149
+ const cliDirectory = path.join((0, store_1.dreamsDir)(), "cli");
150
+ let entries;
151
+ try {
152
+ entries = fs.readdirSync(cliDirectory, { withFileTypes: true });
153
+ }
154
+ catch {
155
+ return null;
156
+ }
157
+ for (const entry of entries) {
158
+ if (entry.isDirectory() && (0, launcher_1.installationComplete)(entry.name) && launcher.includes((0, launcher_1.installedBin)(entry.name))) {
159
+ return entry.name;
160
+ }
187
161
  }
162
+ return null;
163
+ }
164
+ function launcherControllerSource() {
165
+ return path.join(__dirname, "..", "dist", "launcher.js");
188
166
  }
189
167
  function ensureManagedInstall(options = {}) {
190
168
  (0, store_1.secureDreamsDir)();
191
169
  if (process.env.DREAMS_SKIP_MANAGED_INSTALL === "1") {
192
- return { cli_path: stableCliPath(options.platform), status: "skipped" };
170
+ return { cli_path: (0, launcher_1.stableCliPath)(options.platform), status: "skipped" };
193
171
  }
194
172
  const version = options.version ?? (0, version_1.packageVersion)();
195
173
  const platform = options.platform ?? process.platform;
196
- const changed = installVersion(version, options.installPackage ?? defaultInstallPackage);
197
- const cliPath = stableCliPath(platform);
198
- writeAtomic(cliPath, launcherContent(platform, options.nodePath ?? process.execPath, installedBin(version)), platform === "win32" ? 0o600 : 0o700);
174
+ const cliPath = (0, launcher_1.stableCliPath)(platform);
175
+ let changed = false;
176
+ (0, launcher_1.withInstallLock)(() => {
177
+ const legacyActiveVersion = detectLegacyActiveVersion();
178
+ changed = installVersionLocked(version, options.installPackage ?? defaultInstallPackage);
179
+ const controllerSource = launcherControllerSource();
180
+ if (!fs.existsSync(controllerSource)) {
181
+ throw new Error(`Dreams launcher controller is missing at ${controllerSource}`);
182
+ }
183
+ writeAtomic((0, launcher_1.stableLauncherControllerPath)(), fs.readFileSync(controllerSource, "utf8"), 0o600);
184
+ (0, launcher_1.activateVersionLocked)(version, legacyActiveVersion);
185
+ writeAtomic(cliPath, launcherContent(platform, options.nodePath ?? process.execPath, (0, launcher_1.stableLauncherControllerPath)()), platform === "win32" ? 0o600 : 0o700);
186
+ });
199
187
  return { cli_path: cliPath, status: changed ? "installed" : "unchanged" };
200
188
  }
package/dist/onboard.js CHANGED
@@ -1,100 +1,59 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.commandOnboard = commandOnboard;
4
- const index_1 = require("./auth/index");
5
4
  const db_1 = require("./local/db");
5
+ const state_lock_1 = require("./local/state-lock");
6
6
  const managed_install_1 = require("./managed-install");
7
7
  const skill_1 = require("./skill");
8
8
  const store_1 = require("./store");
9
9
  const version_1 = require("./version");
10
- const LOCAL_SETUP = [
11
- "cli_installed",
12
- "installation_initialized",
13
- "skill_installed",
14
- "local_state_initialized",
15
- ];
16
- function command(cliPath, args) {
17
- return `${JSON.stringify(cliPath)} ${args}`;
18
- }
19
- function awaitingAuthEnvelope(cliPath, completed) {
20
- const loginCommand = command(cliPath, "auth login --json");
21
- const resumeCommand = command(cliPath, "onboard --json");
10
+ function readyEnvelope(cliPath) {
22
11
  return {
23
12
  schema_version: 1,
24
- state: "awaiting_auth",
25
- completed,
13
+ status: "ready",
26
14
  cli_path: cliPath,
27
- next_action: { kind: "run_command", command: loginCommand },
28
- agent_instructions: `Run ${loginCommand} and wait for the user to authorize in the browser. ` +
29
- `After login succeeds, run ${resumeCommand} to continue setup.`,
30
- ui: { milestone: "authentication" },
31
- done: false,
32
- };
33
- }
34
- function orientReadyEnvelope(cliPath, completed) {
35
- const orientCommand = command(cliPath, "orient --json");
36
- return {
37
- schema_version: 1,
38
- state: "ready_for_orient",
39
- completed,
40
- cli_path: cliPath,
41
- next_action: { kind: "run_command", command: orientCommand },
42
- agent_instructions: `Dreams is installed and authenticated. Run ${orientCommand} to begin orient.`,
43
- ui: { milestone: "orient" },
44
- done: false,
15
+ skill: {
16
+ name: "dreams-setup",
17
+ path: (0, skill_1.skillFilePath)(),
18
+ version: (0, version_1.packageVersion)(),
19
+ },
20
+ message: "Continue setup using the installed Dreams setup skill. Start at step 1 (Authenticate).",
45
21
  };
46
22
  }
47
- function errorEnvelope(cliPath, completed, retryCommand, error) {
23
+ function errorEnvelope(cliPath, error) {
48
24
  return {
49
25
  schema_version: 1,
50
- state: "error",
51
- completed,
26
+ status: "error",
52
27
  cli_path: cliPath,
53
- next_action: {
54
- kind: "run_command",
55
- command: retryCommand,
56
- },
57
28
  error: { message: error instanceof Error ? error.message : String(error) },
58
- done: false,
59
29
  };
60
30
  }
61
31
  function renderEnvelope(envelope) {
62
32
  return [
63
33
  "Dreams setup",
64
34
  "",
65
- ` State: ${envelope.state}`,
66
- ` Durable CLI: ${envelope.cli_path}`,
67
- ` Local database: ${(0, db_1.dbFilePath)()}`,
68
- ` Next command: ${envelope.next_action.command}`,
35
+ ` Status: ${envelope.status}`,
36
+ ` Durable CLI: ${envelope.cli_path}`,
37
+ ` Setup skill: ${envelope.skill.path}`,
38
+ ` Skill dir: ${(0, skill_1.skillDir)()}`,
69
39
  "",
70
- envelope.agent_instructions,
40
+ envelope.message,
71
41
  ].join("\n");
72
42
  }
73
- async function isAuthenticated() {
74
- try {
75
- await (0, index_1.resolveAccessToken)();
76
- return true;
77
- }
78
- catch (error) {
79
- if (error instanceof index_1.NotAuthenticatedError)
80
- return false;
81
- throw error;
82
- }
83
- }
84
43
  async function commandOnboard(json) {
85
- const completed = [];
86
44
  let cliPath = (0, managed_install_1.stableCliPath)();
45
+ let stateLock = null;
87
46
  try {
47
+ stateLock = (0, state_lock_1.acquireLocalStateLock)();
48
+ if (stateLock === null)
49
+ throw new Error("Another Dreams command is using local state. Try again after it finishes.");
88
50
  const managedInstall = (0, managed_install_1.ensureManagedInstall)();
89
51
  cliPath = managedInstall.cli_path;
90
- completed.push("cli_installed");
91
52
  if (managedInstall.status === "installed") {
92
53
  process.stderr.write(`Installed durable Dreams CLI at ${cliPath}\n`);
93
54
  }
94
55
  const installation = (0, store_1.loadOrCreateInstallation)();
95
- completed.push("installation_initialized");
96
56
  const skill = (0, skill_1.installSkill)();
97
- completed.push("skill_installed");
98
57
  if (skill !== "unchanged") {
99
58
  process.stderr.write(`${skill === "installed" ? "Installed" : "Updated"} setup skill v${(0, version_1.packageVersion)()} at ${(0, skill_1.skillFilePath)()}\n`);
100
59
  }
@@ -107,25 +66,20 @@ async function commandOnboard(json) {
107
66
  finally {
108
67
  (0, db_1.closeDb)();
109
68
  }
110
- completed.push("local_state_initialized");
111
- const authenticated = await isAuthenticated();
112
- if (authenticated)
113
- completed.push("authenticated");
114
- const envelope = authenticated
115
- ? orientReadyEnvelope(cliPath, completed)
116
- : awaitingAuthEnvelope(cliPath, completed);
69
+ const envelope = readyEnvelope(cliPath);
117
70
  console.log(json ? JSON.stringify(envelope, null, 2) : renderEnvelope(envelope));
118
71
  return 0;
119
72
  }
120
73
  catch (error) {
121
- const retryCommand = completed.includes("cli_installed")
122
- ? command(cliPath, `onboard${json ? " --json" : ""}`)
123
- : `npx @letta-ai/dreams@latest onboard${json ? " --json" : ""}`;
124
- const envelope = errorEnvelope(cliPath, completed, retryCommand, error);
74
+ const envelope = errorEnvelope(cliPath, error);
125
75
  if (json)
126
76
  console.log(JSON.stringify(envelope, null, 2));
127
77
  else
128
78
  process.stderr.write(`Dreams setup failed: ${envelope.error.message}\n`);
129
79
  return 1;
130
80
  }
81
+ finally {
82
+ if (stateLock !== null)
83
+ (0, state_lock_1.releaseLocalStateLock)(stateLock);
84
+ }
131
85
  }