atlarix 15.4.1 → 15.5.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.
@@ -167,7 +167,13 @@ var init_electron_stub = __esm({
167
167
  showSaveDialog: async () => ({ canceled: true })
168
168
  };
169
169
  shell = {
170
- openExternal: async () => {
170
+ // Under `atlarix acp` the editor opens it (an MCP server's sign-in page, say):
171
+ // its extension watches stderr for this line, as it does for Atlarix's sign-in.
172
+ openExternal: async (url2) => {
173
+ if (process.env.ATLARIX_OPEN_URLS_VIA_STDERR === "1" && typeof url2 === "string" && /^https?:\/\//i.test(url2)) {
174
+ process.stderr.write(`Atlarix open: ${url2}
175
+ `);
176
+ }
171
177
  },
172
178
  openPath: async () => "",
173
179
  showItemInFolder: noop,
@@ -27586,6 +27592,8 @@ __export(settings_exports, {
27586
27592
  readSettings: () => readSettings,
27587
27593
  setRuntimeSettingsOverride: () => setRuntimeSettingsOverride,
27588
27594
  useSafeStorageProvider: () => useSafeStorageProvider,
27595
+ writeProviderKey: () => writeProviderKey,
27596
+ writeProviderSetting: () => writeProviderSetting,
27589
27597
  writeSettings: () => writeSettings
27590
27598
  });
27591
27599
  import fs4 from "node:fs";
@@ -27754,6 +27762,52 @@ function readRawSettingsFile() {
27754
27762
  return null;
27755
27763
  }
27756
27764
  }
27765
+ function writeProviderKey(providerId, key) {
27766
+ const raw = readRawSettingsFile();
27767
+ const value = key?.trim();
27768
+ if (!raw) {
27769
+ if (value) writeSettings({ providerSettings: { [providerId]: { apiKey: { value } } } });
27770
+ return;
27771
+ }
27772
+ const providers = { ...raw.providerSettings ?? {} };
27773
+ const entry = { ...providers[providerId] ?? {} };
27774
+ if (value) entry.apiKey = encrypt(value);
27775
+ else delete entry.apiKey;
27776
+ providers[providerId] = entry;
27777
+ const validated = UserSettingsSchema.parse({ ...DEFAULT_SETTINGS, ...raw, providerSettings: providers });
27778
+ const filePath = getSettingsFilePath();
27779
+ fs4.writeFileSync(filePath, JSON.stringify(validated, null, 2));
27780
+ if (process.platform !== "win32") {
27781
+ try {
27782
+ fs4.chmodSync(filePath, 384);
27783
+ } catch {
27784
+ }
27785
+ }
27786
+ }
27787
+ function writeProviderSetting(providerId, patch) {
27788
+ if ("apiKey" in patch || "serviceAccountKey" in patch) throw new Error("Keys go through writeProviderKey.");
27789
+ const raw = readRawSettingsFile();
27790
+ if (!raw) {
27791
+ writeSettings({ providerSettings: { [providerId]: patch } });
27792
+ return;
27793
+ }
27794
+ const providers = { ...raw.providerSettings ?? {} };
27795
+ const entry = { ...providers[providerId] ?? {} };
27796
+ for (const [k2, v2] of Object.entries(patch)) {
27797
+ if (v2 === null) delete entry[k2];
27798
+ else entry[k2] = v2;
27799
+ }
27800
+ providers[providerId] = entry;
27801
+ const validated = UserSettingsSchema.parse({ ...DEFAULT_SETTINGS, ...raw, providerSettings: providers });
27802
+ const filePath = getSettingsFilePath();
27803
+ fs4.writeFileSync(filePath, JSON.stringify(validated, null, 2));
27804
+ if (process.platform !== "win32") {
27805
+ try {
27806
+ fs4.chmodSync(filePath, 384);
27807
+ } catch {
27808
+ }
27809
+ }
27810
+ }
27757
27811
  function writeSettings(settings) {
27758
27812
  try {
27759
27813
  const filePath = getSettingsFilePath();
@@ -239390,6 +239444,10 @@ function registerWorkspaceSessionHandlers() {
239390
239444
  ).orderBy(desc(chatSessions.updatedAt));
239391
239445
  return rows.map((r3) => mapSession(r3));
239392
239446
  });
239447
+ handle("sessions:list-all", async (_event, limit = 200) => {
239448
+ const rows = await db.select({ session: chatSessions, folder: apps.path, folderName: apps.name }).from(chatSessions).innerJoin(apps, eq(apps.id, chatSessions.workspaceId)).where(eq(chatSessions.kind, "normal")).orderBy(desc(chatSessions.updatedAt)).limit(Math.min(Math.max(1, Number(limit) || 200), 500));
239449
+ return rows.map((r3) => ({ ...mapSession(r3.session), folder: r3.folder, folderName: r3.folderName }));
239450
+ });
239393
239451
  handle(
239394
239452
  "sessions:resolve-for-transport",
239395
239453
  async (_event, payload) => {
@@ -322851,6 +322909,7 @@ function isProtectedRelativePath(relativePath) {
322851
322909
  return !normalizeRelativePath2(relativePath);
322852
322910
  }
322853
322911
  function pathUnderDirectory(filePath, dirScope) {
322912
+ if (dirScope === WHOLE_FOLDER) return !!normalizeRelativePath2(filePath);
322854
322913
  const dir = normalizeRelativePath2(dirScope);
322855
322914
  if (!dir) return false;
322856
322915
  const file2 = normalizeRelativePath2(filePath);
@@ -322964,11 +323023,12 @@ function normalizeScopeValue(scopeType, value) {
322964
323023
  return v2.startsWith(".") ? v2.toLowerCase() : `.${v2.toLowerCase()}`;
322965
323024
  }
322966
323025
  if (scopeType === "directory") {
323026
+ if (v2 === WHOLE_FOLDER) return WHOLE_FOLDER;
322967
323027
  return normalizeRelativePath2(v2.replace(/\/+$/, ""));
322968
323028
  }
322969
323029
  return normalizeRelativePath2(v2);
322970
323030
  }
322971
- var FILE_OPS_WITH_SCOPE;
323031
+ var FILE_OPS_WITH_SCOPE, WHOLE_FOLDER;
322972
323032
  var init_file_permission_scope = __esm({
322973
323033
  "src/lib/file-permission-scope.ts"() {
322974
323034
  FILE_OPS_WITH_SCOPE = /* @__PURE__ */ new Set([
@@ -322976,6 +323036,7 @@ var init_file_permission_scope = __esm({
322976
323036
  "delete_file",
322977
323037
  "rename_file"
322978
323038
  ]);
323039
+ WHOLE_FOLDER = ".";
322979
323040
  }
322980
323041
  });
322981
323042
 
@@ -328480,6 +328541,7 @@ __export(snapshot_manager_exports, {
328480
328541
  captureSnapshotAcrossRoots: () => captureSnapshotAcrossRoots,
328481
328542
  groupPathsByRoot: () => groupPathsByRoot,
328482
328543
  listSnapshotFiles: () => listSnapshotFiles,
328544
+ readSnapshotFile: () => readSnapshotFile,
328483
328545
  revertSnapshot: () => revertSnapshot,
328484
328546
  revertSnapshotFiles: () => revertSnapshotFiles,
328485
328547
  snapshotExists: () => snapshotExists
@@ -328846,6 +328908,21 @@ async function revertSnapshotFiles(params) {
328846
328908
  if (!anyManifest) return { success: false, restoredFiles: 0 };
328847
328909
  return { success: true, restoredFiles: restored };
328848
328910
  }
328911
+ async function readSnapshotFile(params) {
328912
+ const { workspacePath, turnId, relativePath } = params;
328913
+ const seg = sanitizeLedgerDirSegment(turnId);
328914
+ const roots = await turnRoots(workspacePath, turnId);
328915
+ const [group2] = groupPathsByRoot({ workspacePath, paths: [relativePath], grantedRoots: roots });
328916
+ const rel = group2?.relativePaths[0];
328917
+ if (!group2 || !rel) return null;
328918
+ const gitDir = shadowGitDir(group2.root);
328919
+ const manifest = await readManifest(gitDir, seg);
328920
+ if (!manifest) return null;
328921
+ if (manifest.createdFiles.includes(rel)) return { existed: false, content: "" };
328922
+ if (!manifest.filesChanged.includes(rel)) return null;
328923
+ const out = await git(["show", `${turnRef(seg)}:${rel}`], group2.root, gitEnv(gitDir, group2.root));
328924
+ return out.exitCode === 0 ? { existed: true, content: out.stdout } : { existed: false, content: "" };
328925
+ }
328849
328926
  async function snapshotExists(workspacePath, turnId) {
328850
328927
  if (!workspacePath || !turnId) return false;
328851
328928
  const seg = sanitizeLedgerDirSegment(turnId);
@@ -343090,7 +343167,7 @@ ${err2.stack}` : "";
343090
343167
  }
343091
343168
 
343092
343169
  // src/headless/atlarix-headless.mts
343093
- var VERSION15 = false ? "dev" : "15.4.1";
343170
+ var VERSION15 = false ? "dev" : "15.5.0";
343094
343171
  if (process.argv[2] === "run") process.argv.splice(2, 1);
343095
343172
  function arg(name29) {
343096
343173
  const i4 = process.argv.indexOf(`--${name29}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atlarix",
3
- "version": "15.4.1",
3
+ "version": "15.5.0",
4
4
  "description": "Atlarix CLI: an AI coding agent in your terminal. Works with any model (Atlarix Auto, your own API key, or a local model) and runs unattended with `atlarix run` for CI.",
5
5
  "license": "PROPRIETARY",
6
6
  "author": {
@@ -65,12 +65,12 @@
65
65
  "provenance": false
66
66
  },
67
67
  "optionalDependencies": {
68
- "atlarix-darwin-arm64": "15.4.1",
69
- "atlarix-darwin-x64": "15.4.1",
70
- "atlarix-linux-x64": "15.4.1",
71
- "atlarix-linux-arm64": "15.4.1",
72
- "atlarix-linux-x64-musl": "15.4.1",
73
- "atlarix-linux-arm64-musl": "15.4.1",
74
- "atlarix-windows-x64": "15.4.1"
68
+ "atlarix-darwin-arm64": "15.5.0",
69
+ "atlarix-darwin-x64": "15.5.0",
70
+ "atlarix-linux-x64": "15.5.0",
71
+ "atlarix-linux-arm64": "15.5.0",
72
+ "atlarix-linux-x64-musl": "15.5.0",
73
+ "atlarix-linux-arm64-musl": "15.5.0",
74
+ "atlarix-windows-x64": "15.5.0"
75
75
  }
76
76
  }