@adhdev/daemon-core 0.9.82-rc.445 → 0.9.82-rc.447

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/dist/index.js CHANGED
@@ -409,10 +409,10 @@ function readInjected(value) {
409
409
  }
410
410
  function getDaemonBuildInfo() {
411
411
  if (cached) return cached;
412
- const commit = readInjected(true ? "92b0714a88a4e1e253a40fa5a8c49602d087a5b3" : void 0) ?? "unknown";
413
- const commitShort = readInjected(true ? "92b0714a" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
- const version = readInjected(true ? "0.9.82-rc.445" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
- const builtAt = readInjected(true ? "2026-07-01T12:57:54.212Z" : void 0);
412
+ const commit = readInjected(true ? "fb4b6fd9ffb70781692aceb7eea162dd92606fad" : void 0) ?? "unknown";
413
+ const commitShort = readInjected(true ? "fb4b6fd9" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
+ const version = readInjected(true ? "0.9.82-rc.447" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
+ const builtAt = readInjected(true ? "2026-07-01T16:13:26.252Z" : void 0);
416
416
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
417
417
  return cached;
418
418
  }
@@ -1502,6 +1502,255 @@ var init_git_diff = __esm({
1502
1502
  }
1503
1503
  });
1504
1504
 
1505
+ // src/config/config.ts
1506
+ var config_exports = {};
1507
+ __export(config_exports, {
1508
+ generateMachineId: () => generateMachineId,
1509
+ getConfigDir: () => getConfigDir,
1510
+ getDaemonDataDir: () => getDaemonDataDir,
1511
+ isSetupComplete: () => isSetupComplete,
1512
+ isStableMachineId: () => isStableMachineId,
1513
+ loadConfig: () => loadConfig,
1514
+ markSetupComplete: () => markSetupComplete,
1515
+ resetConfig: () => resetConfig,
1516
+ resolveProviderSourceMode: () => resolveProviderSourceMode,
1517
+ saveConfig: () => saveConfig,
1518
+ updateConfig: () => updateConfig
1519
+ });
1520
+ function resolveProviderSourceMode(providerSourceMode, legacyDisableUpstream) {
1521
+ if (providerSourceMode === "normal" || providerSourceMode === "no-upstream") {
1522
+ return providerSourceMode;
1523
+ }
1524
+ return legacyDisableUpstream === true ? "no-upstream" : "normal";
1525
+ }
1526
+ function isPlainObject(value) {
1527
+ return !!value && typeof value === "object" && !Array.isArray(value);
1528
+ }
1529
+ function asStringArray(value) {
1530
+ if (!Array.isArray(value)) return [];
1531
+ return value.filter((item) => typeof item === "string");
1532
+ }
1533
+ function asNullableString(value) {
1534
+ return typeof value === "string" ? value : null;
1535
+ }
1536
+ function asOptionalString(value) {
1537
+ return typeof value === "string" && value.trim() ? value : void 0;
1538
+ }
1539
+ function asBoolean(value, fallback) {
1540
+ return typeof value === "boolean" ? value : fallback;
1541
+ }
1542
+ function normalizeMachineProviders(value) {
1543
+ if (!isPlainObject(value)) return {};
1544
+ const result = {};
1545
+ for (const [providerType, raw] of Object.entries(value)) {
1546
+ if (!isPlainObject(raw)) continue;
1547
+ const entry = {};
1548
+ if (raw.enabled === true) entry.enabled = true;
1549
+ if (typeof raw.executable === "string" && raw.executable.trim()) {
1550
+ entry.executable = raw.executable.trim();
1551
+ }
1552
+ if (Array.isArray(raw.args)) {
1553
+ entry.args = raw.args.filter((arg) => typeof arg === "string");
1554
+ }
1555
+ if (isPlainObject(raw.lastDetection)) {
1556
+ entry.lastDetection = raw.lastDetection;
1557
+ }
1558
+ if (isPlainObject(raw.lastVerification)) {
1559
+ entry.lastVerification = raw.lastVerification;
1560
+ }
1561
+ result[providerType] = entry;
1562
+ }
1563
+ return result;
1564
+ }
1565
+ function normalizeConfig(raw) {
1566
+ const parsed = isPlainObject(raw) ? raw : {};
1567
+ return {
1568
+ serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
1569
+ allowServerApiProxy: asBoolean(parsed.allowServerApiProxy, DEFAULT_CONFIG.allowServerApiProxy ?? false),
1570
+ selectedIde: asNullableString(parsed.selectedIde),
1571
+ configuredIdes: asStringArray(parsed.configuredIdes),
1572
+ installedExtensions: asStringArray(parsed.installedExtensions),
1573
+ userEmail: asNullableString(parsed.userEmail),
1574
+ userName: asNullableString(parsed.userName),
1575
+ setupCompleted: asBoolean(parsed.setupCompleted, DEFAULT_CONFIG.setupCompleted),
1576
+ setupDate: asNullableString(parsed.setupDate),
1577
+ enabledIdes: asStringArray(parsed.enabledIdes),
1578
+ workspaces: Array.isArray(parsed.workspaces) ? parsed.workspaces : [],
1579
+ defaultWorkspaceId: asNullableString(parsed.defaultWorkspaceId) ?? asNullableString(parsed.activeWorkspaceId),
1580
+ machineNickname: asNullableString(parsed.machineNickname),
1581
+ machineId: asOptionalString(parsed.machineId),
1582
+ machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
1583
+ registeredMachineId: asOptionalString(parsed.registeredMachineId),
1584
+ providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
1585
+ machineProviders: normalizeMachineProviders(parsed.machineProviders),
1586
+ ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
1587
+ providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
1588
+ providerDir: asOptionalString(parsed.providerDir),
1589
+ updateChannel: parsed.updateChannel === "preview" ? "preview" : "stable",
1590
+ terminalSizingMode: parsed.terminalSizingMode === "fit" ? "fit" : "measured"
1591
+ };
1592
+ }
1593
+ function generateMachineId() {
1594
+ return `${MACHINE_ID_PREFIX}${(0, import_crypto.randomUUID)().replace(/-/g, "")}`;
1595
+ }
1596
+ function isStableMachineId(machineId) {
1597
+ return typeof machineId === "string" && machineId.startsWith(MACHINE_ID_PREFIX);
1598
+ }
1599
+ function ensureMachineId(config) {
1600
+ if (isStableMachineId(config.machineId)) {
1601
+ return { config, changed: false };
1602
+ }
1603
+ return {
1604
+ config: {
1605
+ ...config,
1606
+ machineId: generateMachineId()
1607
+ },
1608
+ changed: true
1609
+ };
1610
+ }
1611
+ function getConfigDir() {
1612
+ const override = process.env.ADHDEV_CONFIG_DIR;
1613
+ const dir = override && override.trim() ? override.trim() : (0, import_path2.join)((0, import_os.homedir)(), ".adhdev");
1614
+ if (!(0, import_fs2.existsSync)(dir)) {
1615
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
1616
+ }
1617
+ return dir;
1618
+ }
1619
+ function getDaemonDataDir() {
1620
+ const dir = (0, import_path2.join)(getConfigDir(), "daemon");
1621
+ if (!(0, import_fs2.existsSync)(dir)) {
1622
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
1623
+ }
1624
+ return dir;
1625
+ }
1626
+ function getConfigPath() {
1627
+ return (0, import_path2.join)(getConfigDir(), "config.json");
1628
+ }
1629
+ function migrateStateToStateFile(raw) {
1630
+ const statePath = (0, import_path2.join)(getConfigDir(), "state.json");
1631
+ if ((0, import_fs2.existsSync)(statePath)) return;
1632
+ const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
1633
+ const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
1634
+ const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
1635
+ const sessionReads = isPlainObject(raw.sessionReads) ? raw.sessionReads : {};
1636
+ const sessionReadMarkers = isPlainObject(raw.sessionReadMarkers) ? raw.sessionReadMarkers : {};
1637
+ const hasData = recentActivity.length > 0 || savedProviderSessions.length > 0 || Object.keys(sessionReads).length > 0 || Object.keys(legacySessionReads).length > 0 || Object.keys(sessionReadMarkers).length > 0;
1638
+ if (!hasData) return;
1639
+ const mergedReads = Object.fromEntries(
1640
+ Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, v]) => typeof v === "number" && Number.isFinite(v))
1641
+ );
1642
+ const cleanedMarkers = Object.fromEntries(
1643
+ Object.entries(sessionReadMarkers).filter(([, v]) => typeof v === "string")
1644
+ );
1645
+ const state = {
1646
+ recentActivity,
1647
+ savedProviderSessions,
1648
+ sessionReads: mergedReads,
1649
+ sessionReadMarkers: cleanedMarkers
1650
+ };
1651
+ (0, import_fs2.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
1652
+ }
1653
+ function loadConfig() {
1654
+ const configPath = getConfigPath();
1655
+ if (!(0, import_fs2.existsSync)(configPath)) {
1656
+ const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
1657
+ try {
1658
+ saveConfig(initialized.config);
1659
+ } catch {
1660
+ }
1661
+ return initialized.config;
1662
+ }
1663
+ try {
1664
+ const raw = (0, import_fs2.readFileSync)(configPath, "utf-8");
1665
+ const parsed = JSON.parse(raw);
1666
+ migrateStateToStateFile(parsed);
1667
+ const normalizedInput = normalizeConfig(parsed);
1668
+ const ensured = ensureMachineId(normalizedInput);
1669
+ const normalized = ensured.config;
1670
+ if (ensured.changed || JSON.stringify(parsed) !== JSON.stringify(normalized)) {
1671
+ try {
1672
+ saveConfig(normalized);
1673
+ } catch {
1674
+ }
1675
+ }
1676
+ return normalized;
1677
+ } catch {
1678
+ const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
1679
+ return initialized.config;
1680
+ }
1681
+ }
1682
+ function saveConfig(config) {
1683
+ const configPath = getConfigPath();
1684
+ const dir = getConfigDir();
1685
+ const normalized = normalizeConfig(config);
1686
+ if (!(0, import_fs2.existsSync)(dir)) {
1687
+ (0, import_fs2.mkdirSync)(dir, { recursive: true, mode: 448 });
1688
+ }
1689
+ (0, import_fs2.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
1690
+ try {
1691
+ (0, import_fs2.chmodSync)(configPath, 384);
1692
+ } catch {
1693
+ }
1694
+ }
1695
+ function updateConfig(updates) {
1696
+ const config = loadConfig();
1697
+ const updated = { ...config, ...updates };
1698
+ saveConfig(updated);
1699
+ return updated;
1700
+ }
1701
+ function markSetupComplete(ideId, extensions) {
1702
+ const ideIds = Array.isArray(ideId) ? ideId : [ideId];
1703
+ return updateConfig({
1704
+ selectedIde: ideIds[0],
1705
+ configuredIdes: ideIds,
1706
+ installedExtensions: extensions,
1707
+ setupCompleted: true,
1708
+ setupDate: (/* @__PURE__ */ new Date()).toISOString()
1709
+ });
1710
+ }
1711
+ function isSetupComplete() {
1712
+ const config = loadConfig();
1713
+ return config.setupCompleted;
1714
+ }
1715
+ function resetConfig() {
1716
+ saveConfig({ ...DEFAULT_CONFIG });
1717
+ }
1718
+ var import_os, import_path2, import_fs2, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
1719
+ var init_config = __esm({
1720
+ "src/config/config.ts"() {
1721
+ "use strict";
1722
+ import_os = require("os");
1723
+ import_path2 = require("path");
1724
+ import_fs2 = require("fs");
1725
+ import_crypto = require("crypto");
1726
+ DEFAULT_CONFIG = {
1727
+ serverUrl: "https://api.adhf.dev",
1728
+ allowServerApiProxy: false,
1729
+ selectedIde: null,
1730
+ configuredIdes: [],
1731
+ installedExtensions: [],
1732
+ userEmail: null,
1733
+ userName: null,
1734
+ setupCompleted: false,
1735
+ setupDate: null,
1736
+ enabledIdes: [],
1737
+ workspaces: [],
1738
+ defaultWorkspaceId: null,
1739
+ machineNickname: null,
1740
+ machineId: void 0,
1741
+ machineSecret: null,
1742
+ registeredMachineId: void 0,
1743
+ providerSettings: {},
1744
+ machineProviders: {},
1745
+ ideSettings: {},
1746
+ providerSourceMode: "normal",
1747
+ updateChannel: "stable",
1748
+ terminalSizingMode: "measured"
1749
+ };
1750
+ MACHINE_ID_PREFIX = "mach_";
1751
+ }
1752
+ });
1753
+
1505
1754
  // src/git/git-worktree.ts
1506
1755
  var git_worktree_exports = {};
1507
1756
  __export(git_worktree_exports, {
@@ -1812,255 +2061,6 @@ var init_git_worktree = __esm({
1812
2061
  }
1813
2062
  });
1814
2063
 
1815
- // src/config/config.ts
1816
- var config_exports = {};
1817
- __export(config_exports, {
1818
- generateMachineId: () => generateMachineId,
1819
- getConfigDir: () => getConfigDir,
1820
- getDaemonDataDir: () => getDaemonDataDir,
1821
- isSetupComplete: () => isSetupComplete,
1822
- isStableMachineId: () => isStableMachineId,
1823
- loadConfig: () => loadConfig,
1824
- markSetupComplete: () => markSetupComplete,
1825
- resetConfig: () => resetConfig,
1826
- resolveProviderSourceMode: () => resolveProviderSourceMode,
1827
- saveConfig: () => saveConfig,
1828
- updateConfig: () => updateConfig
1829
- });
1830
- function resolveProviderSourceMode(providerSourceMode, legacyDisableUpstream) {
1831
- if (providerSourceMode === "normal" || providerSourceMode === "no-upstream") {
1832
- return providerSourceMode;
1833
- }
1834
- return legacyDisableUpstream === true ? "no-upstream" : "normal";
1835
- }
1836
- function isPlainObject(value) {
1837
- return !!value && typeof value === "object" && !Array.isArray(value);
1838
- }
1839
- function asStringArray(value) {
1840
- if (!Array.isArray(value)) return [];
1841
- return value.filter((item) => typeof item === "string");
1842
- }
1843
- function asNullableString(value) {
1844
- return typeof value === "string" ? value : null;
1845
- }
1846
- function asOptionalString(value) {
1847
- return typeof value === "string" && value.trim() ? value : void 0;
1848
- }
1849
- function asBoolean(value, fallback) {
1850
- return typeof value === "boolean" ? value : fallback;
1851
- }
1852
- function normalizeMachineProviders(value) {
1853
- if (!isPlainObject(value)) return {};
1854
- const result = {};
1855
- for (const [providerType, raw] of Object.entries(value)) {
1856
- if (!isPlainObject(raw)) continue;
1857
- const entry = {};
1858
- if (raw.enabled === true) entry.enabled = true;
1859
- if (typeof raw.executable === "string" && raw.executable.trim()) {
1860
- entry.executable = raw.executable.trim();
1861
- }
1862
- if (Array.isArray(raw.args)) {
1863
- entry.args = raw.args.filter((arg) => typeof arg === "string");
1864
- }
1865
- if (isPlainObject(raw.lastDetection)) {
1866
- entry.lastDetection = raw.lastDetection;
1867
- }
1868
- if (isPlainObject(raw.lastVerification)) {
1869
- entry.lastVerification = raw.lastVerification;
1870
- }
1871
- result[providerType] = entry;
1872
- }
1873
- return result;
1874
- }
1875
- function normalizeConfig(raw) {
1876
- const parsed = isPlainObject(raw) ? raw : {};
1877
- return {
1878
- serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
1879
- allowServerApiProxy: asBoolean(parsed.allowServerApiProxy, DEFAULT_CONFIG.allowServerApiProxy ?? false),
1880
- selectedIde: asNullableString(parsed.selectedIde),
1881
- configuredIdes: asStringArray(parsed.configuredIdes),
1882
- installedExtensions: asStringArray(parsed.installedExtensions),
1883
- userEmail: asNullableString(parsed.userEmail),
1884
- userName: asNullableString(parsed.userName),
1885
- setupCompleted: asBoolean(parsed.setupCompleted, DEFAULT_CONFIG.setupCompleted),
1886
- setupDate: asNullableString(parsed.setupDate),
1887
- enabledIdes: asStringArray(parsed.enabledIdes),
1888
- workspaces: Array.isArray(parsed.workspaces) ? parsed.workspaces : [],
1889
- defaultWorkspaceId: asNullableString(parsed.defaultWorkspaceId) ?? asNullableString(parsed.activeWorkspaceId),
1890
- machineNickname: asNullableString(parsed.machineNickname),
1891
- machineId: asOptionalString(parsed.machineId),
1892
- machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
1893
- registeredMachineId: asOptionalString(parsed.registeredMachineId),
1894
- providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
1895
- machineProviders: normalizeMachineProviders(parsed.machineProviders),
1896
- ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
1897
- providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
1898
- providerDir: asOptionalString(parsed.providerDir),
1899
- updateChannel: parsed.updateChannel === "preview" ? "preview" : "stable",
1900
- terminalSizingMode: parsed.terminalSizingMode === "fit" ? "fit" : "measured"
1901
- };
1902
- }
1903
- function generateMachineId() {
1904
- return `${MACHINE_ID_PREFIX}${(0, import_crypto.randomUUID)().replace(/-/g, "")}`;
1905
- }
1906
- function isStableMachineId(machineId) {
1907
- return typeof machineId === "string" && machineId.startsWith(MACHINE_ID_PREFIX);
1908
- }
1909
- function ensureMachineId(config) {
1910
- if (isStableMachineId(config.machineId)) {
1911
- return { config, changed: false };
1912
- }
1913
- return {
1914
- config: {
1915
- ...config,
1916
- machineId: generateMachineId()
1917
- },
1918
- changed: true
1919
- };
1920
- }
1921
- function getConfigDir() {
1922
- const override = process.env.ADHDEV_CONFIG_DIR;
1923
- const dir = override && override.trim() ? override.trim() : (0, import_path2.join)((0, import_os.homedir)(), ".adhdev");
1924
- if (!(0, import_fs2.existsSync)(dir)) {
1925
- (0, import_fs2.mkdirSync)(dir, { recursive: true });
1926
- }
1927
- return dir;
1928
- }
1929
- function getDaemonDataDir() {
1930
- const dir = (0, import_path2.join)(getConfigDir(), "daemon");
1931
- if (!(0, import_fs2.existsSync)(dir)) {
1932
- (0, import_fs2.mkdirSync)(dir, { recursive: true });
1933
- }
1934
- return dir;
1935
- }
1936
- function getConfigPath() {
1937
- return (0, import_path2.join)(getConfigDir(), "config.json");
1938
- }
1939
- function migrateStateToStateFile(raw) {
1940
- const statePath = (0, import_path2.join)(getConfigDir(), "state.json");
1941
- if ((0, import_fs2.existsSync)(statePath)) return;
1942
- const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
1943
- const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
1944
- const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
1945
- const sessionReads = isPlainObject(raw.sessionReads) ? raw.sessionReads : {};
1946
- const sessionReadMarkers = isPlainObject(raw.sessionReadMarkers) ? raw.sessionReadMarkers : {};
1947
- const hasData = recentActivity.length > 0 || savedProviderSessions.length > 0 || Object.keys(sessionReads).length > 0 || Object.keys(legacySessionReads).length > 0 || Object.keys(sessionReadMarkers).length > 0;
1948
- if (!hasData) return;
1949
- const mergedReads = Object.fromEntries(
1950
- Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, v]) => typeof v === "number" && Number.isFinite(v))
1951
- );
1952
- const cleanedMarkers = Object.fromEntries(
1953
- Object.entries(sessionReadMarkers).filter(([, v]) => typeof v === "string")
1954
- );
1955
- const state = {
1956
- recentActivity,
1957
- savedProviderSessions,
1958
- sessionReads: mergedReads,
1959
- sessionReadMarkers: cleanedMarkers
1960
- };
1961
- (0, import_fs2.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
1962
- }
1963
- function loadConfig() {
1964
- const configPath = getConfigPath();
1965
- if (!(0, import_fs2.existsSync)(configPath)) {
1966
- const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
1967
- try {
1968
- saveConfig(initialized.config);
1969
- } catch {
1970
- }
1971
- return initialized.config;
1972
- }
1973
- try {
1974
- const raw = (0, import_fs2.readFileSync)(configPath, "utf-8");
1975
- const parsed = JSON.parse(raw);
1976
- migrateStateToStateFile(parsed);
1977
- const normalizedInput = normalizeConfig(parsed);
1978
- const ensured = ensureMachineId(normalizedInput);
1979
- const normalized = ensured.config;
1980
- if (ensured.changed || JSON.stringify(parsed) !== JSON.stringify(normalized)) {
1981
- try {
1982
- saveConfig(normalized);
1983
- } catch {
1984
- }
1985
- }
1986
- return normalized;
1987
- } catch {
1988
- const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
1989
- return initialized.config;
1990
- }
1991
- }
1992
- function saveConfig(config) {
1993
- const configPath = getConfigPath();
1994
- const dir = getConfigDir();
1995
- const normalized = normalizeConfig(config);
1996
- if (!(0, import_fs2.existsSync)(dir)) {
1997
- (0, import_fs2.mkdirSync)(dir, { recursive: true, mode: 448 });
1998
- }
1999
- (0, import_fs2.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
2000
- try {
2001
- (0, import_fs2.chmodSync)(configPath, 384);
2002
- } catch {
2003
- }
2004
- }
2005
- function updateConfig(updates) {
2006
- const config = loadConfig();
2007
- const updated = { ...config, ...updates };
2008
- saveConfig(updated);
2009
- return updated;
2010
- }
2011
- function markSetupComplete(ideId, extensions) {
2012
- const ideIds = Array.isArray(ideId) ? ideId : [ideId];
2013
- return updateConfig({
2014
- selectedIde: ideIds[0],
2015
- configuredIdes: ideIds,
2016
- installedExtensions: extensions,
2017
- setupCompleted: true,
2018
- setupDate: (/* @__PURE__ */ new Date()).toISOString()
2019
- });
2020
- }
2021
- function isSetupComplete() {
2022
- const config = loadConfig();
2023
- return config.setupCompleted;
2024
- }
2025
- function resetConfig() {
2026
- saveConfig({ ...DEFAULT_CONFIG });
2027
- }
2028
- var import_os, import_path2, import_fs2, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
2029
- var init_config = __esm({
2030
- "src/config/config.ts"() {
2031
- "use strict";
2032
- import_os = require("os");
2033
- import_path2 = require("path");
2034
- import_fs2 = require("fs");
2035
- import_crypto = require("crypto");
2036
- DEFAULT_CONFIG = {
2037
- serverUrl: "https://api.adhf.dev",
2038
- allowServerApiProxy: false,
2039
- selectedIde: null,
2040
- configuredIdes: [],
2041
- installedExtensions: [],
2042
- userEmail: null,
2043
- userName: null,
2044
- setupCompleted: false,
2045
- setupDate: null,
2046
- enabledIdes: [],
2047
- workspaces: [],
2048
- defaultWorkspaceId: null,
2049
- machineNickname: null,
2050
- machineId: void 0,
2051
- machineSecret: null,
2052
- registeredMachineId: void 0,
2053
- providerSettings: {},
2054
- machineProviders: {},
2055
- ideSettings: {},
2056
- providerSourceMode: "normal",
2057
- updateChannel: "stable",
2058
- terminalSizingMode: "measured"
2059
- };
2060
- MACHINE_ID_PREFIX = "mach_";
2061
- }
2062
- });
2063
-
2064
2064
  // src/config/workspaces.ts
2065
2065
  function expandPath(p) {
2066
2066
  const t = (p || "").trim();
@@ -3201,12 +3201,23 @@ function addNode(meshId, opts) {
3201
3201
  if (mesh.nodes.some((n) => n.workspace === opts.workspace)) {
3202
3202
  throw new Error("This workspace is already in the mesh");
3203
3203
  }
3204
+ const machineNickname = (() => {
3205
+ const explicit = typeof opts.machineNickname === "string" ? opts.machineNickname.trim() : "";
3206
+ if (explicit) return explicit;
3207
+ try {
3208
+ const local = loadConfig().machineNickname;
3209
+ return typeof local === "string" && local.trim() ? local.trim() : void 0;
3210
+ } catch {
3211
+ return void 0;
3212
+ }
3213
+ })();
3204
3214
  const node = {
3205
3215
  id: `node_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
3206
3216
  workspace: opts.workspace.trim(),
3207
3217
  repoRoot: opts.repoRoot,
3208
3218
  daemonId: opts.daemonId,
3209
3219
  machineId: opts.machineId,
3220
+ ...machineNickname ? { machineNickname } : {},
3210
3221
  capabilities: normalizeCapabilityTags(opts.capabilities),
3211
3222
  userOverrides: opts.userOverrides || {},
3212
3223
  policy: opts.policy || {},
@@ -3241,6 +3252,7 @@ function updateNode(meshId, nodeId, opts) {
3241
3252
  if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
3242
3253
  if (opts.reportedPlatform && opts.reportedPlatform.trim()) node.reportedPlatform = opts.reportedPlatform.trim();
3243
3254
  if (opts.reportedArch && opts.reportedArch.trim()) node.reportedArch = opts.reportedArch.trim();
3255
+ if (opts.reportedMachineNickname && opts.reportedMachineNickname.trim()) node.machineNickname = opts.reportedMachineNickname.trim();
3244
3256
  if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
3245
3257
  if (opts.worktreeBootstrap) node.worktreeBootstrap = opts.worktreeBootstrap;
3246
3258
  if (Object.prototype.hasOwnProperty.call(opts, "systemPrompt")) {
@@ -24946,6 +24958,7 @@ var path3 = __toESM(require("path"));
24946
24958
  init_git_diff();
24947
24959
  init_git_executor();
24948
24960
  init_git_status();
24961
+ init_config();
24949
24962
  var GIT_COMMAND_NAMES = /* @__PURE__ */ new Set([
24950
24963
  "git_status",
24951
24964
  "git_diff_summary",
@@ -25085,7 +25098,21 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
25085
25098
  if (submoduleIgnorePaths && submoduleIgnorePaths.length > 0) statusParams.submoduleIgnorePaths = submoduleIgnorePaths;
25086
25099
  const status = await runService(() => services.getStatus(statusParams));
25087
25100
  if ("success" in status) return status;
25088
- return { success: true, status, reporterPlatform: process.platform, reporterArch: process.arch };
25101
+ const reporterMachineNickname = (() => {
25102
+ try {
25103
+ const nick = loadConfig().machineNickname;
25104
+ return typeof nick === "string" && nick.trim() ? nick.trim() : void 0;
25105
+ } catch {
25106
+ return void 0;
25107
+ }
25108
+ })();
25109
+ return {
25110
+ success: true,
25111
+ status,
25112
+ reporterPlatform: process.platform,
25113
+ reporterArch: process.arch,
25114
+ ...reporterMachineNickname ? { reporterMachineNickname } : {}
25115
+ };
25089
25116
  }
25090
25117
  case "git_diff_summary": {
25091
25118
  if (!services.getDiffSummary) return serviceNotImplemented(command);
@@ -42614,19 +42641,41 @@ var CliProviderInstance = class _CliProviderInstance {
42614
42641
  if (shortFinalSummary) {
42615
42642
  this.pushEvent({ event: "agent:generating_started", chatTitle, timestamp: now - shortDurationMs });
42616
42643
  }
42644
+ const shortEngineTurnStart = typeof this.adapter?.currentTurnStartedAt === "number" && Number.isFinite(this.adapter.currentTurnStartedAt) ? this.adapter.currentTurnStartedAt : 0;
42645
+ const shortTurnStartedAt = shortEngineTurnStart || this.generatingStartedAt || 0;
42646
+ const shortTaskId = this.completingTurnTaskId();
42617
42647
  this.generatingDebouncePending = null;
42618
42648
  this.generatingStartedAt = 0;
42619
- const missingEvidence = (this.provider.requiresFinalAssistantBeforeIdle === true || shortEvidenceSource === "external-native") && !shortFinalSummary;
42649
+ const missingEvidence = (this.provider.requiresFinalAssistantBeforeIdle === true || shortEvidenceSource === "external-native" || shortEvidenceSource === "unavailable") && !shortFinalSummary;
42620
42650
  if (missingEvidence) {
42621
42651
  LOG.warn("CLI", `[${this.type}] short completion missing final assistant evidence (source=${shortEvidenceSource})`);
42622
42652
  }
42623
- const hasMeshContext = !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.launchedByCoordinator);
42624
- if (missingEvidence && !hasMeshContext) {
42625
- LOG.info("CLI", `[${this.type}] short completion suppressed: missing final assistant evidence, no mesh context (source=${shortEvidenceSource})`);
42626
- } else {
42653
+ if (this.isAutonomousMeshSession()) {
42654
+ this.completedDebouncePending = {
42655
+ chatTitle,
42656
+ duration: Math.round(shortDurationMs / 1e3),
42657
+ timestamp: now,
42658
+ firstObservedAt: now,
42659
+ // Short-gen enters from generating→idle (or waiting_approval→idle); the
42660
+ // completedDebounce finalization gate treats previousStatus for its
42661
+ // approval-resolution / inter-approval-valley handling. lastStatus is the
42662
+ // status we transitioned FROM here.
42663
+ previousStatus: this.lastStatus,
42664
+ ...shortTaskId ? { taskId: shortTaskId } : {},
42665
+ ...shortTurnStartedAt ? { turnStartedAt: shortTurnStartedAt } : {},
42666
+ // FALSE-IDLE continuity: same arm-time snapshots as the normal branch so the
42667
+ // flush guard can prove continuous idle across the settle window.
42668
+ busyEpochAtArm: this.busyEpoch,
42669
+ ...typeof adapterStatus?.lastOutputAt === "number" && Number.isFinite(adapterStatus.lastOutputAt) ? { lastOutputAtArm: adapterStatus.lastOutputAt } : {}
42670
+ };
42671
+ LOG.info("CLI", `[${this.type}] short-generating routed through settle window (${shortDurationMs}ms, source=${shortEvidenceSource}, missingEvidence=${missingEvidence}) \u2014 arming completedDebouncePending instead of inline fire`);
42627
42672
  if (this.isMeshWorkerSession()) {
42628
- traceMeshEventStage("fired", this.meshTraceCtx(), `short-generating idle (source=${shortEvidenceSource})`);
42673
+ traceMeshEventStage("arm", this.meshTraceCtx(), `short-generating settle-arm (source=${shortEvidenceSource}, missingEvidence=${missingEvidence})`);
42629
42674
  }
42675
+ this.scheduleCompletedDebounceFlush(NATIVE_HISTORY_MESH_IDLE_SETTLE_MS);
42676
+ } else if (missingEvidence) {
42677
+ LOG.info("CLI", `[${this.type}] short completion suppressed: missing final assistant evidence, non-mesh session (source=${shortEvidenceSource})`);
42678
+ } else {
42630
42679
  this.pushEvent({
42631
42680
  event: "agent:generating_completed",
42632
42681
  chatTitle,
@@ -42636,8 +42685,7 @@ var CliProviderInstance = class _CliProviderInstance {
42636
42685
  completionDiagnostic: {
42637
42686
  reason: "short_generating_suppressed",
42638
42687
  shortDurationMs,
42639
- finalAssistantEvidenceSource: shortEvidenceSource,
42640
- ...missingEvidence ? { blockReason: "missing_final_assistant" } : {}
42688
+ finalAssistantEvidenceSource: shortEvidenceSource
42641
42689
  }
42642
42690
  });
42643
42691
  }
@@ -46985,38 +47033,75 @@ function extractUserPrompt(payload) {
46985
47033
  if (!text) return "";
46986
47034
  return extractUserRequestContent(text);
46987
47035
  }
47036
+ function isSqliteBusyError(err) {
47037
+ if (!err) return false;
47038
+ const code = err.code;
47039
+ if (typeof code === "string" && code.includes("SQLITE_BUSY")) return true;
47040
+ const msg = err instanceof Error ? err.message : String(err);
47041
+ return /SQLITE_BUSY|database is locked|database table is locked/i.test(msg);
47042
+ }
47043
+ var AGY_DB_BUSY_TIMEOUT_MS = 3e3;
47044
+ var AGY_DB_MAX_ATTEMPTS = 4;
47045
+ var AGY_DB_RETRY_BACKOFF_MS = [50, 100, 150];
47046
+ function sleepBusy(ms) {
47047
+ const end = Date.now() + ms;
47048
+ while (Date.now() < end) {
47049
+ }
47050
+ }
46988
47051
  function parseConversationDb(filePath, sessionId, workspace) {
46989
- let db;
47052
+ let Database;
46990
47053
  try {
46991
- const Database = loadBetterSqlite3();
46992
- db = new Database(filePath, { readonly: true, fileMustExist: true });
47054
+ Database = loadBetterSqlite3();
46993
47055
  } catch (err) {
46994
47056
  LOG.warn(
46995
47057
  "NativeHistory",
46996
- `antigravity .db reader could not open ${path31.basename(filePath)}: ${err instanceof Error ? err.message : String(err)} (better-sqlite3 load/open failed \u2014 assistant answers in this .db will not surface)`
47058
+ `antigravity .db reader could not load better-sqlite3 for ${path31.basename(filePath)}: ${err instanceof Error ? err.message : String(err)} (native binding unavailable \u2014 assistant answers in this .db will not surface)`
46997
47059
  );
46998
47060
  return null;
46999
47061
  }
47000
- let rows;
47001
- try {
47002
- rows = db.prepare(
47003
- `SELECT idx, step_type, step_payload
47004
- FROM steps
47005
- WHERE step_type IN (${AGY_STEP_TYPE_USER}, ${AGY_STEP_TYPE_MODEL})
47006
- ORDER BY idx ASC`
47007
- ).all();
47008
- } catch (err) {
47009
- LOG.debug(
47010
- "NativeHistory",
47011
- `antigravity .db ${path31.basename(filePath)} has no readable steps table: ${err instanceof Error ? err.message : String(err)}`
47012
- );
47013
- return null;
47014
- } finally {
47062
+ let rows = null;
47063
+ let lastBusyErr;
47064
+ for (let attempt = 1; attempt <= AGY_DB_MAX_ATTEMPTS; attempt++) {
47065
+ let db;
47015
47066
  try {
47016
- db.close();
47017
- } catch {
47067
+ db = new Database(filePath, { readonly: true, fileMustExist: true });
47068
+ try {
47069
+ db.pragma(`busy_timeout = ${AGY_DB_BUSY_TIMEOUT_MS}`);
47070
+ } catch {
47071
+ }
47072
+ rows = db.prepare(
47073
+ `SELECT idx, step_type, step_payload
47074
+ FROM steps
47075
+ WHERE step_type IN (${AGY_STEP_TYPE_USER}, ${AGY_STEP_TYPE_MODEL})
47076
+ ORDER BY idx ASC`
47077
+ ).all();
47078
+ break;
47079
+ } catch (err) {
47080
+ if (isSqliteBusyError(err)) {
47081
+ lastBusyErr = err;
47082
+ if (attempt < AGY_DB_MAX_ATTEMPTS) {
47083
+ sleepBusy(AGY_DB_RETRY_BACKOFF_MS[attempt - 1] ?? 150);
47084
+ continue;
47085
+ }
47086
+ LOG.warn(
47087
+ "NativeHistory",
47088
+ `antigravity .db ${path31.basename(filePath)} stayed locked (SQLITE_BUSY) after ${AGY_DB_MAX_ATTEMPTS} attempts: ${err instanceof Error ? err.message : String(err)} (WAL write/checkpoint lock contention \u2014 assistant answers may transiently not surface this read)`
47089
+ );
47090
+ return null;
47091
+ }
47092
+ LOG.debug(
47093
+ "NativeHistory",
47094
+ `antigravity .db ${path31.basename(filePath)} not readable: ${err instanceof Error ? err.message : String(err)}`
47095
+ );
47096
+ return null;
47097
+ } finally {
47098
+ try {
47099
+ db?.close();
47100
+ } catch {
47101
+ }
47018
47102
  }
47019
47103
  }
47104
+ void lastBusyErr;
47020
47105
  if (!Array.isArray(rows) || rows.length === 0) return null;
47021
47106
  const normalizedWorkspace = typeof workspace === "string" ? workspace.trim() : "";
47022
47107
  const baseTs = statMtimeMs3(filePath) || Date.now();
@@ -52369,6 +52454,10 @@ var meshStatusHandlers = {
52369
52454
  const sessionHostRecords = ctx.deps.sessionHostControl?.listSessions ? await ctx.deps.sessionHostControl.listSessions().catch(() => []) : [];
52370
52455
  const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
52371
52456
  const localMachineId = loadConfig().machineId || "";
52457
+ const localMachineNickname = (() => {
52458
+ const nick = loadConfig().machineNickname;
52459
+ return typeof nick === "string" && nick.trim() ? nick.trim() : "";
52460
+ })();
52372
52461
  const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
52373
52462
  const meshGitProbeCache = ctx.meshGitProbeCache;
52374
52463
  const directTruth = requireDirectPeerTruth ? await hydrateInlineMeshDirectTruth({
@@ -52449,6 +52538,9 @@ var meshStatusHandlers = {
52449
52538
  ) || Boolean(
52450
52539
  daemonId && (daemonIdsEquivalent(daemonId, localMachineId) || daemonIdsEquivalent(daemonId, ctx.deps.statusInstanceId))
52451
52540
  ) || Boolean(meshRecord?.inline && nodeIndex === 0) || sparseConfiguredCoordinatorNode;
52541
+ if (isSelfNode && localMachineNickname && !readStringValue(node.machineNickname, node.machine_nickname)) {
52542
+ node.machineNickname = localMachineNickname;
52543
+ }
52452
52544
  const machineIdentity = buildMeshNodeMachineIdentity(node, {
52453
52545
  localMachineId,
52454
52546
  localDaemonId: ctx.deps.statusInstanceId,
@@ -53337,7 +53429,7 @@ function buildLivePeerGitConnection(connection, timestamp = (/* @__PURE__ */ new
53337
53429
  }
53338
53430
  function recordInlineMeshDirectGitTruth(node, git, source) {
53339
53431
  if (!node || typeof node !== "object" || Array.isArray(node)) {
53340
- return { reporterPlatform: null, reporterArch: null };
53432
+ return { reporterPlatform: null, reporterArch: null, reporterMachineNickname: null };
53341
53433
  }
53342
53434
  const checkedAt = readNumberValue(git.lastCheckedAt) ?? Date.now();
53343
53435
  const updatedAt = new Date(checkedAt).toISOString();
@@ -53362,7 +53454,9 @@ function recordInlineMeshDirectGitTruth(node, git, source) {
53362
53454
  stampNodeReporterPlatform(node, reporterPlatform, reporterArch);
53363
53455
  if (reporterPlatform) node.reportedPlatform = reporterPlatform;
53364
53456
  if (reporterArch) node.reportedArch = reporterArch;
53365
- return { reporterPlatform, reporterArch };
53457
+ const reporterMachineNickname = readStringValue(git.reporterMachineNickname) ?? null;
53458
+ if (reporterMachineNickname) node.machineNickname = reporterMachineNickname;
53459
+ return { reporterPlatform, reporterArch, reporterMachineNickname };
53366
53460
  }
53367
53461
  function stampNodeReporterPlatform(node, platform10, arch2) {
53368
53462
  if (!node || typeof node !== "object" || Array.isArray(node)) return;
@@ -53385,8 +53479,9 @@ function persistNodeReporterPlatform(meshSource, mesh, nodeId, reporter) {
53385
53479
  if (!meshId || !nodeId) return;
53386
53480
  const reportedPlatform = reporter.reporterPlatform ?? void 0;
53387
53481
  const reportedArch = reporter.reporterArch ?? void 0;
53388
- if (!reportedPlatform && !reportedArch) return;
53389
- void Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports)).then(({ updateNode: updateNode2 }) => updateNode2(meshId, nodeId, { reportedPlatform, reportedArch })).catch(() => {
53482
+ const reportedMachineNickname = reporter.reporterMachineNickname ?? void 0;
53483
+ if (!reportedPlatform && !reportedArch && !reportedMachineNickname) return;
53484
+ void Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports)).then(({ updateNode: updateNode2 }) => updateNode2(meshId, nodeId, { reportedPlatform, reportedArch, reportedMachineNickname })).catch(() => {
53390
53485
  });
53391
53486
  }
53392
53487
  function buildCachedInlineMeshGitStatus(node) {
@@ -54038,9 +54133,11 @@ async function probeRemoteMeshGitStatus(args) {
54038
54133
  if (!remoteGit || typeof remoteGit !== "object" || typeof remoteGit.isGitRepo !== "boolean") return null;
54039
54134
  const reporterPlatform = readStringValue(remoteResult?.reporterPlatform);
54040
54135
  const reporterArch = readStringValue(remoteResult?.reporterArch);
54136
+ const reporterMachineNickname = readStringValue(remoteResult?.reporterMachineNickname);
54041
54137
  const git = remoteGit;
54042
54138
  if (reporterPlatform) git.reporterPlatform = reporterPlatform;
54043
54139
  if (reporterArch) git.reporterArch = reporterArch;
54140
+ if (reporterMachineNickname) git.reporterMachineNickname = reporterMachineNickname;
54044
54141
  return git;
54045
54142
  }
54046
54143
  var MESH_DIRECT_PROBE_MAX_RETRIES = 2;