alegra-data-agent 0.7.2 → 0.7.4
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/autoupdate.js +41 -8
- package/dist/commands/update.js +1 -3
- package/dist/hermes-plugin.js +38 -3
- package/dist/lib.js +2 -0
- package/package.json +1 -1
package/dist/autoupdate.js
CHANGED
|
@@ -4,7 +4,7 @@ import { logWarn } from "./colors.js";
|
|
|
4
4
|
import { hookCommandFor, runHookInstall, runHookUninstall, } from "./commands/hook.js";
|
|
5
5
|
import { HERMES_PLUGIN_NAME, hermesPluginManifest, hermesPluginModule } from "./hermes-plugin.js";
|
|
6
6
|
import { runHermesCliAt } from "./installer.js";
|
|
7
|
-
import { COMMAND_NAME, getAntigravityHooksPath, getClaudeSettingsPath, getCodexHooksPath, getCursorHooksPath, getGeminiSettingsPath, getHermesHome, getHermesPluginsDir, getOpenCodePluginPath, readLockFile, } from "./lib.js";
|
|
7
|
+
import { BACKGROUND_AUTH_FAIL_COOLDOWN_MS, BACKGROUND_COOLDOWN_MS, COMMAND_NAME, PRODUCT_NAME, getAntigravityHooksPath, getClaudeSettingsPath, getCodexHooksPath, getCursorHooksPath, getGeminiSettingsPath, getHermesHome, getHermesPluginsDir, getOpenCodePluginPath, readLockFile, } from "./lib.js";
|
|
8
8
|
function readJsonSafe(path) {
|
|
9
9
|
if (!existsSync(path))
|
|
10
10
|
return {};
|
|
@@ -15,12 +15,21 @@ function readJsonSafe(path) {
|
|
|
15
15
|
return null;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function writeIfChanged(path, content) {
|
|
19
|
+
try {
|
|
20
|
+
if (readFileSync(path, "utf-8") === content)
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
}
|
|
19
25
|
mkdirSync(dirname(path), { recursive: true });
|
|
20
26
|
const tmp = `${path}.tmp-${process.pid}`;
|
|
21
|
-
writeFileSync(tmp,
|
|
27
|
+
writeFileSync(tmp, content, "utf-8");
|
|
22
28
|
renameSync(tmp, path);
|
|
23
29
|
}
|
|
30
|
+
function writeJson(path, data) {
|
|
31
|
+
writeIfChanged(path, `${JSON.stringify(data, null, 2)}\n`);
|
|
32
|
+
}
|
|
24
33
|
function entryIsOurs(m) {
|
|
25
34
|
if (!m || typeof m !== "object")
|
|
26
35
|
return false;
|
|
@@ -126,14 +135,39 @@ function antigravityHookIsOurs() {
|
|
|
126
135
|
}
|
|
127
136
|
function installOpenCode(command) {
|
|
128
137
|
const path = getOpenCodePluginPath();
|
|
129
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
130
138
|
const plugin = `// alegra-data-agent: auto-update al iniciar OpenCode. Generado por el instalador.
|
|
131
139
|
// Borrar este archivo desactiva el auto-update. No editar a mano.
|
|
132
140
|
import { spawn } from "node:child_process"
|
|
141
|
+
import { readFileSync } from "node:fs"
|
|
142
|
+
import { homedir } from "node:os"
|
|
143
|
+
import { join } from "node:path"
|
|
133
144
|
|
|
134
145
|
const COMMAND = ${JSON.stringify(command)}
|
|
146
|
+
const COOLDOWN_MS = ${BACKGROUND_COOLDOWN_MS}
|
|
147
|
+
const AUTH_FAIL_COOLDOWN_MS = ${BACKGROUND_AUTH_FAIL_COOLDOWN_MS}
|
|
148
|
+
|
|
149
|
+
let launchedAt = 0
|
|
150
|
+
|
|
151
|
+
function within(iso, windowMs) {
|
|
152
|
+
const at = Date.parse(iso || "")
|
|
153
|
+
if (Number.isNaN(at)) return false
|
|
154
|
+
const age = Date.now() - at
|
|
155
|
+
return age >= 0 && age < windowMs
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function checkedRecently() {
|
|
159
|
+
try {
|
|
160
|
+
const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config")
|
|
161
|
+
const last = JSON.parse(readFileSync(join(base, ${JSON.stringify(PRODUCT_NAME)}, "last-check.json"), "utf-8"))
|
|
162
|
+
return within(last.checkedAt, COOLDOWN_MS) || within(last.authFailedAt, AUTH_FAIL_COOLDOWN_MS)
|
|
163
|
+
} catch (_e) {
|
|
164
|
+
return false
|
|
165
|
+
}
|
|
166
|
+
}
|
|
135
167
|
|
|
136
168
|
function runUpdate() {
|
|
169
|
+
if (checkedRecently() || Date.now() - launchedAt < COOLDOWN_MS) return
|
|
170
|
+
launchedAt = Date.now()
|
|
137
171
|
try {
|
|
138
172
|
const child = spawn(COMMAND, { shell: true, detached: true, stdio: "ignore", windowsHide: true })
|
|
139
173
|
child.on("error", () => {})
|
|
@@ -154,13 +188,12 @@ export default {
|
|
|
154
188
|
},
|
|
155
189
|
}
|
|
156
190
|
`;
|
|
157
|
-
|
|
191
|
+
writeIfChanged(path, plugin);
|
|
158
192
|
}
|
|
159
193
|
function installHermes(command) {
|
|
160
194
|
const dir = join(getHermesPluginsDir(), HERMES_PLUGIN_NAME);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
writeFileSync(join(dir, "__init__.py"), hermesPluginModule(command), "utf-8");
|
|
195
|
+
writeIfChanged(join(dir, "plugin.yaml"), hermesPluginManifest());
|
|
196
|
+
writeIfChanged(join(dir, "__init__.py"), hermesPluginModule(command));
|
|
164
197
|
enableHermesPlugin();
|
|
165
198
|
}
|
|
166
199
|
function enableHermesPlugin() {
|
package/dist/commands/update.js
CHANGED
|
@@ -6,15 +6,13 @@ import { hasAutoUpdate, refreshAutoUpdate } from "../autoupdate.js";
|
|
|
6
6
|
import { approveCodexHook, hasCodexTrustConsent } from "../codex-trust.js";
|
|
7
7
|
import { cyan, dim, gray, green, log, logError, yellow } from "../colors.js";
|
|
8
8
|
import { detectDrift, installAll, summarize } from "../installer.js";
|
|
9
|
-
import { COMMAND_NAME, getAutoUpdateLogPath, getLastCheckPath, getPackageVersion, } from "../lib.js";
|
|
9
|
+
import { BACKGROUND_AUTH_FAIL_COOLDOWN_MS, BACKGROUND_COOLDOWN_MS, COMMAND_NAME, getAutoUpdateLogPath, getLastCheckPath, getPackageVersion, } from "../lib.js";
|
|
10
10
|
import { banner } from "../ui.js";
|
|
11
11
|
import { runLogin } from "./login.js";
|
|
12
|
-
const BACKGROUND_COOLDOWN_MS = 15 * 60_000;
|
|
13
12
|
const BACKGROUND_LOGIN_TIMEOUT_MS = (() => {
|
|
14
13
|
const v = Number(process.env.ALEGRA_DATA_AGENT_BG_LOGIN_TIMEOUT_MS);
|
|
15
14
|
return Number.isFinite(v) && v > 0 ? v : 90_000;
|
|
16
15
|
})();
|
|
17
|
-
export const BACKGROUND_AUTH_FAIL_COOLDOWN_MS = 60 * 60_000;
|
|
18
16
|
function readLastCheck() {
|
|
19
17
|
try {
|
|
20
18
|
const parsed = JSON.parse(readFileSync(getLastCheckPath(), "utf-8"));
|
package/dist/hermes-plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { COMMAND_NAME } from "./lib.js";
|
|
1
|
+
import { BACKGROUND_AUTH_FAIL_COOLDOWN_MS, BACKGROUND_COOLDOWN_MS, COMMAND_NAME } from "./lib.js";
|
|
2
2
|
export const HERMES_PLUGIN_NAME = "alegra-data-agent-autoupdate";
|
|
3
3
|
export function hermesPluginManifest() {
|
|
4
4
|
return `# Generado por ${COMMAND_NAME}. Borrar esta carpeta desactiva el auto-update.
|
|
@@ -18,16 +18,23 @@ Generado por el instalador — no editar a mano. Borrar esta carpeta (o correr
|
|
|
18
18
|
\`${COMMAND_NAME} uninstall\`) desactiva el auto-update.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
+
import json
|
|
21
22
|
import logging
|
|
22
23
|
import os
|
|
23
24
|
import shlex
|
|
24
25
|
import shutil
|
|
25
26
|
import subprocess
|
|
27
|
+
import time
|
|
28
|
+
from datetime import datetime
|
|
26
29
|
from pathlib import Path
|
|
27
30
|
|
|
28
31
|
logger = logging.getLogger(__name__)
|
|
29
32
|
|
|
30
33
|
COMMAND = ${commandLiteral}
|
|
34
|
+
COOLDOWN_S = ${BACKGROUND_COOLDOWN_MS / 1000}
|
|
35
|
+
AUTH_FAIL_COOLDOWN_S = ${BACKGROUND_AUTH_FAIL_COOLDOWN_MS / 1000}
|
|
36
|
+
|
|
37
|
+
_launched_at = 0.0
|
|
31
38
|
|
|
32
39
|
# Hermes puede arrancar sin el PATH del shell del usuario (Desktop, servicios):
|
|
33
40
|
# ahí \`pnpm\` no resuelve y el auto-update moriría en silencio.
|
|
@@ -40,11 +47,35 @@ EXTRA_PATH_DIRS = (
|
|
|
40
47
|
)
|
|
41
48
|
|
|
42
49
|
|
|
50
|
+
def _config_dir() -> Path:
|
|
51
|
+
base = os.environ.get("XDG_CONFIG_HOME") or os.path.expanduser("~/.config")
|
|
52
|
+
return Path(base) / ${productLiteral}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _within(iso, window_s: float) -> bool:
|
|
56
|
+
try:
|
|
57
|
+
at = datetime.fromisoformat(str(iso).replace("Z", "+00:00")).timestamp()
|
|
58
|
+
except Exception:
|
|
59
|
+
return False
|
|
60
|
+
age = time.time() - at
|
|
61
|
+
return 0 <= age < window_s
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _checked_recently() -> bool:
|
|
65
|
+
"""Mismas ventanas que \`update --background\`: si el último chequeo es reciente, no se lanza nada."""
|
|
66
|
+
try:
|
|
67
|
+
last = json.loads((_config_dir() / "last-check.json").read_text(encoding="utf-8"))
|
|
68
|
+
return _within(last.get("checkedAt"), COOLDOWN_S) or _within(
|
|
69
|
+
last.get("authFailedAt"), AUTH_FAIL_COOLDOWN_S
|
|
70
|
+
)
|
|
71
|
+
except Exception:
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
|
|
43
75
|
def _log_skip(reason: str) -> None:
|
|
44
76
|
"""Deja constancia en autoupdate.log — el mismo archivo que reporta status."""
|
|
45
77
|
try:
|
|
46
|
-
|
|
47
|
-
log_file = Path(base) / ${productLiteral} / "autoupdate.log"
|
|
78
|
+
log_file = _config_dir() / "autoupdate.log"
|
|
48
79
|
log_file.parent.mkdir(parents=True, exist_ok=True)
|
|
49
80
|
with log_file.open("a", encoding="utf-8") as fh:
|
|
50
81
|
fh.write(f"[hermes] {reason}\\n")
|
|
@@ -54,6 +85,9 @@ def _log_skip(reason: str) -> None:
|
|
|
54
85
|
|
|
55
86
|
def _run_update(**_kwargs) -> None:
|
|
56
87
|
"""Lanza el update y vuelve: nunca bloquea ni rompe el arranque."""
|
|
88
|
+
global _launched_at
|
|
89
|
+
if _checked_recently() or time.time() - _launched_at < COOLDOWN_S:
|
|
90
|
+
return
|
|
57
91
|
try:
|
|
58
92
|
argv = shlex.split(COMMAND)
|
|
59
93
|
if not argv:
|
|
@@ -73,6 +107,7 @@ def _run_update(**_kwargs) -> None:
|
|
|
73
107
|
stderr=subprocess.DEVNULL,
|
|
74
108
|
start_new_session=True,
|
|
75
109
|
)
|
|
110
|
+
_launched_at = time.time()
|
|
76
111
|
except Exception as exc:
|
|
77
112
|
logger.debug("%s: auto-update no se pudo lanzar: %s", ${productLiteral}, exc)
|
|
78
113
|
|
package/dist/lib.js
CHANGED
|
@@ -288,6 +288,8 @@ export function getAuthFilePath() {
|
|
|
288
288
|
export function getLastCheckPath() {
|
|
289
289
|
return join(getConfigDir(), "last-check.json");
|
|
290
290
|
}
|
|
291
|
+
export const BACKGROUND_COOLDOWN_MS = 15 * 60_000;
|
|
292
|
+
export const BACKGROUND_AUTH_FAIL_COOLDOWN_MS = 60 * 60_000;
|
|
291
293
|
export function getManifestCachePath() {
|
|
292
294
|
return join(getConfigDir(), "manifest-cache.json");
|
|
293
295
|
}
|