@letta-ai/dreams 0.0.1

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.
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.stableCliPath = stableCliPath;
37
+ exports.ensureManagedInstall = ensureManagedInstall;
38
+ const node_child_process_1 = require("node:child_process");
39
+ const crypto = __importStar(require("node:crypto"));
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const store_1 = require("./store");
43
+ const version_1 = require("./version");
44
+ 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
+ function versionDirectory(version) {
49
+ return path.join((0, store_1.dreamsDir)(), "cli", version);
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
+ function npmCommand(platform) {
61
+ return platform === "win32" ? "npm.cmd" : "npm";
62
+ }
63
+ function defaultInstallPackage(directory, _packageSpec) {
64
+ const packageRoot = path.join(__dirname, "..");
65
+ const packageDirectory = path.join(directory, "package");
66
+ fs.mkdirSync(packageDirectory, { recursive: true });
67
+ for (const name of ["bin", "dist"]) {
68
+ fs.cpSync(path.join(packageRoot, name), path.join(packageDirectory, name), { recursive: true });
69
+ }
70
+ fs.copyFileSync(path.join(packageRoot, "package.json"), path.join(packageDirectory, "package.json"));
71
+ const result = (0, node_child_process_1.spawnSync)(npmCommand(process.platform), ["install", "--prefix", packageDirectory, "--omit=dev", "--no-audit", "--no-fund"], {
72
+ encoding: "utf8",
73
+ env: { ...process.env, npm_config_update_notifier: "false" },
74
+ });
75
+ if (result.error)
76
+ throw result.error;
77
+ if (result.status !== 0) {
78
+ const detail = result.stderr.trim() || result.stdout.trim() || `npm exited ${result.status}`;
79
+ throw new Error(`Could not install the durable Dreams CLI: ${detail}`);
80
+ }
81
+ }
82
+ function shellQuote(value) {
83
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
84
+ }
85
+ function launcherContent(platform, nodePath, binPath) {
86
+ if (platform === "win32") {
87
+ return `@echo off\r\n"${nodePath}" "${binPath}" %*\r\n`;
88
+ }
89
+ return `#!/bin/sh\nexec ${shellQuote(nodePath)} ${shellQuote(binPath)} "$@"\n`;
90
+ }
91
+ function writeAtomic(file, contents, mode) {
92
+ try {
93
+ if (fs.readFileSync(file, "utf8") === contents) {
94
+ if (process.platform !== "win32")
95
+ fs.chmodSync(file, mode);
96
+ return;
97
+ }
98
+ }
99
+ catch {
100
+ // Missing or unreadable launcher: replace it below.
101
+ }
102
+ fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
103
+ const temporary = `${file}.tmp-${process.pid}-${crypto.randomBytes(4).toString("hex")}`;
104
+ try {
105
+ fs.writeFileSync(temporary, contents, { mode });
106
+ fs.renameSync(temporary, file);
107
+ if (process.platform !== "win32")
108
+ fs.chmodSync(file, mode);
109
+ }
110
+ finally {
111
+ fs.rmSync(temporary, { force: true });
112
+ }
113
+ }
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) {
119
+ 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
+ };
126
+ }
127
+ 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);
144
+ }
145
+ }
146
+ }
147
+ function installVersion(version, installPackage) {
148
+ if (installationComplete(version))
149
+ return false;
150
+ const releaseLock = waitForInstallLock();
151
+ 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
+ }
184
+ }
185
+ finally {
186
+ releaseLock();
187
+ }
188
+ }
189
+ function ensureManagedInstall(options = {}) {
190
+ (0, store_1.secureDreamsDir)();
191
+ if (process.env.DREAMS_SKIP_MANAGED_INSTALL === "1") {
192
+ return { cli_path: stableCliPath(options.platform), status: "skipped" };
193
+ }
194
+ const version = options.version ?? (0, version_1.packageVersion)();
195
+ 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);
199
+ return { cli_path: cliPath, status: changed ? "installed" : "unchanged" };
200
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.commandOnboard = commandOnboard;
4
+ const index_1 = require("./auth/index");
5
+ const db_1 = require("./local/db");
6
+ const managed_install_1 = require("./managed-install");
7
+ const skill_1 = require("./skill");
8
+ const store_1 = require("./store");
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");
22
+ return {
23
+ schema_version: 1,
24
+ state: "awaiting_auth",
25
+ completed,
26
+ 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,
45
+ };
46
+ }
47
+ function errorEnvelope(cliPath, completed, retryCommand, error) {
48
+ return {
49
+ schema_version: 1,
50
+ state: "error",
51
+ completed,
52
+ cli_path: cliPath,
53
+ next_action: {
54
+ kind: "run_command",
55
+ command: retryCommand,
56
+ },
57
+ error: { message: error instanceof Error ? error.message : String(error) },
58
+ done: false,
59
+ };
60
+ }
61
+ function renderEnvelope(envelope) {
62
+ return [
63
+ "Dreams setup",
64
+ "",
65
+ ` State: ${envelope.state}`,
66
+ ` Durable CLI: ${envelope.cli_path}`,
67
+ ` Local database: ${(0, db_1.dbFilePath)()}`,
68
+ ` Next command: ${envelope.next_action.command}`,
69
+ "",
70
+ envelope.agent_instructions,
71
+ ].join("\n");
72
+ }
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
+ async function commandOnboard(json) {
85
+ const completed = [];
86
+ let cliPath = (0, managed_install_1.stableCliPath)();
87
+ try {
88
+ const managedInstall = (0, managed_install_1.ensureManagedInstall)();
89
+ cliPath = managedInstall.cli_path;
90
+ completed.push("cli_installed");
91
+ if (managedInstall.status === "installed") {
92
+ process.stderr.write(`Installed durable Dreams CLI at ${cliPath}\n`);
93
+ }
94
+ const installation = (0, store_1.loadOrCreateInstallation)();
95
+ completed.push("installation_initialized");
96
+ const skill = (0, skill_1.installSkill)();
97
+ completed.push("skill_installed");
98
+ if (skill !== "unchanged") {
99
+ process.stderr.write(`${skill === "installed" ? "Installed" : "Updated"} setup skill v${(0, version_1.packageVersion)()} at ${(0, skill_1.skillFilePath)()}\n`);
100
+ }
101
+ try {
102
+ (0, db_1.openDb)({
103
+ installationId: installation.installation_id,
104
+ installationCreatedAt: installation.created_at,
105
+ });
106
+ }
107
+ finally {
108
+ (0, db_1.closeDb)();
109
+ }
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);
117
+ console.log(json ? JSON.stringify(envelope, null, 2) : renderEnvelope(envelope));
118
+ return 0;
119
+ }
120
+ 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);
125
+ if (json)
126
+ console.log(JSON.stringify(envelope, null, 2));
127
+ else
128
+ process.stderr.write(`Dreams setup failed: ${envelope.error.message}\n`);
129
+ return 1;
130
+ }
131
+ }
package/dist/skill.js ADDED
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.skillDir = skillDir;
37
+ exports.skillFilePath = skillFilePath;
38
+ exports.installedSkillVersion = installedSkillVersion;
39
+ exports.installSkill = installSkill;
40
+ const crypto = __importStar(require("node:crypto"));
41
+ const fs = __importStar(require("node:fs"));
42
+ const os = __importStar(require("node:os"));
43
+ const path = __importStar(require("node:path"));
44
+ const version_1 = require("./version");
45
+ const SKILL_NAME = "dreams-setup";
46
+ const LEGACY_SKILL_NAME = "dreams-onboarding";
47
+ function skillDir() {
48
+ return path.join(os.homedir(), ".claude", "skills", SKILL_NAME);
49
+ }
50
+ function skillFilePath() {
51
+ return path.join(skillDir(), "SKILL.md");
52
+ }
53
+ function skillContent(version) {
54
+ return `---
55
+ name: dreams-setup
56
+ description: Set up Dreams, Letta's shared organizational memory, or continue an interrupted Dreams setup. Use when the user asks to install Dreams, set up Dreams, or connect this device to Dreams.
57
+ version: ${version}
58
+ ---
59
+
60
+ # Dreams setup
61
+
62
+ Start or repair the local setup with:
63
+
64
+ \`\`\`bash
65
+ npx @letta-ai/dreams@latest onboard --json
66
+ \`\`\`
67
+
68
+ \`onboard\` installs an exact CLI version at a stable local path, creates or reuses the installation identity, installs this skill, initializes local SQLite, and checks authentication. It does not log in or run \`orient\` itself.
69
+
70
+ ## Follow the response
71
+
72
+ 1. Parse the single JSON document from stdout.
73
+ 2. Briefly explain \`agent_instructions\` to the user without pasting raw JSON.
74
+ 3. Run the exact command in \`next_action.command\`.
75
+ 4. Use the absolute \`cli_path\` from the response for later Dreams commands.
76
+
77
+ When \`state\` is \`awaiting_auth\`, run the returned \`auth login --json\` command and wait for the user to approve in the browser. That login command emits JSON Lines: first \`awaiting_approval\`, then \`authenticated\`. After it succeeds, run the stable CLI's \`onboard --json\` command again.
78
+
79
+ When \`state\` is \`ready_for_orient\`, run the returned \`orient\` command.
80
+
81
+ Repeated \`onboard\` calls are safe. They repair missing local setup and return the same next action until authentication state changes.
82
+
83
+ Never print or summarize access tokens, refresh tokens, credential files, or keychain contents.
84
+ `;
85
+ }
86
+ function readFile(file) {
87
+ try {
88
+ return fs.readFileSync(file, "utf8");
89
+ }
90
+ catch {
91
+ return null;
92
+ }
93
+ }
94
+ function writeAtomic(file, contents) {
95
+ fs.mkdirSync(path.dirname(file), { recursive: true });
96
+ const temporary = `${file}.tmp-${process.pid}-${crypto.randomBytes(4).toString("hex")}`;
97
+ try {
98
+ fs.writeFileSync(temporary, contents);
99
+ fs.renameSync(temporary, file);
100
+ }
101
+ finally {
102
+ fs.rmSync(temporary, { force: true });
103
+ }
104
+ }
105
+ function removeLegacyGeneratedSkill() {
106
+ const directory = path.join(os.homedir(), ".claude", "skills", LEGACY_SKILL_NAME);
107
+ const file = path.join(directory, "SKILL.md");
108
+ const contents = readFile(file);
109
+ if (contents === null ||
110
+ !/^name:\s*dreams-onboarding\s*$/m.test(contents) ||
111
+ !contents.includes("dreams init --json") ||
112
+ !contents.includes("resumable onboarding")) {
113
+ return;
114
+ }
115
+ fs.rmSync(file, { force: true });
116
+ try {
117
+ fs.rmdirSync(directory);
118
+ }
119
+ catch {
120
+ // Preserve the directory when it contains other user-owned files.
121
+ }
122
+ }
123
+ function installedSkillVersion() {
124
+ const text = readFile(skillFilePath());
125
+ if (text === null)
126
+ return null;
127
+ const match = text.match(/^version:\s*(\S+)\s*$/m);
128
+ return match ? match[1] : null;
129
+ }
130
+ function installSkill() {
131
+ removeLegacyGeneratedSkill();
132
+ const desired = skillContent((0, version_1.packageVersion)());
133
+ const existing = readFile(skillFilePath());
134
+ if (existing === desired)
135
+ return "unchanged";
136
+ writeAtomic(skillFilePath(), desired);
137
+ return existing === null ? "installed" : "updated";
138
+ }
package/dist/store.js ADDED
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.dreamsDir = dreamsDir;
37
+ exports.secureDreamsDir = secureDreamsDir;
38
+ exports.installationFilePath = installationFilePath;
39
+ exports.loadOrCreateInstallation = loadOrCreateInstallation;
40
+ const crypto = __importStar(require("node:crypto"));
41
+ const fs = __importStar(require("node:fs"));
42
+ const os = __importStar(require("node:os"));
43
+ const path = __importStar(require("node:path"));
44
+ function dreamsDir() {
45
+ return path.join(os.homedir(), ".dreams");
46
+ }
47
+ /**
48
+ * Create/keep the state directory private (0700) on every load and open, not
49
+ * only when first minting an installation. On Windows the mode bits are advisory
50
+ * (NTFS ACLs govern access); best-effort chmod keeps POSIX platforms locked down.
51
+ */
52
+ function secureDreamsDir() {
53
+ const dir = dreamsDir();
54
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
55
+ if (process.platform !== "win32") {
56
+ try {
57
+ fs.chmodSync(dir, 0o700);
58
+ }
59
+ catch {
60
+ // Non-fatal: an unwritable mode should not block reads of existing state.
61
+ }
62
+ }
63
+ return dir;
64
+ }
65
+ function installationFilePath() {
66
+ return path.join(dreamsDir(), "installation.json");
67
+ }
68
+ function readJson(file) {
69
+ try {
70
+ return JSON.parse(fs.readFileSync(file, "utf8"));
71
+ }
72
+ catch {
73
+ return null;
74
+ }
75
+ }
76
+ function fsyncDirectory(dir) {
77
+ if (process.platform === "win32")
78
+ return;
79
+ const fd = fs.openSync(dir, "r");
80
+ try {
81
+ fs.fsyncSync(fd);
82
+ }
83
+ finally {
84
+ fs.closeSync(fd);
85
+ }
86
+ }
87
+ /** Publish a complete JSON file only if no other process has won the race. */
88
+ function writeJsonExclusive(file, value) {
89
+ const dir = path.dirname(file);
90
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
91
+ fs.chmodSync(dir, 0o700);
92
+ const tmp = path.join(dir, `.${path.basename(file)}.${process.pid}.${crypto.randomUUID()}.tmp`);
93
+ const data = JSON.stringify(value, null, 2) + "\n";
94
+ const fd = fs.openSync(tmp, "wx", 0o600);
95
+ try {
96
+ fs.writeFileSync(fd, data);
97
+ fs.fsyncSync(fd);
98
+ }
99
+ finally {
100
+ fs.closeSync(fd);
101
+ }
102
+ try {
103
+ // A hard link is an atomic no-replace publish on every supported platform.
104
+ // Unlike rename, it cannot overwrite another process's winning identity.
105
+ fs.linkSync(tmp, file);
106
+ fsyncDirectory(dir);
107
+ }
108
+ catch (error) {
109
+ if (error.code !== "EEXIST")
110
+ throw error;
111
+ }
112
+ finally {
113
+ fs.rmSync(tmp, { force: true });
114
+ }
115
+ }
116
+ function loadOrCreateInstallation() {
117
+ secureDreamsDir();
118
+ const file = installationFilePath();
119
+ const existing = readJson(file);
120
+ if (existing?.installation_id)
121
+ return existing;
122
+ if (fs.existsSync(file))
123
+ throw new Error(`Invalid installation state at ${file}`);
124
+ writeJsonExclusive(file, {
125
+ installation_id: "device_" + crypto.randomBytes(8).toString("hex"),
126
+ created_at: new Date().toISOString(),
127
+ });
128
+ // Always reread the published winner; another process may have linked first.
129
+ const persisted = readJson(file);
130
+ if (!persisted?.installation_id)
131
+ throw new Error(`Failed to create installation state at ${file}`);
132
+ return persisted;
133
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.packageVersion = packageVersion;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ /**
40
+ * Read the package version at runtime. Works from src/ (tsx dev), dist/
41
+ * (built), and inside the packed tarball — package.json is one level up in
42
+ * all three cases.
43
+ */
44
+ function packageVersion() {
45
+ const pkgPath = path.join(__dirname, "..", "package.json");
46
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
47
+ return pkg.version;
48
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@letta-ai/dreams",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "description": "Dreams CLI - shared organizational memory from coding-agent transcripts",
6
+ "license": "Apache-2.0",
7
+ "bin": {
8
+ "dreams": "bin/dreams.cjs"
9
+ },
10
+ "files": [
11
+ "bin",
12
+ "dist"
13
+ ],
14
+ "engines": {
15
+ "node": ">=22.13"
16
+ },
17
+ "scripts": {
18
+ "dev": "tsx src/cli.ts",
19
+ "typecheck": "tsc --noEmit",
20
+ "build": "tsc",
21
+ "prepack": "npm run build",
22
+ "test": "npm run build && node --test test/*.test.mjs"
23
+ },
24
+ "optionalDependencies": {
25
+ "@napi-rs/keyring": "^1.3.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.10.0",
29
+ "tsx": "^4.19.0",
30
+ "typescript": "^5.7.0"
31
+ }
32
+ }