drift-ml 0.1.12 → 0.1.15

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/README.md CHANGED
@@ -6,11 +6,11 @@
6
6
 
7
7
  ## Exactly what to do
8
8
 
9
- 1. **Install drift**
9
+ 1. **Install drift** (pipx recommended — works standalone)
10
10
  ```bash
11
- npm install -g drift-ml
11
+ pipx install drift-ml
12
12
  ```
13
- Requires Node.js 18 and Python 3 on your PATH.
13
+ Or: `npm install -g drift-ml` (requires `pipx install drift-ml` for the CLI).
14
14
 
15
15
  2. **Run drift**
16
16
  ```bash
@@ -41,6 +41,8 @@ That’s it. The engine runs locally. The web app (if you use it) can be hosted
41
41
  - **Terminal-first, chat-based** — Same engine as the web app. No commands to memorize; chat in natural language.
42
42
  - **Engine** — On first run the CLI downloads and starts the engine from `~/.drift/bin/`. Or set `DRIFT_BACKEND_URL` to a running engine URL.
43
43
 
44
+ **Custom / private repo:** Engine binaries are hosted at [lakshitsachdeva/drift](https://github.com/lakshitsachdeva/drift) (public). For a private fork, set `DRIFT_GITHUB_TOKEN` with a token that has repo read access.
45
+
44
46
  ---
45
47
 
46
48
  ## Install (details)
package/bin/drift.js CHANGED
@@ -17,7 +17,11 @@ const http = require("http");
17
17
  const isWindows = process.platform === "win32";
18
18
  const ENGINE_PORT = process.env.DRIFT_ENGINE_PORT || "8000";
19
19
  // Pinned tag: draft releases are invisible to /releases/latest.
20
- const ENGINE_BASE_URL = process.env.DRIFT_ENGINE_BASE_URL || "https://github.com/lakshitsachdeva/intent2model/releases/download/v0.1.1";
20
+ const ENGINE_TAG = "v0.1.3";
21
+ const GITHUB_REPO = "lakshitsachdeva/drift";
22
+ const ENGINE_BASE_URL = process.env.DRIFT_ENGINE_BASE_URL || `https://github.com/${GITHUB_REPO}/releases/download/${ENGINE_TAG}`;
23
+ const GITHUB_API_RELEASE = `https://api.github.com/repos/${GITHUB_REPO}/releases/tags/${ENGINE_TAG}`;
24
+ const GITHUB_TOKEN = process.env.DRIFT_GITHUB_TOKEN || process.env.GITHUB_TOKEN;
21
25
  const HEALTH_URL = `http://127.0.0.1:${ENGINE_PORT}/health`;
22
26
  const HEALTH_TIMEOUT_MS = 2000;
23
27
  const HEALTH_POLL_MS = 500;
@@ -62,10 +66,55 @@ function fetchOk(url) {
62
66
  });
63
67
  }
64
68
 
69
+ const API_HEADERS = {
70
+ "User-Agent": "Drift-Engine-Launcher/1.0",
71
+ Accept: "application/vnd.github+json",
72
+ ...(GITHUB_TOKEN && { Authorization: `Bearer ${GITHUB_TOKEN}` }),
73
+ };
74
+ const DOWNLOAD_HEADERS = {
75
+ "User-Agent": "Drift-Engine-Launcher/1.0",
76
+ Accept: "application/octet-stream",
77
+ ...(GITHUB_TOKEN && { Authorization: `Bearer ${GITHUB_TOKEN}` }),
78
+ };
79
+
80
+ // Resolve GitHub release asset to API download URL (browser_download_url returns 404 for scripts).
81
+ function getGitHubAssetUrl(assetName) {
82
+ return new Promise((resolve, reject) => {
83
+ const req = https.get(GITHUB_API_RELEASE, { headers: API_HEADERS }, (res) => {
84
+ if (res.statusCode === 404) {
85
+ reject(new Error(
86
+ "Release not found (404). If the repo is private, set DRIFT_GITHUB_TOKEN with a token that has repo read access."
87
+ ));
88
+ return;
89
+ }
90
+ if (res.statusCode !== 200) {
91
+ reject(new Error(`Release not found: ${res.statusCode}`));
92
+ return;
93
+ }
94
+ let body = "";
95
+ res.on("data", (chunk) => { body += chunk; });
96
+ res.on("end", () => {
97
+ try {
98
+ const data = JSON.parse(body);
99
+ const asset = (data.assets || []).find((a) => a.name === assetName);
100
+ if (!asset || !asset.url) {
101
+ reject(new Error(`Asset not found: ${assetName}`));
102
+ return;
103
+ }
104
+ resolve(asset.url);
105
+ } catch (e) {
106
+ reject(e);
107
+ }
108
+ });
109
+ });
110
+ req.on("error", reject);
111
+ });
112
+ }
113
+
65
114
  function downloadFile(url, destPath) {
66
115
  return new Promise((resolve, reject) => {
67
116
  const client = url.startsWith("https") ? https : http;
68
- const req = client.get(url, (res) => {
117
+ const req = client.get(url, { headers: DOWNLOAD_HEADERS }, (res) => {
69
118
  const redirect = res.statusCode >= 301 && res.statusCode <= 302 && res.headers.location;
70
119
  if (redirect) {
71
120
  downloadFile(redirect, destPath).then(resolve).catch(reject);
@@ -117,7 +166,10 @@ async function ensureEngine() {
117
166
  const { plat, arch } = getPlatformKey();
118
167
  const ext = isWindows ? ".exe" : "";
119
168
  const asset = `drift-engine-${plat}-${arch}${ext}`;
120
- const url = `${ENGINE_BASE_URL.replace(/\/$/, "")}/${asset}`;
169
+ const isDefaultGitHub = !process.env.DRIFT_ENGINE_BASE_URL;
170
+ const url = isDefaultGitHub
171
+ ? await getGitHubAssetUrl(asset)
172
+ : `${ENGINE_BASE_URL.replace(/\/$/, "")}/${asset}`;
121
173
  process.stderr.write(`drift: Downloading engine (${asset})...\n`);
122
174
  try {
123
175
  await downloadFile(url, binPath);
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "drift-ml",
3
- "version": "0.1.12",
3
+ "version": "0.1.15",
4
4
  "description": "Drift — terminal-first, chat-based AutoML. Same engine as the web app. On first run: downloads and starts the engine locally (never exposes engine source).",
5
5
  "bin": {
6
- "drift": "./bin/drift.js"
6
+ "drift": "bin/drift.js"
7
7
  },
8
+ "files": ["bin", "README.md"],
8
9
  "engines": {
9
10
  "node": ">=18"
10
11
  },