@fml-inc/fml 0.8.12-rc.1 → 0.8.13-rc.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.
@@ -10,7 +10,7 @@ var __export = (target, all) => {
10
10
 
11
11
  // src/dirs.ts
12
12
  import os from "node:os";
13
- import path14 from "node:path";
13
+ import path15 from "node:path";
14
14
  function isPresent(value) {
15
15
  return value !== void 0 && value.trim().length > 0;
16
16
  }
@@ -31,7 +31,7 @@ function platformBaseDirectory(value, pathApi) {
31
31
  function resolveFmlDirectories(options = {}) {
32
32
  const platform = options.platform ?? process.platform;
33
33
  const env = options.env ?? process.env;
34
- const pathApi = platform === "win32" ? path14.win32 : path14.posix;
34
+ const pathApi = platform === "win32" ? path15.win32 : path15.posix;
35
35
  const homeDir = normalizeAbsolutePath(
36
36
  options.homeDir ?? os.homedir(),
37
37
  "home directory",
@@ -123,41 +123,41 @@ var init_dirs = __esm({
123
123
  FML_LOG_DIR = DIRECTORIES.logDir;
124
124
  FML_OBSERVER_DIR = DIRECTORIES.observerDir;
125
125
  FML_OBSERVER_PORT = observerPort();
126
- FML_OBSERVER_STATE_FILE = path14.join(
126
+ FML_OBSERVER_STATE_FILE = path15.join(
127
127
  FML_OBSERVER_DIR,
128
128
  "observer.pid.json"
129
129
  );
130
- FML_OBSERVER_LOCK_FILE = path14.join(
130
+ FML_OBSERVER_LOCK_FILE = path15.join(
131
131
  FML_OBSERVER_DIR,
132
132
  "observer.lock"
133
133
  );
134
- FML_OBSERVER_AUTH_TOKEN_FILE = path14.join(
134
+ FML_OBSERVER_AUTH_TOKEN_FILE = path15.join(
135
135
  FML_OBSERVER_DIR,
136
136
  "auth-token"
137
137
  );
138
- FML_OBSERVER_ENDPOINT_FILE = path14.join(
138
+ FML_OBSERVER_ENDPOINT_FILE = path15.join(
139
139
  FML_OBSERVER_DIR,
140
140
  "endpoint.json"
141
141
  );
142
- FML_OBSERVER_LOG_FILE = path14.join(FML_LOG_DIR, "observer.log");
143
- FML_UPDATE_LOG_FILE = path14.join(FML_LOG_DIR, "update.log");
144
- FML_INSTALLATION_ID_FILE = path14.join(
142
+ FML_OBSERVER_LOG_FILE = path15.join(FML_LOG_DIR, "observer.log");
143
+ FML_UPDATE_LOG_FILE = path15.join(FML_LOG_DIR, "update.log");
144
+ FML_INSTALLATION_ID_FILE = path15.join(
145
145
  FML_STATE_DIR,
146
146
  "installation_id"
147
147
  );
148
- FML_PANOPTICON_DB_FILE = path14.join(FML_STATE_DIR, "panopticon.db");
148
+ FML_PANOPTICON_DB_FILE = path15.join(FML_STATE_DIR, "panopticon.db");
149
149
  FML_PANOPTICON_DB_OBSERVER_STATE_FILE = `${FML_PANOPTICON_DB_FILE}.observer.pid.json`;
150
150
  FML_PANOPTICON_DB_OBSERVER_LOCK_FILE = `${FML_PANOPTICON_DB_FILE}.observer.lock`;
151
- FML_LEGACY_OBSERVER_DB_FILE = path14.join(
151
+ FML_LEGACY_OBSERVER_DB_FILE = path15.join(
152
152
  FML_OBSERVER_DIR,
153
153
  "observer.db"
154
154
  );
155
- FML_HOOK_INBOX_DIR = path14.join(FML_OBSERVER_DIR, "hook-inbox");
156
- FML_HOOK_CONTEXT_STATE_DIR = path14.join(
155
+ FML_HOOK_INBOX_DIR = path15.join(FML_OBSERVER_DIR, "hook-inbox");
156
+ FML_HOOK_CONTEXT_STATE_DIR = path15.join(
157
157
  FML_OBSERVER_DIR,
158
158
  "hook-context-state"
159
159
  );
160
- FML_HOOK_CAPTURE_DISABLED_FILE = path14.join(
160
+ FML_HOOK_CAPTURE_DISABLED_FILE = path15.join(
161
161
  FML_OBSERVER_DIR,
162
162
  "hook-capture.disabled"
163
163
  );
@@ -166,7 +166,7 @@ var init_dirs = __esm({
166
166
 
167
167
  // src/config.ts
168
168
  import fs6 from "node:fs";
169
- import path15 from "node:path";
169
+ import path16 from "node:path";
170
170
  function isHostedBackendUrl(url2) {
171
171
  let normalized;
172
172
  try {
@@ -256,7 +256,7 @@ function getActiveEnv() {
256
256
  return { name, convexUrl, appUrl };
257
257
  }
258
258
  function authStorePathFor(envName) {
259
- return path15.join(FML_DATA_DIR, `auth.${envName}.json`);
259
+ return path16.join(FML_DATA_DIR, `auth.${envName}.json`);
260
260
  }
261
261
  function getSiteUrlForConvexUrl(convexUrl) {
262
262
  const explicit = process.env.CONVEX_SITE_URL;
@@ -274,7 +274,7 @@ var init_config = __esm({
274
274
  LEGACY_HOSTED_BACKEND_URLS = [
275
275
  "https://trustworthy-chihuahua-382.convex.site"
276
276
  ];
277
- ENV_CONFIG_PATH = path15.join(FML_DATA_DIR, "env.json");
277
+ ENV_CONFIG_PATH = path16.join(FML_DATA_DIR, "env.json");
278
278
  ENV_NAME_RE = /^[A-Za-z0-9_-]+$/;
279
279
  CONVEX_URL = (process.env.FML_CONVEX_URL ?? getActiveEnv().convexUrl ?? DEFAULT_PROD_URL).replace(/\/$/, "");
280
280
  WORKOS_API_URL = "https://api.workos.com";
@@ -309,7 +309,7 @@ __export(telemetry_config_exports, {
309
309
  });
310
310
  import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
311
311
  import fs7 from "node:fs";
312
- import path16 from "node:path";
312
+ import path17 from "node:path";
313
313
  function parseSentryConfig(value) {
314
314
  if (value === null) return null;
315
315
  if (!value || typeof value !== "object")
@@ -330,7 +330,7 @@ function parseSentryConfig(value) {
330
330
  }
331
331
  function cachePathFor(siteUrl) {
332
332
  const key = isHostedBackendUrl(siteUrl) ? DEFAULT_SYNC_URL : siteUrl;
333
- return path16.join(
333
+ return path17.join(
334
334
  FML_DATA_DIR,
335
335
  "telemetry-config",
336
336
  `${createHash3("sha256").update(key).digest("hex")}.json`
@@ -358,7 +358,7 @@ function writeCache(entry) {
358
358
  const cachePath = cachePathFor(entry.siteUrl);
359
359
  const temporaryPath = `${cachePath}.${randomUUID2()}.tmp`;
360
360
  try {
361
- fs7.mkdirSync(path16.dirname(cachePath), { recursive: true, mode: 448 });
361
+ fs7.mkdirSync(path17.dirname(cachePath), { recursive: true, mode: 448 });
362
362
  fs7.writeFileSync(temporaryPath, JSON.stringify(entry), { mode: 384 });
363
363
  fs7.renameSync(temporaryPath, cachePath);
364
364
  } catch {
@@ -453,7 +453,7 @@ var init_telemetry_config = __esm({
453
453
  import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
454
454
  import { execFileSync } from "node:child_process";
455
455
  import fs8 from "node:fs";
456
- import path17 from "node:path";
456
+ import path18 from "node:path";
457
457
  function getCurrentProcessIdentity() {
458
458
  let cache = processGlobals[PROCESS_IDENTITY_KEY];
459
459
  if (!cache) {
@@ -473,7 +473,7 @@ function resolveEnvName(envName) {
473
473
  return envName ?? getActiveEnv().name;
474
474
  }
475
475
  function ensureDir(envName) {
476
- const dir = path17.dirname(storePathFor(envName));
476
+ const dir = path18.dirname(storePathFor(envName));
477
477
  fs8.mkdirSync(dir, { recursive: true, mode: 448 });
478
478
  try {
479
479
  fs8.chmodSync(dir, 448);
@@ -639,7 +639,7 @@ function refreshLockPath(envName) {
639
639
  return `${storePathFor(envName)}.refresh.lock`;
640
640
  }
641
641
  function pendingOAuthRefreshPrefix(envName) {
642
- return `${path17.basename(storePathFor(envName))}.refresh-result.`;
642
+ return `${path18.basename(storePathFor(envName))}.refresh-result.`;
643
643
  }
644
644
  function parsePendingOAuthRefresh(raw) {
645
645
  try {
@@ -679,11 +679,11 @@ function removePendingOAuthRefresh(resultPath) {
679
679
  }
680
680
  function reconcilePendingOAuthRefreshes(envName, unreadableStorePolicy = "preserve-staged") {
681
681
  const storePath = storePathFor(envName);
682
- const directory = path17.dirname(storePath);
682
+ const directory = path18.dirname(storePath);
683
683
  const prefix = pendingOAuthRefreshPrefix(envName);
684
684
  let resultPaths;
685
685
  try {
686
- resultPaths = fs8.readdirSync(directory).filter((entry) => entry.startsWith(prefix) && entry.endsWith(".json")).map((entry) => path17.join(directory, entry));
686
+ resultPaths = fs8.readdirSync(directory).filter((entry) => entry.startsWith(prefix) && entry.endsWith(".json")).map((entry) => path18.join(directory, entry));
687
687
  } catch (error62) {
688
688
  if (error62.code === "ENOENT") return;
689
689
  throw error62;
@@ -807,7 +807,7 @@ function snapshotLeaseFile(filePath) {
807
807
  try {
808
808
  return {
809
809
  stat,
810
- raw: fs8.readFileSync(path17.join(filePath, "owner.json"), "utf8")
810
+ raw: fs8.readFileSync(path18.join(filePath, "owner.json"), "utf8")
811
811
  };
812
812
  } catch (error62) {
813
813
  if (error62.code === "ENOENT") {
@@ -1616,26 +1616,41 @@ var init_token_store = __esm({
1616
1616
  import { randomUUID as randomUUID4 } from "node:crypto";
1617
1617
  import fs9 from "node:fs";
1618
1618
  import os2 from "node:os";
1619
- import path19 from "node:path";
1619
+ import path20 from "node:path";
1620
+
1621
+ // ../../packages/agent-targets/src/pi-agent-dir.ts
1622
+ import path from "node:path";
1623
+ function resolvePiAgentDir(context) {
1624
+ const pathApi = (context.platform ?? process.platform) === "win32" ? path.win32 : path.posix;
1625
+ const configured = context.env.PI_CODING_AGENT_DIR?.trim();
1626
+ if (!configured) {
1627
+ return pathApi.join(context.homeDir, ".pi", "agent");
1628
+ }
1629
+ if (configured === "~") return context.homeDir;
1630
+ if (configured.startsWith("~/") || configured.startsWith("~\\")) {
1631
+ return pathApi.join(context.homeDir, configured.slice(2));
1632
+ }
1633
+ return pathApi.normalize(configured);
1634
+ }
1620
1635
 
1621
1636
  // ../../packages/agent-targets/src/artifacts/targets/claude.ts
1622
- import path3 from "node:path";
1637
+ import path4 from "node:path";
1623
1638
 
1624
1639
  // ../../packages/agent-targets/src/config-paths.ts
1625
- import path from "node:path";
1640
+ import path2 from "node:path";
1626
1641
  function claudeConfigDirectory(context) {
1627
1642
  const configuredDir = context.claudeConfigDir ?? context.env?.CLAUDE_CONFIG_DIR;
1628
- return typeof configuredDir === "string" && configuredDir.trim().length > 0 ? path.resolve(configuredDir) : path.join(context.homeDir, ".claude");
1643
+ return typeof configuredDir === "string" && configuredDir.trim().length > 0 ? path2.resolve(configuredDir) : path2.join(context.homeDir, ".claude");
1629
1644
  }
1630
1645
  function geminiConfigDirectory(context) {
1631
1646
  const configuredHome = context.env.GEMINI_CLI_HOME;
1632
- const homeRoot = typeof configuredHome === "string" && configuredHome.trim().length > 0 ? path.resolve(configuredHome) : context.homeDir;
1633
- return path.join(homeRoot, ".gemini");
1647
+ const homeRoot = typeof configuredHome === "string" && configuredHome.trim().length > 0 ? path2.resolve(configuredHome) : context.homeDir;
1648
+ return path2.join(homeRoot, ".gemini");
1634
1649
  }
1635
1650
 
1636
1651
  // ../../packages/agent-targets/src/artifacts/filesystem.ts
1637
1652
  import fs from "node:fs";
1638
- import path2 from "node:path";
1653
+ import path3 from "node:path";
1639
1654
  var DEFAULT_SKIP_DIRS = /* @__PURE__ */ new Set([
1640
1655
  "node_modules",
1641
1656
  "dist",
@@ -1652,7 +1667,7 @@ var DEFAULT_SKIP_DIRS = /* @__PURE__ */ new Set([
1652
1667
  "designqc-captures"
1653
1668
  ]);
1654
1669
  function normalizeFilePath(filePath) {
1655
- return path2.resolve(filePath);
1670
+ return path3.resolve(filePath);
1656
1671
  }
1657
1672
  function safeReaddir(dir) {
1658
1673
  try {
@@ -1669,7 +1684,7 @@ function walkFiles(input2) {
1669
1684
  function walk(dir, depth) {
1670
1685
  if (depth > input2.maxDepth) return;
1671
1686
  for (const entry of safeReaddir(dir)) {
1672
- const entryPath = path2.join(dir, entry.name);
1687
+ const entryPath = path3.join(dir, entry.name);
1673
1688
  if (entry.isDirectory()) {
1674
1689
  if (!skipDirs.has(entry.name)) walk(entryPath, depth + 1);
1675
1690
  continue;
@@ -1941,9 +1956,9 @@ var claudeArtifactDiscovery = Object.freeze({
1941
1956
  discover: (context) => {
1942
1957
  const { homeDir, env } = context;
1943
1958
  const configDir = claudeConfigDirectory({ homeDir, env });
1944
- const harnessInstallId = readClaudeMachineId(path3.join(configDir, ".claude.json")) ?? readClaudeMachineId(path3.join(homeDir, ".claude.json"));
1959
+ const harnessInstallId = readClaudeMachineId(path4.join(configDir, ".claude.json")) ?? readClaudeMachineId(path4.join(homeDir, ".claude.json"));
1945
1960
  return walkFiles({
1946
- root: path3.join(configDir, "projects"),
1961
+ root: path4.join(configDir, "projects"),
1947
1962
  maxDepth: 6,
1948
1963
  includeFile: (filePath) => filePath.endsWith(".jsonl")
1949
1964
  }).map(
@@ -1953,10 +1968,10 @@ var claudeArtifactDiscovery = Object.freeze({
1953
1968
  });
1954
1969
 
1955
1970
  // ../../packages/agent-targets/src/artifacts/targets/codex.ts
1956
- import path4 from "node:path";
1971
+ import path5 from "node:path";
1957
1972
  var CODEX_ROLLOUT_ID = /-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl(?:\.zst)?$/i;
1958
1973
  function codexRolloutId(sourcePath) {
1959
- return CODEX_ROLLOUT_ID.exec(path4.basename(sourcePath))?.[1]?.toLowerCase() ?? null;
1974
+ return CODEX_ROLLOUT_ID.exec(path5.basename(sourcePath))?.[1]?.toLowerCase() ?? null;
1960
1975
  }
1961
1976
  function codexTranscriptCandidate(sourcePath, readPath, store, context, harnessInstallId) {
1962
1977
  const rolloutId = codexRolloutId(sourcePath);
@@ -2026,15 +2041,15 @@ var codexArtifactDiscovery = Object.freeze({
2026
2041
  discover: (context) => {
2027
2042
  const { homeDir, env } = context;
2028
2043
  const configuredHome = env.CODEX_HOME?.trim();
2029
- const codexHome = configuredHome ? path4.resolve(configuredHome) : path4.join(homeDir, ".codex");
2044
+ const codexHome = configuredHome ? path5.resolve(configuredHome) : path5.join(homeDir, ".codex");
2030
2045
  const harnessInstallId = readHarnessInstallIdFile(
2031
- path4.join(codexHome, "installation_id")
2046
+ path5.join(codexHome, "installation_id")
2032
2047
  );
2033
2048
  const roots = [
2034
- { store: "sessions", root: path4.join(codexHome, "sessions") },
2049
+ { store: "sessions", root: path5.join(codexHome, "sessions") },
2035
2050
  {
2036
2051
  store: "archived_sessions",
2037
- root: path4.join(codexHome, "archived_sessions")
2052
+ root: path5.join(codexHome, "archived_sessions")
2038
2053
  }
2039
2054
  ];
2040
2055
  const files = roots.flatMap(
@@ -2072,27 +2087,27 @@ var codexArtifactDiscovery = Object.freeze({
2072
2087
  });
2073
2088
 
2074
2089
  // ../../packages/agent-targets/src/artifacts/targets/copilot-cli.ts
2075
- import path5 from "node:path";
2090
+ import path6 from "node:path";
2076
2091
  var copilotCliArtifactDiscovery = Object.freeze({
2077
2092
  targetId: "copilot-cli",
2078
2093
  discover: ({ homeDir }) => walkFiles({
2079
- root: path5.join(homeDir, ".copilot", "session-state"),
2094
+ root: path6.join(homeDir, ".copilot", "session-state"),
2080
2095
  maxDepth: 3,
2081
- includeFile: (filePath) => path5.basename(filePath) === "events.jsonl"
2096
+ includeFile: (filePath) => path6.basename(filePath) === "events.jsonl"
2082
2097
  }).map(
2083
2098
  (sourcePath) => transcriptCandidate({ targetId: "copilot-cli", sourcePath })
2084
2099
  )
2085
2100
  });
2086
2101
 
2087
2102
  // ../../packages/agent-targets/src/artifacts/targets/cursor.ts
2088
- import path6 from "node:path";
2103
+ import path7 from "node:path";
2089
2104
  function hasPathSegment(filePath, segment) {
2090
- return normalizeFilePath(filePath).split(path6.sep).includes(segment);
2105
+ return normalizeFilePath(filePath).split(path7.sep).includes(segment);
2091
2106
  }
2092
2107
  var cursorArtifactDiscovery = Object.freeze({
2093
2108
  targetId: "cursor",
2094
2109
  discover: ({ homeDir }) => walkFiles({
2095
- root: path6.join(homeDir, ".cursor", "projects"),
2110
+ root: path7.join(homeDir, ".cursor", "projects"),
2096
2111
  maxDepth: 5,
2097
2112
  includeFile: (filePath) => filePath.endsWith(".jsonl") && hasPathSegment(filePath, "agent-transcripts")
2098
2113
  }).map(
@@ -2101,11 +2116,11 @@ var cursorArtifactDiscovery = Object.freeze({
2101
2116
  });
2102
2117
 
2103
2118
  // ../../packages/agent-targets/src/artifacts/targets/factory-droid.ts
2104
- import path7 from "node:path";
2119
+ import path8 from "node:path";
2105
2120
  var factoryDroidArtifactDiscovery = Object.freeze({
2106
2121
  targetId: "factory-droid",
2107
2122
  discover: ({ homeDir }) => walkFiles({
2108
- root: path7.join(homeDir, ".factory", "sessions"),
2123
+ root: path8.join(homeDir, ".factory", "sessions"),
2109
2124
  maxDepth: 4,
2110
2125
  includeFile: (filePath) => filePath.endsWith(".jsonl")
2111
2126
  }).map(
@@ -2114,7 +2129,7 @@ var factoryDroidArtifactDiscovery = Object.freeze({
2114
2129
  });
2115
2130
 
2116
2131
  // ../../packages/agent-targets/src/artifacts/targets/gemini.ts
2117
- import path8 from "node:path";
2132
+ import path9 from "node:path";
2118
2133
  var GEMINI_DISCOVER_SKIP_DIRS = /* @__PURE__ */ new Set([
2119
2134
  "bin",
2120
2135
  "checkpoints",
@@ -2129,15 +2144,15 @@ var geminiArtifactDiscovery = Object.freeze({
2129
2144
  discover: ({ homeDir, env }) => {
2130
2145
  const geminiDir = geminiConfigDirectory({ homeDir, env });
2131
2146
  const harnessInstallId = readHarnessInstallIdFile(
2132
- path8.join(geminiDir, "installation_id")
2147
+ path9.join(geminiDir, "installation_id")
2133
2148
  );
2134
- const root = path8.join(geminiDir, "tmp");
2149
+ const root = path9.join(geminiDir, "tmp");
2135
2150
  const files = [];
2136
2151
  const seen = /* @__PURE__ */ new Set();
2137
2152
  function walk(dir, depth) {
2138
2153
  if (depth > 4) return;
2139
2154
  for (const entry of safeReaddir(dir)) {
2140
- const entryPath = path8.join(dir, entry.name);
2155
+ const entryPath = path9.join(dir, entry.name);
2141
2156
  if (!entry.isDirectory()) continue;
2142
2157
  if (GEMINI_DISCOVER_SKIP_DIRS.has(entry.name)) continue;
2143
2158
  if (entry.name === "chats") {
@@ -2146,7 +2161,7 @@ var geminiArtifactDiscovery = Object.freeze({
2146
2161
  continue;
2147
2162
  }
2148
2163
  const sourcePath = normalizeFilePath(
2149
- path8.join(entryPath, chatEntry.name)
2164
+ path9.join(entryPath, chatEntry.name)
2150
2165
  );
2151
2166
  if (seen.has(sourcePath)) continue;
2152
2167
  seen.add(sourcePath);
@@ -2169,17 +2184,17 @@ var geminiArtifactDiscovery = Object.freeze({
2169
2184
  });
2170
2185
 
2171
2186
  // ../../packages/agent-targets/src/artifacts/targets/grok.ts
2172
- import path9 from "node:path";
2187
+ import path10 from "node:path";
2173
2188
  function grokHome(homeDir, env) {
2174
2189
  const configuredHome = env.GROK_HOME?.trim();
2175
- return configuredHome ? path9.resolve(configuredHome) : path9.join(homeDir, ".grok");
2190
+ return configuredHome ? path10.resolve(configuredHome) : path10.join(homeDir, ".grok");
2176
2191
  }
2177
2192
  var grokArtifactDiscovery = Object.freeze({
2178
2193
  targetId: "grok",
2179
2194
  discover: ({ homeDir, env }) => walkFiles({
2180
- root: path9.join(grokHome(homeDir, env), "sessions"),
2195
+ root: path10.join(grokHome(homeDir, env), "sessions"),
2181
2196
  maxDepth: 5,
2182
- includeFile: (filePath) => path9.basename(filePath) === "updates.jsonl"
2197
+ includeFile: (filePath) => path10.basename(filePath) === "updates.jsonl"
2183
2198
  }).map(
2184
2199
  (sourcePath) => transcriptCandidate({ targetId: "grok", sourcePath })
2185
2200
  )
@@ -2187,24 +2202,24 @@ var grokArtifactDiscovery = Object.freeze({
2187
2202
 
2188
2203
  // ../../packages/agent-targets/src/artifacts/targets/mini-swe-agent.ts
2189
2204
  import fs4 from "node:fs";
2190
- import path10 from "node:path";
2205
+ import path11 from "node:path";
2191
2206
  var SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2192
2207
  function dataDirectory({ homeDir, env }) {
2193
2208
  if (env.FML_DATA_DIR?.trim()) {
2194
- if (!path10.isAbsolute(env.FML_DATA_DIR)) {
2209
+ if (!path11.isAbsolute(env.FML_DATA_DIR)) {
2195
2210
  throw new Error("FML_DATA_DIR must be an absolute path");
2196
2211
  }
2197
- return path10.normalize(env.FML_DATA_DIR);
2212
+ return path11.normalize(env.FML_DATA_DIR);
2198
2213
  }
2199
2214
  if (process.platform === "darwin") {
2200
- return path10.join(homeDir, "Library", "Application Support", "fml");
2215
+ return path11.join(homeDir, "Library", "Application Support", "fml");
2201
2216
  }
2202
2217
  if (process.platform === "win32") {
2203
- const roaming = env.APPDATA && path10.isAbsolute(env.APPDATA) ? env.APPDATA : path10.join(homeDir, "AppData", "Roaming");
2204
- return path10.join(roaming, "fml");
2218
+ const roaming = env.APPDATA && path11.isAbsolute(env.APPDATA) ? env.APPDATA : path11.join(homeDir, "AppData", "Roaming");
2219
+ return path11.join(roaming, "fml");
2205
2220
  }
2206
- const xdgDataHome = env.XDG_DATA_HOME && path10.isAbsolute(env.XDG_DATA_HOME) ? env.XDG_DATA_HOME : path10.join(homeDir, ".local", "share");
2207
- return path10.join(xdgDataHome, "fml");
2221
+ const xdgDataHome = env.XDG_DATA_HOME && path11.isAbsolute(env.XDG_DATA_HOME) ? env.XDG_DATA_HOME : path11.join(homeDir, ".local", "share");
2222
+ return path11.join(xdgDataHome, "fml");
2208
2223
  }
2209
2224
  function snapshotCandidate(sourcePath, context) {
2210
2225
  let file2;
@@ -2268,7 +2283,7 @@ function snapshotCandidate(sourcePath, context) {
2268
2283
  var miniSweAgentArtifactDiscovery = Object.freeze({
2269
2284
  targetId: "mini-swe-agent",
2270
2285
  discover: (context) => walkFiles({
2271
- root: path10.join(dataDirectory(context), "mini-swe-agent", "trajectories"),
2286
+ root: path11.join(dataDirectory(context), "mini-swe-agent", "trajectories"),
2272
2287
  maxDepth: 0,
2273
2288
  includeFile: (filePath) => filePath.endsWith(".traj.json")
2274
2289
  }).flatMap((sourcePath) => {
@@ -2278,7 +2293,7 @@ var miniSweAgentArtifactDiscovery = Object.freeze({
2278
2293
  });
2279
2294
 
2280
2295
  // ../../packages/agent-targets/src/artifacts/targets/pi.ts
2281
- import path11 from "node:path";
2296
+ import path12 from "node:path";
2282
2297
 
2283
2298
  // ../../node_modules/.pnpm/zod@4.6.6/node_modules/zod/v4/classic/external.js
2284
2299
  var external_exports = {};
@@ -3097,10 +3112,10 @@ function mergeDefs(...defs) {
3097
3112
  function cloneDef(schema) {
3098
3113
  return mergeDefs(schema._zod.def);
3099
3114
  }
3100
- function getElementAtPath(obj, path20) {
3101
- if (!path20)
3115
+ function getElementAtPath(obj, path21) {
3116
+ if (!path21)
3102
3117
  return obj;
3103
- return path20.reduce((acc, key) => acc?.[key], obj);
3118
+ return path21.reduce((acc, key) => acc?.[key], obj);
3104
3119
  }
3105
3120
  function promiseAllObject(promisesObj) {
3106
3121
  const keys = Object.keys(promisesObj);
@@ -3440,11 +3455,11 @@ function explicitlyAborted(x, startIndex = 0) {
3440
3455
  }
3441
3456
  return false;
3442
3457
  }
3443
- function prefixIssues(path20, issues) {
3458
+ function prefixIssues(path21, issues) {
3444
3459
  return issues.map((iss) => {
3445
3460
  var _a3;
3446
3461
  (_a3 = iss).path ?? (_a3.path = []);
3447
- iss.path.unshift(path20);
3462
+ iss.path.unshift(path21);
3448
3463
  return iss;
3449
3464
  });
3450
3465
  }
@@ -3906,16 +3921,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
3906
3921
  }
3907
3922
  function formatError(error62, mapper = (issue2) => issue2.message) {
3908
3923
  const fieldErrors = { _errors: [] };
3909
- const processError = (error63, path20 = []) => {
3924
+ const processError = (error63, path21 = []) => {
3910
3925
  for (const issue2 of error63.issues) {
3911
3926
  if (issue2.code === "invalid_union" && issue2.errors.length) {
3912
- issue2.errors.map((issues) => processError({ issues }, [...path20, ...issue2.path]));
3927
+ issue2.errors.map((issues) => processError({ issues }, [...path21, ...issue2.path]));
3913
3928
  } else if (issue2.code === "invalid_key") {
3914
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
3929
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
3915
3930
  } else if (issue2.code === "invalid_element") {
3916
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
3931
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
3917
3932
  } else {
3918
- const fullpath = [...path20, ...issue2.path];
3933
+ const fullpath = [...path21, ...issue2.path];
3919
3934
  if (fullpath.length === 0) {
3920
3935
  fieldErrors._errors.push(mapper(issue2));
3921
3936
  } else {
@@ -3954,17 +3969,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
3954
3969
  }
3955
3970
  function treeifyError(error62, mapper = (issue2) => issue2.message) {
3956
3971
  const result = { errors: [] };
3957
- const processError = (error63, path20 = []) => {
3972
+ const processError = (error63, path21 = []) => {
3958
3973
  var _a3;
3959
3974
  for (const issue2 of error63.issues) {
3960
3975
  if (issue2.code === "invalid_union" && issue2.errors.length) {
3961
- issue2.errors.map((issues) => processError({ issues }, [...path20, ...issue2.path]));
3976
+ issue2.errors.map((issues) => processError({ issues }, [...path21, ...issue2.path]));
3962
3977
  } else if (issue2.code === "invalid_key") {
3963
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
3978
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
3964
3979
  } else if (issue2.code === "invalid_element") {
3965
- processError({ issues: issue2.issues }, [...path20, ...issue2.path]);
3980
+ processError({ issues: issue2.issues }, [...path21, ...issue2.path]);
3966
3981
  } else {
3967
- const fullpath = [...path20, ...issue2.path];
3982
+ const fullpath = [...path21, ...issue2.path];
3968
3983
  if (fullpath.length === 0) {
3969
3984
  result.errors.push(mapper(issue2));
3970
3985
  continue;
@@ -4003,8 +4018,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
4003
4018
  }
4004
4019
  function toDotPath(_path) {
4005
4020
  const segs = [];
4006
- const path20 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
4007
- for (const seg of path20) {
4021
+ const path21 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
4022
+ for (const seg of path21) {
4008
4023
  if (typeof seg === "number")
4009
4024
  segs.push(`[${seg}]`);
4010
4025
  else if (typeof seg === "symbol")
@@ -21142,13 +21157,13 @@ function resolveRef(ref, ctx) {
21142
21157
  if (!ref.startsWith("#")) {
21143
21158
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
21144
21159
  }
21145
- const path20 = ref.slice(1).split("/").filter(Boolean);
21146
- if (path20.length === 0) {
21160
+ const path21 = ref.slice(1).split("/").filter(Boolean);
21161
+ if (path21.length === 0) {
21147
21162
  return ctx.rootSchema;
21148
21163
  }
21149
21164
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
21150
- if (path20[0] === defsKey) {
21151
- const key = path20[1] === void 0 ? void 0 : decodeJSONPointerSegment(path20[1]);
21165
+ if (path21[0] === defsKey) {
21166
+ const key = path21[1] === void 0 ? void 0 : decodeJSONPointerSegment(path21[1]);
21152
21167
  if (!key || !ctx.defs[key]) {
21153
21168
  throw new Error(`Reference not found: ${ref}`);
21154
21169
  }
@@ -22056,9 +22071,8 @@ function piTranscriptCandidate(sourcePath) {
22056
22071
  var piArtifactDiscovery = Object.freeze({
22057
22072
  targetId: "pi",
22058
22073
  discover: (context) => {
22059
- const { homeDir } = context;
22060
22074
  return walkFiles({
22061
- root: path11.join(homeDir, ".pi", "agent", "sessions"),
22075
+ root: path12.join(resolvePiAgentDir(context), "sessions"),
22062
22076
  maxDepth: 8,
22063
22077
  includeFile: (filePath) => filePath.endsWith(".jsonl"),
22064
22078
  skipDirs: PI_SKIP_DIRS
@@ -22085,7 +22099,7 @@ var DEFAULT_MATERIALIZED_CACHE_BYTES = 2 * 1024 * 1024 * 1024;
22085
22099
 
22086
22100
  // ../../packages/agent-targets/src/install/pi/index.ts
22087
22101
  import fs5 from "node:fs";
22088
- import path12 from "node:path";
22102
+ import path13 from "node:path";
22089
22103
  import { randomUUID } from "node:crypto";
22090
22104
  var FML_PI_EXTENSION_MARKER = "__FML_PI_EXTENSION_V1__";
22091
22105
  var LEGACY_PI_EXTENSION_MARKER = "__panopticonPiExtensionTest";
@@ -22098,18 +22112,7 @@ var LEGACY_PI_EXTENSION_SIGNATURES = Object.freeze([
22098
22112
  "SessionEnd"
22099
22113
  ]);
22100
22114
  function pathApiFor(platform) {
22101
- return platform === "win32" ? path12.win32 : path12.posix;
22102
- }
22103
- function resolvePiAgentDir(context, pathApi) {
22104
- const configured = context.env.PI_CODING_AGENT_DIR?.trim();
22105
- if (!configured) {
22106
- return pathApi.join(context.homeDir, ".pi", "agent");
22107
- }
22108
- if (configured === "~") return context.homeDir;
22109
- if (configured.startsWith("~/") || configured.startsWith("~\\")) {
22110
- return pathApi.join(context.homeDir, configured.slice(2));
22111
- }
22112
- return pathApi.normalize(configured);
22115
+ return platform === "win32" ? path13.win32 : path13.posix;
22113
22116
  }
22114
22117
  function readFileIfPresent(filePath) {
22115
22118
  try {
@@ -22134,10 +22137,10 @@ function removeLegacyExtension(filePath) {
22134
22137
  return { removed: true, preserved: false };
22135
22138
  }
22136
22139
  function writeExtensionAtomically(filePath, source) {
22137
- fs5.mkdirSync(path12.dirname(filePath), { recursive: true, mode: 448 });
22138
- const temporaryPath = path12.join(
22139
- path12.dirname(filePath),
22140
- `.${path12.basename(filePath)}.${process.pid}.${randomUUID()}.tmp`
22140
+ fs5.mkdirSync(path13.dirname(filePath), { recursive: true, mode: 448 });
22141
+ const temporaryPath = path13.join(
22142
+ path13.dirname(filePath),
22143
+ `.${path13.basename(filePath)}.${process.pid}.${randomUUID()}.tmp`
22141
22144
  );
22142
22145
  try {
22143
22146
  fs5.writeFileSync(temporaryPath, source, { encoding: "utf8", mode: 384 });
@@ -22153,7 +22156,7 @@ var PI_EXTENSION_INSTALLER = Object.freeze({
22153
22156
  resolvePaths(context) {
22154
22157
  const pathApi = pathApiFor(context.platform);
22155
22158
  const extensionsDir = pathApi.join(
22156
- resolvePiAgentDir(context, pathApi),
22159
+ resolvePiAgentDir(context),
22157
22160
  "extensions"
22158
22161
  );
22159
22162
  return {
@@ -22230,7 +22233,7 @@ var PI_EXTENSION_INSTALLER = Object.freeze({
22230
22233
 
22231
22234
  // src/hooks/context.ts
22232
22235
  import { createHash as createHash5 } from "node:crypto";
22233
- import path18 from "node:path";
22236
+ import path19 from "node:path";
22234
22237
 
22235
22238
  // ../../packages/agent-targets/src/hooks/normalize.ts
22236
22239
  import { createHash as createHash2 } from "node:crypto";
@@ -22349,7 +22352,7 @@ var MINI_SWE_AGENT_HOOK_EVENTS = Object.freeze([
22349
22352
  ]);
22350
22353
 
22351
22354
  // ../../packages/agent-targets/src/hooks/read-command.ts
22352
- import path13 from "node:path";
22355
+ import path14 from "node:path";
22353
22356
  var SHELL_TOOL_NAMES = /* @__PURE__ */ new Set([
22354
22357
  "bash",
22355
22358
  "exec_command",
@@ -22493,7 +22496,7 @@ function isPlausibleReadPath(argument) {
22493
22496
  if (COMMAND_SEPARATORS.has(argument)) return false;
22494
22497
  if (/[\0*?[{}`$]/.test(argument)) return false;
22495
22498
  if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(argument)) return false;
22496
- return path13.posix.isAbsolute(argument) || path13.win32.isAbsolute(argument) || argument.startsWith("~/") || argument.startsWith("./") || argument.startsWith("../") || argument.includes("/") || /\.[A-Za-z0-9][A-Za-z0-9_-]*$/.test(argument) || /^[A-Z][A-Za-z0-9_.-]*$/.test(argument);
22499
+ return path14.posix.isAbsolute(argument) || path14.win32.isAbsolute(argument) || argument.startsWith("~/") || argument.startsWith("./") || argument.startsWith("../") || argument.includes("/") || /\.[A-Za-z0-9][A-Za-z0-9_-]*$/.test(argument) || /^[A-Z][A-Za-z0-9_.-]*$/.test(argument);
22497
22500
  }
22498
22501
  function filePathFromSegment(tokens) {
22499
22502
  const commandTokens = [...tokens];
@@ -22925,7 +22928,7 @@ function canonicalHookContextFilePath(filePath, cwd, repositoryRoot) {
22925
22928
  const windows = [filePath, cwd, repositoryRoot].some(
22926
22929
  (value) => value !== void 0 && value !== null && /^[A-Za-z]:[\\/]/.test(value)
22927
22930
  );
22928
- const pathApi = windows ? path18.win32 : path18.posix;
22931
+ const pathApi = windows ? path19.win32 : path19.posix;
22929
22932
  const normalized = pathApi.normalize(filePath);
22930
22933
  const resolved = pathApi.isAbsolute(normalized) ? normalized : cwd && pathApi.isAbsolute(cwd) ? pathApi.resolve(cwd, normalized) : normalized;
22931
22934
  if (repositoryRoot && pathApi.isAbsolute(resolved)) {
@@ -23254,13 +23257,13 @@ function absoluteEnvPath(value) {
23254
23257
  const trimmed = value.trim();
23255
23258
  if (trimmed === "~") return os2.homedir();
23256
23259
  if (trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
23257
- return path19.join(os2.homedir(), trimmed.slice(2));
23260
+ return path20.join(os2.homedir(), trimmed.slice(2));
23258
23261
  }
23259
- return path19.isAbsolute(trimmed) ? path19.normalize(trimmed) : void 0;
23262
+ return path20.isAbsolute(trimmed) ? path20.normalize(trimmed) : void 0;
23260
23263
  }
23261
23264
  function observerDirectory() {
23262
23265
  const fmlHome = absoluteEnvPath(process.env.FML_HOME);
23263
- return absoluteEnvPath(process.env.FML_OBSERVER_DIR) ?? absoluteEnvPath(process.env.PANOPTICON_HOME) ?? (fmlHome ? path19.join(fmlHome, "panopticon") : path19.join(os2.homedir(), ".fml", "panopticon"));
23266
+ return absoluteEnvPath(process.env.FML_OBSERVER_DIR) ?? absoluteEnvPath(process.env.PANOPTICON_HOME) ?? (fmlHome ? path20.join(fmlHome, "panopticon") : path20.join(os2.homedir(), ".fml", "panopticon"));
23264
23267
  }
23265
23268
  function readObserverEndpoint(filePath) {
23266
23269
  try {
@@ -23286,8 +23289,8 @@ function readObserverAuthToken(filePath) {
23286
23289
  }
23287
23290
  async function deliver(event, repository) {
23288
23291
  const directory = observerDirectory();
23289
- const endpoint = readObserverEndpoint(path19.join(directory, "endpoint.json"));
23290
- const authToken = readObserverAuthToken(path19.join(directory, "auth-token"));
23292
+ const endpoint = readObserverEndpoint(path20.join(directory, "endpoint.json"));
23293
+ const authToken = readObserverAuthToken(path20.join(directory, "auth-token"));
23291
23294
  if (!endpoint || !authToken) return;
23292
23295
  const host = endpoint.host === "::1" ? "[::1]" : endpoint.host;
23293
23296
  try {