amalgm 0.1.58 → 0.1.60

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.
@@ -99,7 +99,7 @@ function listProcProcesses() {
99
99
  pid,
100
100
  ppid: readProcPpid(pid),
101
101
  command: readProcCommand(pid),
102
- env: readProcEnv(pid),
102
+ env: null,
103
103
  }))
104
104
  .filter((item) => item.command);
105
105
  } catch {
@@ -141,6 +141,14 @@ function listProcesses() {
141
141
  }));
142
142
  }
143
143
 
144
+ function withEnv(item) {
145
+ if (!item || item.env) return item;
146
+ return {
147
+ ...item,
148
+ env: readProcEnv(item.pid),
149
+ };
150
+ }
151
+
144
152
  function normalizedCommand(command) {
145
153
  return String(command || '').replace(/\\/g, '/');
146
154
  }
@@ -195,6 +203,7 @@ function runtimeServiceProcesses(options = {}) {
195
203
  return listProcesses()
196
204
  .filter((item) => !exclude.has(item.pid))
197
205
  .filter((item) => commandLooksLikeRuntimeService(item.command, item, options))
206
+ .map(withEnv)
198
207
  .filter((item) => envMatchesAmalgmDir(item.env));
199
208
  }
200
209
 
@@ -203,6 +212,7 @@ function supervisorProcesses(options = {}) {
203
212
  return listProcesses()
204
213
  .filter((item) => !exclude.has(item.pid))
205
214
  .filter((item) => commandLooksLikeSupervisor(item.command))
215
+ .map(withEnv)
206
216
  .filter((item) => envMatchesAmalgmDir(item.env));
207
217
  }
208
218
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amalgm",
3
- "version": "0.1.58",
3
+ "version": "0.1.60",
4
4
  "description": "Amalgm local computer runtime: login, MCP, chat, events, previews, and tunnels.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -5,9 +5,13 @@
5
5
  * for task/event/agent runs without requiring the caller to specify it.
6
6
  */
7
7
 
8
+ const fs = require('fs');
8
9
  const { openLocalDb } = require('../state/db');
9
10
  const { insertStateEvent, publishStateEvent } = require('../state/events');
10
- const { canonicalProjectPath } = require('../../lib/project-paths');
11
+ const {
12
+ canonicalProjectPath,
13
+ isWorkspaceRootPath,
14
+ } = require('../../lib/project-paths');
11
15
 
12
16
  const DEFAULT_SELECTED_MODELS = {
13
17
  claude_code: 'anthropic/claude-opus-4.7',
@@ -351,6 +355,26 @@ function reasoningEffortForSelection(harnessId, modelId, normalizedEffort) {
351
355
  return normalizeReasoningEffort(settings.effort || settings.reasoningEffort || settings.reasoning) || 'xhigh';
352
356
  }
353
357
 
358
+ function preferredWorkspaceCwd() {
359
+ try {
360
+ const { listWorkspaces } = require('../workspace/store');
361
+ const workspaces = listWorkspaces()
362
+ .filter((workspace) => workspace?.path && fs.existsSync(workspace.path));
363
+ const ready = workspaces.find((workspace) => workspace.status === 'ready');
364
+ return ready?.path || workspaces[0]?.path || '';
365
+ } catch {
366
+ return '';
367
+ }
368
+ }
369
+
370
+ function normalizePreferenceCwd(value) {
371
+ const localPath = canonicalProjectPath(cleanString(value));
372
+ if (!localPath) return '';
373
+ if (isWorkspaceRootPath(localPath)) return preferredWorkspaceCwd() || '';
374
+ if (fs.existsSync(localPath)) return localPath;
375
+ return preferredWorkspaceCwd() || '';
376
+ }
377
+
354
378
  function normalizePreferences(input) {
355
379
  const raw = isPlainObject(input) ? input : {};
356
380
  const rawRecentPrefs = isPlainObject(raw.recent_prefs) ? raw.recent_prefs : {};
@@ -383,7 +407,7 @@ function normalizePreferences(input) {
383
407
  last_used: {
384
408
  harness: lastUsedHarness,
385
409
  model: lastUsedModel,
386
- cwd: canonicalProjectPath(cleanString(rawLastUsed.cwd ?? raw.last_cwd ?? raw.selected_cwd)),
410
+ cwd: normalizePreferenceCwd(rawLastUsed.cwd ?? raw.last_cwd ?? raw.selected_cwd),
387
411
  },
388
412
  usage,
389
413
  recent_prefs: recentPrefs,
@@ -32,6 +32,21 @@ function legacyWorkspaceRoots() {
32
32
  .map((entry) => path.resolve(expandHome(entry)));
33
33
  }
34
34
 
35
+ function workspaceRootPaths() {
36
+ const home = process.env.AMALGM_HOME || path.join(os.homedir(), '.amalgm');
37
+ const stateRoot = process.env.AMALGM_DIR;
38
+ return [
39
+ process.env.AMALGM_WORKSPACES_DIR,
40
+ process.env.AMALGM_PROJECTS_DIR,
41
+ stateRoot && path.join(stateRoot, 'workspaces'),
42
+ stateRoot && path.join(stateRoot, 'projects'),
43
+ path.join(home, 'workspaces'),
44
+ path.join(home, 'projects'),
45
+ ]
46
+ .filter(Boolean)
47
+ .map((entry) => path.resolve(expandHome(entry)));
48
+ }
49
+
35
50
  function legacyManagedRelativePath(localPath) {
36
51
  const resolved = path.resolve(expandHome(localPath));
37
52
  const currentRoot = cleanString(process.env.AMALGM_WORKSPACES_DIR || process.env.AMALGM_PROJECTS_DIR);
@@ -64,9 +79,17 @@ function isLegacyManagedWorkspacePath(value) {
64
79
  return Boolean(cleanString(value) && legacyManagedRelativePath(value));
65
80
  }
66
81
 
82
+ function isWorkspaceRootPath(value) {
83
+ const expanded = expandHome(value);
84
+ if (!expanded) return false;
85
+ const resolved = path.resolve(expanded);
86
+ return workspaceRootPaths().some((root) => path.resolve(root) === resolved);
87
+ }
88
+
67
89
  module.exports = {
68
90
  canonicalProjectPath,
69
91
  cleanString,
70
92
  expandHome,
71
93
  isLegacyManagedWorkspacePath,
94
+ isWorkspaceRootPath,
72
95
  };