log-llm-config 1.5.8 → 1.5.10
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/README.md +1 -1
- package/dist/bootstrap_constants.js +3 -3
- package/dist/dialog_prefs_cli.js +1 -1
- package/dist/log_config_files/auth/auth_flow.js +2 -2
- package/dist/log_config_files/auth/auth_key_store.js +2 -2
- package/dist/log_config_files/collection/config_collector.js +1 -0
- package/dist/log_config_files/collection/cowork_desktop_version_collector.js +60 -0
- package/dist/log_config_files/collection/openclaw_token_usage_collector.js +35 -0
- package/dist/log_config_files/collection/opencode_token_usage_collector.js +10 -3
- package/dist/log_config_files/collection/pi_token_usage_collector.js +27 -4
- package/dist/log_config_files/paths/path_constants_helpers.js +1 -1
- package/dist/log_config_files/runtime/client_event_reporter.js +4 -4
- package/dist/log_config_files/runtime/compliance_session_log.js +2 -2
- package/dist/log_config_files/runtime/hook_logger.js +3 -3
- package/dist/log_config_files/runtime/log_metadata.js +2 -2
- package/dist/log_config_files/runtime/main_runner.js +11 -3
- package/dist/log_config_files/runtime/management_storage.js +8 -8
- package/dist/log_config_files/runtime/remediation_sync.js +3 -3
- package/dist/log_config_files/sender/batch_sender.js +1 -1
- package/dist/log_sensitive_paths_audit.js +3 -3
- package/dist/log_uuid/auth_key_store.js +2 -2
- package/dist/log_uuid/startup_sender.js +1 -1
- package/dist/tofu.js +1 -1
- package/dist/tofu_environment.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ CLI helpers for Optimus Security startup workflows.
|
|
|
11
11
|
|
|
12
12
|
#### `log_uuid`
|
|
13
13
|
|
|
14
|
-
Collects the machine hardware UUID (or uses the `OPTIMUS_HARDWARE_UUID` env variable), prints it, and POSTs a startup payload to `OPTIMUS_ENDPOINT/startup/`. If the server responds with a key, it stores it at
|
|
14
|
+
Collects the machine hardware UUID (or uses the `OPTIMUS_HARDWARE_UUID` env variable), prints it, and POSTs a startup payload to `OPTIMUS_ENDPOINT/startup/`. If the server responds with a key, it stores it at `~/.optimuslabs/management/auth_key.txt`.
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
OPTIMUS_ENDPOINT=http://localhost:8080/endpoint_security/ \
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Bootstrap-level path constants — known before the API response is available.
|
|
3
3
|
* Used by auth, hook logging, and audit output. Do not add agent-specific paths here.
|
|
4
4
|
*/
|
|
5
|
-
export const
|
|
5
|
+
export const OPTIMUSLABS_MANAGEMENT_REL = '.optimuslabs/management';
|
|
6
6
|
/**
|
|
7
7
|
* All hook-written log files live under this subdirectory, grouped by type
|
|
8
8
|
* (see LOG_GROUP_* below). Keeping logs in one subtree leaves the management
|
|
9
9
|
* root limited to secrets/identity/state (auth_key, organization-uuid, contracts).
|
|
10
10
|
*/
|
|
11
|
-
export const
|
|
12
|
-
/** Log group subdirectories under {@link
|
|
11
|
+
export const OPTIMUSLABS_LOGS_REL = `${OPTIMUSLABS_MANAGEMENT_REL}/logs`;
|
|
12
|
+
/** Log group subdirectories under {@link OPTIMUSLABS_LOGS_REL}. */
|
|
13
13
|
export const LOG_GROUP_HOOK = 'hook';
|
|
14
14
|
export const LOG_GROUP_COMPLIANCE = 'compliance';
|
|
15
15
|
export const LOG_GROUP_AUDIT = 'audit';
|
package/dist/dialog_prefs_cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* CLI for macOS non-restart autofix dialogs and dialog preferences in
|
|
3
|
+
* CLI for macOS non-restart autofix dialogs and dialog preferences in ~/.optimuslabs/management.
|
|
4
4
|
* Invoked from optimus-compliance-check.sh hooks.
|
|
5
5
|
*/
|
|
6
6
|
import { execFileSync } from 'node:child_process';
|
|
@@ -2,9 +2,9 @@ import path from 'node:path';
|
|
|
2
2
|
import { postStartupPayload } from '../../endpoint_client/index.js';
|
|
3
3
|
import { ensureAuthentication as ensureTofuAuthentication } from '../../tofu.js';
|
|
4
4
|
import { loadEndpointBase } from '../sender/endpoint_config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { OPTIMUSLABS_MANAGEMENT_REL } from '../../bootstrap_constants.js';
|
|
6
6
|
import { hookRunLog } from '../runtime/hook_logger.js';
|
|
7
|
-
const AUTH_KEY_RELATIVE_PATH = path.join(
|
|
7
|
+
const AUTH_KEY_RELATIVE_PATH = path.join(OPTIMUSLABS_MANAGEMENT_REL, 'auth', 'auth_key.txt');
|
|
8
8
|
/** Ensure authentication — verify stored key or request new one via handshake. */
|
|
9
9
|
async function ensureAuthentication(hardwareUuid, endpointBase) {
|
|
10
10
|
const key = await ensureTofuAuthentication({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { getAuthKeyPath as getSharedAuthKeyPath, readStoredAuthKey as readSharedStoredAuthKey, } from '../../tofu.js';
|
|
3
|
-
import {
|
|
4
|
-
const AUTH_KEY_RELATIVE_PATH = path.join(
|
|
3
|
+
import { OPTIMUSLABS_MANAGEMENT_REL } from '../../bootstrap_constants.js';
|
|
4
|
+
const AUTH_KEY_RELATIVE_PATH = path.join(OPTIMUSLABS_MANAGEMENT_REL, 'auth', 'auth_key.txt');
|
|
5
5
|
const AUTH_KEY_OPTIONS = { authRelativePath: AUTH_KEY_RELATIVE_PATH };
|
|
6
6
|
/** Return absolute path to auth_key.txt, or null if home dir is unavailable. */
|
|
7
7
|
function getAuthKeyPath() {
|
|
@@ -235,6 +235,7 @@ export { collectCursorTokenUsage } from './cursor_token_usage_collector.js';
|
|
|
235
235
|
export { collectHermesTokenUsage } from './hermes_token_usage_collector.js';
|
|
236
236
|
export { collectOpenclawTokenUsage } from './openclaw_token_usage_collector.js';
|
|
237
237
|
export { collectPiTokenUsage } from './pi_token_usage_collector.js';
|
|
238
|
+
export { collectCoworkDesktopVersion } from './cowork_desktop_version_collector.js';
|
|
238
239
|
export { collectClaudeDesktopExtensionManifests, collectClaudeDesktopExtensionSettingsFiles, enrichClaudeDesktopExtensionsInstallationsUpload, mergeClaudeDesktopExtensionEnableSettings, } from './claude_desktop_extensions_collector.js';
|
|
239
240
|
export { collectCursorProjectWorkspaceMcpConfigs } from './cursor_project_mcp_collector.js';
|
|
240
241
|
export { determineFileTypeFromPath } from './file_type_rules.js';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
/**
|
|
6
|
+
* Claude Desktop app version, surfaced as Cowork's Agent Profile `agent_version`.
|
|
7
|
+
*
|
|
8
|
+
* Cowork has no per-session version signal — its `local_<sessionId>.json` session files
|
|
9
|
+
* (see cowork_session_whitelist.ts) carry no version field, confirmed against a live install.
|
|
10
|
+
* Cowork runs inside the Claude Desktop app rather than as a standalone CLI, so the app's own
|
|
11
|
+
* bundle version is the only real "version" available for it: `CFBundleShortVersionString` from
|
|
12
|
+
* Claude.app's Info.plist, read via `plutil` (a stock macOS binary — no new dependency, same
|
|
13
|
+
* shell-out pattern as the sqlite3-based collectors).
|
|
14
|
+
*
|
|
15
|
+
* Gated on the Cowork enablement marker (~/Library/Application Support/Claude/
|
|
16
|
+
* cowork-enabled-cli-ops.json) so a machine with Claude Desktop installed but Cowork never
|
|
17
|
+
* enabled doesn't get an agent=cowork version row. macOS only — Claude Desktop/Cowork ships on
|
|
18
|
+
* macOS today.
|
|
19
|
+
*/
|
|
20
|
+
const FILE_TYPE = 'cowork_desktop_version';
|
|
21
|
+
const BUNDLE_VERSION_KEY = 'CFBundleShortVersionString';
|
|
22
|
+
const CLAUDE_APP_INFO_PLIST = '/Applications/Claude.app/Contents/Info.plist';
|
|
23
|
+
function coworkEnabledMarkerPath(home) {
|
|
24
|
+
return join(home, 'Library', 'Application Support', 'Claude', 'cowork-enabled-cli-ops.json');
|
|
25
|
+
}
|
|
26
|
+
/** `plutil -extract CFBundleShortVersionString raw <path>`, or '' when plutil/the plist is unavailable. */
|
|
27
|
+
function readBundleVersion(plistPath) {
|
|
28
|
+
try {
|
|
29
|
+
return execFileSync('/usr/bin/plutil', ['-extract', BUNDLE_VERSION_KEY, 'raw', plistPath], {
|
|
30
|
+
encoding: 'utf8',
|
|
31
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
32
|
+
}).trim();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Emit the Claude Desktop app version as a single-element aggregate, or [] when this isn't
|
|
40
|
+
* macOS, Cowork isn't enabled on this machine, or Claude.app/plutil is unavailable.
|
|
41
|
+
*/
|
|
42
|
+
function collectCoworkDesktopVersion(home = homedir(), plistPath = CLAUDE_APP_INFO_PLIST) {
|
|
43
|
+
if (process.platform !== 'darwin')
|
|
44
|
+
return [];
|
|
45
|
+
if (!existsSync(coworkEnabledMarkerPath(home)))
|
|
46
|
+
return [];
|
|
47
|
+
if (!existsSync(plistPath))
|
|
48
|
+
return [];
|
|
49
|
+
const version = readBundleVersion(plistPath);
|
|
50
|
+
if (!version)
|
|
51
|
+
return [];
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
file_type: FILE_TYPE,
|
|
55
|
+
file_path: plistPath,
|
|
56
|
+
raw_content: { version },
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
export { collectCoworkDesktopVersion, FILE_TYPE as COWORK_DESKTOP_VERSION_FILE_TYPE };
|
|
@@ -21,6 +21,12 @@ import { homedir } from 'node:os';
|
|
|
21
21
|
* only — never any other key (openclaw.json's other sections can carry messaging/provider
|
|
22
22
|
* settings).
|
|
23
23
|
*
|
|
24
|
+
* Auth method comes from a scoped read of openclaw.json's `auth.profiles.*` entries — each
|
|
25
|
+
* profile is `{provider, mode}` (e.g. `{"provider": "anthropic", "mode": "api_key"}`); we read
|
|
26
|
+
* only those two keys, never any credential material (profiles carry no token/key fields to
|
|
27
|
+
* begin with). Exposed per-provider so the extractor can match it against the provider actually
|
|
28
|
+
* observed in session usage.
|
|
29
|
+
*
|
|
24
30
|
* Only checks ~/.openclaw (the canonical root); the moltbot/clawdbot compatible-fork roots
|
|
25
31
|
* tracked by the presence/log file types are not covered here.
|
|
26
32
|
*/
|
|
@@ -113,6 +119,34 @@ function readVersion(openclawDir) {
|
|
|
113
119
|
return '';
|
|
114
120
|
}
|
|
115
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Scoped read of openclaw.json's `auth.profiles` — provider + mode only, never credentials
|
|
124
|
+
* (the profiles carry no token/key fields). Returns a provider -> mode map (e.g.
|
|
125
|
+
* `{"anthropic": "api_key"}`); a provider with multiple profiles keeps the last one read.
|
|
126
|
+
*/
|
|
127
|
+
function readAuthModesByProvider(openclawDir) {
|
|
128
|
+
try {
|
|
129
|
+
const raw = JSON.parse(readFileSync(join(openclawDir, 'openclaw.json'), 'utf8'));
|
|
130
|
+
const auth = raw.auth;
|
|
131
|
+
const profiles = auth && typeof auth === 'object' ? auth.profiles : undefined;
|
|
132
|
+
const out = {};
|
|
133
|
+
if (profiles && typeof profiles === 'object') {
|
|
134
|
+
for (const value of Object.values(profiles)) {
|
|
135
|
+
if (!value || typeof value !== 'object')
|
|
136
|
+
continue;
|
|
137
|
+
const entry = value;
|
|
138
|
+
const provider = str(entry.provider);
|
|
139
|
+
const mode = str(entry.mode);
|
|
140
|
+
if (provider && mode)
|
|
141
|
+
out[provider] = mode;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return {};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
116
150
|
/**
|
|
117
151
|
* Aggregate OpenClaw session count / token usage / models / providers / version across every
|
|
118
152
|
* agent dir's sessions.json store. Returns a single-element array (one per-machine aggregate)
|
|
@@ -148,6 +182,7 @@ function collectOpenclawTokenUsage(home = homedir()) {
|
|
|
148
182
|
model_token_split: acc.modelTokenSplit,
|
|
149
183
|
window_days: TOKEN_USAGE_RECENCY_DAYS,
|
|
150
184
|
totals: acc.totals,
|
|
185
|
+
auth_modes_by_provider: readAuthModesByProvider(openclawDir),
|
|
151
186
|
},
|
|
152
187
|
},
|
|
153
188
|
];
|
|
@@ -9,9 +9,11 @@ import { resolveSqlite3Binary } from '../runtime/sqlite_binary.js';
|
|
|
9
9
|
* Unlike Claude/Copilot (JSONL transcripts), OpenCode stores everything in a SQLite DB at
|
|
10
10
|
* ~/.local/share/opencode/opencode.db. Each assistant row in the `message` table has a JSON
|
|
11
11
|
* `data` blob carrying `modelID`, `providerID`, `tokens` ({input,output,reasoning,cache:{read,write}})
|
|
12
|
-
* and `cost`; the `account` table carries the login `email`/`url
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
12
|
+
* and `cost`; the `account` table carries the login `email`/`url`; the singleton `account_state`
|
|
13
|
+
* row carries `active_org_id` (an org identifier — no org *name* exists anywhere in the schema).
|
|
14
|
+
* We read those via the bundled `sqlite3` binary (same resolver the remediation path uses) and
|
|
15
|
+
* emit only the aggregated numbers (plus the login email / org id) — never message content. The
|
|
16
|
+
* DB is opened read-only.
|
|
15
17
|
*
|
|
16
18
|
* Bounded by DB-file mtime recency so a stale install isn't re-read every hook run.
|
|
17
19
|
*/
|
|
@@ -151,6 +153,10 @@ function collectOpencodeTokenUsage(home = homedir()) {
|
|
|
151
153
|
.replace(/^https?:\/\//, '')
|
|
152
154
|
.replace(/\/$/, '');
|
|
153
155
|
}
|
|
156
|
+
// Singleton row; absent on older installs/schemas without account_state — querySqlite
|
|
157
|
+
// returns null on "no such table" and orgIdRaw stays empty in that case.
|
|
158
|
+
const orgIdRaw = querySqlite(sqlite3, dbPath, "SELECT COALESCE(active_org_id, '') FROM account_state LIMIT 1;");
|
|
159
|
+
const orgId = orgIdRaw ? orgIdRaw.trim() : '';
|
|
154
160
|
if (!sawData && !email)
|
|
155
161
|
return [];
|
|
156
162
|
return [
|
|
@@ -166,6 +172,7 @@ function collectOpencodeTokenUsage(home = homedir()) {
|
|
|
166
172
|
cost,
|
|
167
173
|
email,
|
|
168
174
|
host,
|
|
175
|
+
org_id: orgId,
|
|
169
176
|
window_days: TOKEN_USAGE_RECENCY_DAYS,
|
|
170
177
|
totals,
|
|
171
178
|
},
|
|
@@ -14,10 +14,11 @@ import { homedir } from 'node:os';
|
|
|
14
14
|
* session count, and models/providers used without ingesting transcript content.
|
|
15
15
|
*
|
|
16
16
|
* Configured defaults come from a scoped read of settings.json's `defaultProvider` /
|
|
17
|
-
* `defaultModel` / `lastChangelogVersion` keys only — never any other key.
|
|
18
|
-
*
|
|
19
|
-
* (`{"anthropic": {"type": ...,
|
|
20
|
-
* auth.json.
|
|
17
|
+
* `defaultModel` / `lastChangelogVersion` keys only — never any other key.
|
|
18
|
+
*
|
|
19
|
+
* auth.json holds literal per-provider `{type, key}` blobs (`{"anthropic": {"type": ...,
|
|
20
|
+
* "key": ...}}`), the same risk class as Hermes's/Codex's auth.json. We read only the `type`
|
|
21
|
+
* field per provider (e.g. `"api_key"`) — never `key`, the actual credential.
|
|
21
22
|
*
|
|
22
23
|
* `lastChangelogVersion` (confirmed against a real install: "0.80.3", matching `pi --version`
|
|
23
24
|
* exactly) is a best-effort CLI version signal, not a guaranteed-current one — it records the
|
|
@@ -83,6 +84,27 @@ function readDefaults(home) {
|
|
|
83
84
|
return { provider: '', model: '', version: '' };
|
|
84
85
|
}
|
|
85
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Scoped read of auth.json's per-provider `type` field only — never the sibling `key`
|
|
89
|
+
* credential. Returns a provider -> type map (e.g. `{"anthropic": "api_key"}`).
|
|
90
|
+
*/
|
|
91
|
+
function readAuthTypesByProvider(home) {
|
|
92
|
+
try {
|
|
93
|
+
const raw = JSON.parse(readFileSync(join(home, '.pi', 'agent', 'auth.json'), 'utf8'));
|
|
94
|
+
const out = {};
|
|
95
|
+
for (const [provider, value] of Object.entries(raw)) {
|
|
96
|
+
if (!value || typeof value !== 'object')
|
|
97
|
+
continue;
|
|
98
|
+
const type = str(value.type);
|
|
99
|
+
if (type)
|
|
100
|
+
out[provider] = type;
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
86
108
|
/**
|
|
87
109
|
* Aggregate Pi session count / token usage / models / providers across recent session
|
|
88
110
|
* transcripts. Returns a single-element array (one per-machine aggregate) or [] when there is
|
|
@@ -173,6 +195,7 @@ function collectPiTokenUsage(home = homedir()) {
|
|
|
173
195
|
configured_provider: defaults.provider,
|
|
174
196
|
window_days: TOKEN_USAGE_RECENCY_DAYS,
|
|
175
197
|
totals,
|
|
198
|
+
auth_types_by_provider: readAuthTypesByProvider(home),
|
|
176
199
|
},
|
|
177
200
|
},
|
|
178
201
|
];
|
|
@@ -27,7 +27,7 @@ export function getInstalledPluginsPath(home, constants) {
|
|
|
27
27
|
return join(home, rel.replace(/^~\//, ''));
|
|
28
28
|
}
|
|
29
29
|
export function getOptAiSecManagementPath(home, constants) {
|
|
30
|
-
const rel = requireKey(constants, '
|
|
30
|
+
const rel = requireKey(constants, 'optimuslabs_management_under_home', '.optimuslabs management path');
|
|
31
31
|
return join(home, rel.replace(/^~\//, ''));
|
|
32
32
|
}
|
|
33
33
|
export function getAuthKeyPathFromConstants(home, constants) {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { existsSync, mkdirSync, appendFileSync, readFileSync, renameSync, unlinkSync, statSync } from 'node:fs';
|
|
14
14
|
import path from 'node:path';
|
|
15
15
|
import { randomUUID } from 'node:crypto';
|
|
16
|
-
import {
|
|
16
|
+
import { OPTIMUSLABS_MANAGEMENT_REL } from '../../bootstrap_constants.js';
|
|
17
17
|
import { executeBody } from '../../endpoint_client/http_transport.js';
|
|
18
18
|
import { loadEndpointBase } from '../sender/endpoint_config.js';
|
|
19
19
|
import { createSignature } from '../sender/signing.js';
|
|
@@ -29,7 +29,7 @@ function bufferPath() {
|
|
|
29
29
|
const home = process.env.HOME || process.env.USERPROFILE;
|
|
30
30
|
if (!home)
|
|
31
31
|
return null;
|
|
32
|
-
return path.join(home,
|
|
32
|
+
return path.join(home, OPTIMUSLABS_MANAGEMENT_REL, 'telemetry', BUFFER_BASENAME);
|
|
33
33
|
}
|
|
34
34
|
/** Keep filename-safe chars only — must match optimus_sanitize_id in optimus-hook-common.sh. */
|
|
35
35
|
function sanitizeId(v) {
|
|
@@ -40,7 +40,7 @@ function storyFilePath() {
|
|
|
40
40
|
const home = process.env.HOME || process.env.USERPROFILE;
|
|
41
41
|
if (!home)
|
|
42
42
|
return null;
|
|
43
|
-
const telemetryDir = path.join(home,
|
|
43
|
+
const telemetryDir = path.join(home, OPTIMUSLABS_MANAGEMENT_REL, 'telemetry');
|
|
44
44
|
const session = sanitizeId((process.env.OPTIMUS_SESSION_ID || '').trim());
|
|
45
45
|
if (session) {
|
|
46
46
|
const agent = sanitizeId((process.env.OPTIMUS_HOOK_TYPE || process.env.OPTIMUS_AGENT || 'claude').trim()) || 'claude';
|
|
@@ -107,7 +107,7 @@ function hookRunFilePath() {
|
|
|
107
107
|
const home = process.env.HOME || process.env.USERPROFILE;
|
|
108
108
|
if (!home)
|
|
109
109
|
return null;
|
|
110
|
-
return path.join(home,
|
|
110
|
+
return path.join(home, OPTIMUSLABS_MANAGEMENT_REL, 'telemetry', 'current_hook_run.id');
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
113
|
* hook_run_id: one uuid per shell hook invocation.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync, appendFileSync, readFileSync, } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
|
-
import {
|
|
4
|
+
import { OPTIMUSLABS_LOGS_REL, LOG_GROUP_COMPLIANCE } from '../../bootstrap_constants.js';
|
|
5
5
|
import { buildLogMetadataBlock } from './log_metadata.js';
|
|
6
6
|
const COMPLIANCE_SUBDIR = LOG_GROUP_COMPLIANCE;
|
|
7
7
|
const TIER_NOOP = 'noop';
|
|
@@ -35,7 +35,7 @@ export function isFinalizeComplianceSessionArgv(argv) {
|
|
|
35
35
|
return argv.includes('--finalize-compliance-session');
|
|
36
36
|
}
|
|
37
37
|
export function getComplianceLogDir() {
|
|
38
|
-
return path.join(homedir(),
|
|
38
|
+
return path.join(homedir(), OPTIMUSLABS_LOGS_REL, COMPLIANCE_SUBDIR);
|
|
39
39
|
}
|
|
40
40
|
export function getActiveComplianceLogPath() {
|
|
41
41
|
return activeComplianceLogPath;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, appendFileSync, writeFileSync, statSync, readFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { OPTIMUSLABS_LOGS_REL, LOG_GROUP_HOOK, LOG_GROUP_COMPLIANCE, } from '../../bootstrap_constants.js';
|
|
4
4
|
import { getActiveComplianceLogPath } from './compliance_session_log.js';
|
|
5
5
|
import { buildLogMetadataBlock, formatErrorBlock } from './log_metadata.js';
|
|
6
6
|
const HOOK_LOG_FILENAME = 'hook_log.txt';
|
|
@@ -12,13 +12,13 @@ function getHookLogPath() {
|
|
|
12
12
|
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
13
13
|
if (!homeDir)
|
|
14
14
|
return null;
|
|
15
|
-
return path.join(homeDir,
|
|
15
|
+
return path.join(homeDir, OPTIMUSLABS_LOGS_REL, LOG_GROUP_HOOK, HOOK_LOG_FILENAME);
|
|
16
16
|
}
|
|
17
17
|
function getComplianceRunnerLogPath() {
|
|
18
18
|
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
19
19
|
if (!homeDir)
|
|
20
20
|
return null;
|
|
21
|
-
return path.join(homeDir,
|
|
21
|
+
return path.join(homeDir, OPTIMUSLABS_LOGS_REL, LOG_GROUP_COMPLIANCE, COMPLIANCE_FALLBACK_TIER, COMPLIANCE_RUNNER_LOG_FILENAME);
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Append one ISO-timestamped line to the active compliance session log.
|
|
@@ -7,7 +7,7 @@ import os from 'node:os';
|
|
|
7
7
|
import { existsSync, readFileSync } from 'node:fs';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { fileURLToPath } from 'node:url';
|
|
10
|
-
import {
|
|
10
|
+
import { OPTIMUSLABS_MANAGEMENT_REL } from '../../bootstrap_constants.js';
|
|
11
11
|
/** This package's name + version as "<name>: <version>", read from its own package.json. */
|
|
12
12
|
function readPackageVersion() {
|
|
13
13
|
try {
|
|
@@ -28,7 +28,7 @@ function readBundleVersion() {
|
|
|
28
28
|
const home = process.env.HOME || process.env.USERPROFILE;
|
|
29
29
|
if (!home)
|
|
30
30
|
return 'unknown';
|
|
31
|
-
const p = path.join(home,
|
|
31
|
+
const p = path.join(home, OPTIMUSLABS_MANAGEMENT_REL, 'release', 'bundle-version.json');
|
|
32
32
|
try {
|
|
33
33
|
if (!existsSync(p))
|
|
34
34
|
return 'unknown';
|
|
@@ -3,7 +3,7 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
const HOME_DIR = homedir();
|
|
5
5
|
import { getFileCollectionPatterns, FILE_PATH_REGISTRY_FILE_PATTERNS_PATH } from '../../endpoint_client/index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { OPTIMUSLABS_LOGS_REL, LOG_GROUP_AUDIT } from '../../bootstrap_constants.js';
|
|
7
7
|
import { runSensitivePathsAudit } from '../../log_sensitive_paths_audit.js';
|
|
8
8
|
import { loadEndpointBase, getEndpointSource } from '../sender/endpoint_config.js';
|
|
9
9
|
import { hookLogReplace, hookRunLog, hookLogError, readHookLog } from './hook_logger.js';
|
|
@@ -14,7 +14,7 @@ import { ensureAuthentication } from '../auth/auth_flow.js';
|
|
|
14
14
|
import { readJSONFile, readMarkdownFile } from '../readers/file_readers.js';
|
|
15
15
|
import { isVscdbVirtualPath, tryReadVscdbVirtualFile, summarizeComposerPayloadForDiagnostics, } from '../readers/vscdb_config_builder.js';
|
|
16
16
|
import { persistVscdbComposerContractFromPatternsResponse } from '../readers/vscdb_reader.js';
|
|
17
|
-
import { collectConfigFilesFromPatterns, collectMcpToolFiles, collectConfigFilesFromInstalledPlugins, collectPluginCacheMcpFiles, collectMcpFromClaudeJsonProjects, collectClaudeTokenUsage, collectCopilotTokenUsage, collectOpencodeTokenUsage, collectCodexTokenUsage, collectCursorTokenUsage, collectHermesTokenUsage, collectOpenclawTokenUsage, collectPiTokenUsage, collectClaudeDesktopExtensionManifests, collectClaudeDesktopExtensionSettingsFiles, enrichClaudeDesktopExtensionsInstallationsUpload, determineFileTypeFromPath, } from '../collection/config_collector.js';
|
|
17
|
+
import { collectConfigFilesFromPatterns, collectMcpToolFiles, collectConfigFilesFromInstalledPlugins, collectPluginCacheMcpFiles, collectMcpFromClaudeJsonProjects, collectClaudeTokenUsage, collectCopilotTokenUsage, collectOpencodeTokenUsage, collectCodexTokenUsage, collectCursorTokenUsage, collectHermesTokenUsage, collectOpenclawTokenUsage, collectPiTokenUsage, collectCoworkDesktopVersion, collectClaudeDesktopExtensionManifests, collectClaudeDesktopExtensionSettingsFiles, enrichClaudeDesktopExtensionsInstallationsUpload, determineFileTypeFromPath, } from '../collection/config_collector.js';
|
|
18
18
|
import { ensureCursorUserSettingsSnapshotInBatch } from '../collection/ensure_cursor_user_settings_snapshot.js';
|
|
19
19
|
import { collectSkillsCliInstalled } from '../collection/skills_cli_collector.js';
|
|
20
20
|
import { collectWorkspaceVscdbs } from '../collection/mcp_tool_collector.js';
|
|
@@ -162,6 +162,14 @@ async function collectAllConfigFiles(endpointBase) {
|
|
|
162
162
|
configFiles.push(entry);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
+
hookRunLog(`reading Claude Desktop app version for Cowork's Agent Profile`);
|
|
166
|
+
for (const entry of collectCoworkDesktopVersion(HOME_DIR)) {
|
|
167
|
+
const key = `${entry.file_type}\t${entry.file_path}`;
|
|
168
|
+
if (!existingPaths.has(key)) {
|
|
169
|
+
existingPaths.add(key);
|
|
170
|
+
configFiles.push(entry);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
165
173
|
hookRunLog(`merging disk-only Claude Desktop extensions into extensions-installations.json`);
|
|
166
174
|
const diskExtMerge = enrichClaudeDesktopExtensionsInstallationsUpload(configFiles, HOME_DIR);
|
|
167
175
|
hookRunLog(`claude desktop extensions: merged=${diskExtMerge.mergedCount} had_registry_upload=${diskExtMerge.hadRegistryUpload}`);
|
|
@@ -199,7 +207,7 @@ async function collectAllConfigFiles(endpointBase) {
|
|
|
199
207
|
}
|
|
200
208
|
async function addSensitivePathsAudit(endpointBase, configFiles) {
|
|
201
209
|
hookRunLog(`running sensitive paths audit`);
|
|
202
|
-
const auditOutputDir = join(homedir(),
|
|
210
|
+
const auditOutputDir = join(homedir(), OPTIMUSLABS_LOGS_REL, LOG_GROUP_AUDIT);
|
|
203
211
|
try {
|
|
204
212
|
const auditResult = await runSensitivePathsAudit(endpointBase, auditOutputDir, PROJECT_ROOT);
|
|
205
213
|
hookRunLog(`sensitive_paths_audit: ${auditResult.paths.length} path(s)`);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Paths and JSON persistence for
|
|
2
|
+
* Paths and JSON persistence for ~/.optimuslabs/management:
|
|
3
3
|
* - remediation_instructions.json (remediations[])
|
|
4
4
|
*/
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
6
6
|
import { dirname, join } from 'node:path';
|
|
7
7
|
import { homedir } from 'node:os';
|
|
8
|
-
import {
|
|
8
|
+
import { OPTIMUSLABS_MANAGEMENT_REL, OPTIMUSLABS_LOGS_REL } from '../../bootstrap_constants.js';
|
|
9
9
|
export const REMEDIATION_INSTRUCTIONS_BASENAME = 'remediation_instructions.json';
|
|
10
10
|
/** Pending state.vscdb writes applied after Cursor exits (IDE holds the DB locked). */
|
|
11
11
|
export const DEFERRED_VSCDB_APPLY_BASENAME = 'optimus_deferred_vscdb_apply.json';
|
|
@@ -51,14 +51,14 @@ export function sanitizeFileCollectionVscdbContract(contract) {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
export function getManagementDir() {
|
|
54
|
-
return join(homedir(),
|
|
54
|
+
return join(homedir(), OPTIMUSLABS_MANAGEMENT_REL);
|
|
55
55
|
}
|
|
56
|
-
/** Root of the grouped hook log subtree (
|
|
56
|
+
/** Root of the grouped hook log subtree (~/.optimuslabs/management/logs). */
|
|
57
57
|
export function getLogsDir() {
|
|
58
|
-
return join(homedir(),
|
|
58
|
+
return join(homedir(), OPTIMUSLABS_LOGS_REL);
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* Directory for vscdb state/contract files (
|
|
61
|
+
* Directory for vscdb state/contract files (~/.optimuslabs/management/vscdb), keeping the
|
|
62
62
|
* several generated vscdb artifacts grouped instead of dangling at the management root.
|
|
63
63
|
* Includes deferred_vscdb_restart.log (detached restart pipeline output).
|
|
64
64
|
*/
|
|
@@ -66,7 +66,7 @@ export function getVscdbStateDir() {
|
|
|
66
66
|
return join(getManagementDir(), 'vscdb');
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
* Directory for non-log remediation state (
|
|
69
|
+
* Directory for non-log remediation state (~/.optimuslabs/management/remediation):
|
|
70
70
|
* remediation_instructions.json (what to fix) and remediation_apply_tracking.json
|
|
71
71
|
* (quarantine + verify-failure history that escapes the autofix restart loop).
|
|
72
72
|
* Remediation session logs live under logs/compliance/.
|
|
@@ -86,7 +86,7 @@ export function getDeferredVscdbRestartLogPath() {
|
|
|
86
86
|
export function getFileCollectionVscdbContractPath() {
|
|
87
87
|
return join(getVscdbStateDir(), FILE_COLLECTION_VSCDB_CONTRACT_BASENAME);
|
|
88
88
|
}
|
|
89
|
-
/** Directory for macOS dialog assets/state (
|
|
89
|
+
/** Directory for macOS dialog assets/state (~/.optimuslabs/management/dialog): prefs + cached icon. */
|
|
90
90
|
export function getDialogStateDir() {
|
|
91
91
|
return join(getManagementDir(), 'dialog');
|
|
92
92
|
}
|
|
@@ -541,7 +541,7 @@ function assertSafeSqliteIdentifiersForItemTable(table, keyColumn, valueColumn)
|
|
|
541
541
|
* Canonical Cursor restart_command strings — single source for buildDeferredCursorRestartCommand + allowlist.
|
|
542
542
|
*
|
|
543
543
|
* - **SQLite / state.vscdb (deferred):** autofix queued ItemTable writes; restart runs `apply_deferred_vscdb` then reopens Cursor.
|
|
544
|
-
* Routing matches shell hooks (`optimus-compliance-check.sh`): read
|
|
544
|
+
* Routing matches shell hooks (`optimus-compliance-check.sh`): read `~/.optimuslabs/management/optimus_dev.env`
|
|
545
545
|
* (then `OPTIMUS_ENVIRONMENT`), use `npx=` base for local `dist` when `environment=development`,
|
|
546
546
|
* `log-llm-config-staging@latest` when `environment=staging`, else production package.
|
|
547
547
|
* - **JSON settings files:** autofix wrote normal config JSON; restart is kill + reopen only (no deferred apply).
|
|
@@ -551,8 +551,8 @@ function assertSafeSqliteIdentifiersForItemTable(table, keyColumn, valueColumn)
|
|
|
551
551
|
*/
|
|
552
552
|
const TRUSTED_CURSOR_SQLITE_DEFERRED_RESTART_COMMAND = 'REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) && export REPO_ROOT && ' +
|
|
553
553
|
'CURSOR_PROJECT="${CURSOR_PROJECT_DIR:-$REPO_ROOT}" && export CURSOR_PROJECT && ' +
|
|
554
|
-
'OPTIMUS_DEFERRED_LOG="${HOME}/
|
|
555
|
-
"nohup bash -c 'exec >>\"\$OPTIMUS_DEFERRED_LOG\" 2>&1; echo deferred_restart:begin ts=\$(date -u +%Y-%m-%dT%H:%M:%SZ) REPO_ROOT=\"\$REPO_ROOT\" CURSOR_PROJECT=\"\$CURSOR_PROJECT\"; sleep 2; STATIC_DEV_ENV=\"\$HOME/
|
|
554
|
+
'OPTIMUS_DEFERRED_LOG="${HOME}/.optimuslabs/management/vscdb/deferred_vscdb_restart.log" && mkdir -p "$(dirname "$OPTIMUS_DEFERRED_LOG")" && export OPTIMUS_DEFERRED_LOG && ' +
|
|
555
|
+
"nohup bash -c 'exec >>\"\$OPTIMUS_DEFERRED_LOG\" 2>&1; echo deferred_restart:begin ts=\$(date -u +%Y-%m-%dT%H:%M:%SZ) REPO_ROOT=\"\$REPO_ROOT\" CURSOR_PROJECT=\"\$CURSOR_PROJECT\"; sleep 2; STATIC_DEV_ENV=\"\$HOME/.optimuslabs/management/optimus_dev.env\"; ENV_LABEL=\"\"; if [ -f \"\$STATIC_DEV_ENV\" ]; then ENV_LABEL=\$(grep -E \"^(environment|ENVIRONMENT|OPTIMUS_ENVIRONMENT)=\" \"\$STATIC_DEV_ENV\" 2>/dev/null | head -1 | cut -d\"=\" -f2- | tr \"[:upper:]\" \"[:lower:]\" | xargs); fi; if [ -z \"\$ENV_LABEL\" ] && [ -n \"\${OPTIMUS_ENVIRONMENT:-}\" ]; then ENV_LABEL=\$(printf \"%s\" \"\$OPTIMUS_ENVIRONMENT\" | tr \"[:upper:]\" \"[:lower:]\" | xargs); fi; [ -z \"\$ENV_LABEL\" ] && ENV_LABEL=\"production\"; NPX_BASE=\"\"; if [ -f \"\$STATIC_DEV_ENV\" ]; then _nb=\$(grep -E \"^npx=\" \"\$STATIC_DEV_ENV\" 2>/dev/null | head -1 | cut -d\"=\" -f2- | xargs); [ -n \"\$_nb\" ] && [ -d \"\$_nb\" ] && NPX_BASE=\"\$_nb\"; fi; p=\"\${npm_config_prefix:-\${NPM_CONFIG_PREFIX:-}}\"; gp=\"\${npm_config_global_prefix:-}\"; gc=\"\${npm_config_globalconfig:-}\"; if [[ \"\$p\" == *\"/Applications/Cursor.app/\"* ]] || [[ \"\$gp\" == *\"/Applications/Cursor.app/\"* ]] || [[ \"\$gc\" == *\"/Applications/Cursor.app/\"* ]]; then unset npm_config_prefix NPM_CONFIG_PREFIX npm_config_global_prefix npm_config_globalconfig npm_node_execpath 2>/dev/null; fi; APPLY_EC=0; if [ -f \"\$REPO_ROOT/dev_npx_packages/log-llm-config/dist/apply_deferred_vscdb.js\" ]; then echo deferred_restart:apply_via_dev_npx_packages; node \"\$REPO_ROOT/dev_npx_packages/log-llm-config/dist/apply_deferred_vscdb.js\"; APPLY_EC=\$?; elif [ \"\$ENV_LABEL\" = \"development\" ] && [ -n \"\$NPX_BASE\" ] && [ -f \"\$NPX_BASE/log-llm-config/dist/apply_deferred_vscdb.js\" ]; then echo deferred_restart:apply_via_optimus_npx_base; node \"\$NPX_BASE/log-llm-config/dist/apply_deferred_vscdb.js\"; APPLY_EC=\$?; elif command -v npx >/dev/null 2>&1; then echo deferred_restart:apply_via_npx env=\"\$ENV_LABEL\"; cd \"\$REPO_ROOT\" || true; if [ \"\$ENV_LABEL\" = \"staging\" ]; then npx --yes --package=log-llm-config-staging@latest apply-deferred-vscdb-staging; APPLY_EC=\$?; else npx --yes --package=log-llm-config@latest apply-deferred-vscdb; APPLY_EC=\$?; fi; else echo deferred_restart:no_npx; APPLY_EC=127; fi; echo deferred_restart:apply_exit=\$APPLY_EC; if [ \$APPLY_EC -ne 0 ]; then echo deferred_restart:APPLY_FAILED_see_messages_above; fi; echo deferred_restart:open_cursor; env -u npm_config_package -u npm_lifecycle_event -u npm_lifecycle_script -u npm_config_local_prefix open -a Cursor \"\$CURSOR_PROJECT\"; echo deferred_restart:open_exit=\$?; echo deferred_restart:end ts=\$(date -u +%Y-%m-%dT%H:%M:%SZ)' >/dev/null 2>&1 & killall -9 Cursor";
|
|
556
556
|
/** Legacy manifests; hooks may run with cwd under `.cursor` where `pwd` is wrong. */
|
|
557
557
|
const TRUSTED_CURSOR_JSON_SETTINGS_RESTART_COMMAND_LEGACY = 'CURSOR_PROJECT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) && export CURSOR_PROJECT && nohup bash -c \'sleep 2 && open -a Cursor "$CURSOR_PROJECT"\' >/dev/null 2>&1 & killall -9 Cursor';
|
|
558
558
|
const TRUSTED_CURSOR_JSON_SETTINGS_RESTART_COMMAND = 'REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) && export REPO_ROOT && ' +
|
|
@@ -43,7 +43,7 @@ function readOrganizationUuid() {
|
|
|
43
43
|
if (envValue)
|
|
44
44
|
return envValue;
|
|
45
45
|
try {
|
|
46
|
-
return fs.readFileSync(path.join(os.homedir(), '
|
|
46
|
+
return fs.readFileSync(path.join(os.homedir(), '.optimuslabs', 'management', 'org', 'organization-uuid.txt'), 'utf8').trim();
|
|
47
47
|
}
|
|
48
48
|
catch {
|
|
49
49
|
return '';
|
|
@@ -10,7 +10,7 @@ import { existsSync, writeFileSync, mkdirSync, statSync } from 'node:fs';
|
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { homedir } from 'node:os';
|
|
12
12
|
import { getSensitivePathsAuditCandidates } from './endpoint_client/index.js';
|
|
13
|
-
import {
|
|
13
|
+
import { OPTIMUSLABS_LOGS_REL, LOG_GROUP_AUDIT } from './bootstrap_constants.js';
|
|
14
14
|
import { loadEndpointBase } from './log_config_files/sender/endpoint_config.js';
|
|
15
15
|
const AUDIT_FILENAME = 'sensitive_paths_audit.txt';
|
|
16
16
|
function expandPath(template, cwd) {
|
|
@@ -63,7 +63,7 @@ export function writeSensitivePathsAudit(outputDir, pathTemplates, cwd = process
|
|
|
63
63
|
* Run audit: fetch candidates from backend, check existence, write file. Returns paths for sending.
|
|
64
64
|
* Used by log_config_files to include the audit in the same batch (same auth).
|
|
65
65
|
*/
|
|
66
|
-
export async function runSensitivePathsAudit(endpointBase, outputDir = join(homedir(),
|
|
66
|
+
export async function runSensitivePathsAudit(endpointBase, outputDir = join(homedir(), OPTIMUSLABS_LOGS_REL, LOG_GROUP_AUDIT), cwd = process.cwd()) {
|
|
67
67
|
const response = await getSensitivePathsAuditCandidates(endpointBase);
|
|
68
68
|
const pathTemplates = response?.paths ?? [];
|
|
69
69
|
if (pathTemplates.length === 0 && !response) {
|
|
@@ -75,7 +75,7 @@ export async function runSensitivePathsAudit(endpointBase, outputDir = join(home
|
|
|
75
75
|
return { paths };
|
|
76
76
|
}
|
|
77
77
|
export async function main() {
|
|
78
|
-
const outputDir = join(homedir(),
|
|
78
|
+
const outputDir = join(homedir(), OPTIMUSLABS_LOGS_REL, LOG_GROUP_AUDIT);
|
|
79
79
|
const endpointBase = loadEndpointBase();
|
|
80
80
|
await runSensitivePathsAudit(endpointBase, outputDir, process.cwd());
|
|
81
81
|
process.exit(0);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { OPTIMUSLABS_MANAGEMENT_REL } from '../bootstrap_constants.js';
|
|
4
4
|
import { loadEndpointBase } from '../log_config_files/sender/endpoint_config.js';
|
|
5
5
|
import { buildStartupEndpointUrl, normalizeBaseUrl } from '../tofu.js';
|
|
6
|
-
const AUTH_KEY_RELATIVE_PATH = path.join(
|
|
6
|
+
const AUTH_KEY_RELATIVE_PATH = path.join(OPTIMUSLABS_MANAGEMENT_REL, 'auth', 'auth_key.txt');
|
|
7
7
|
const getAuthKeyPath = () => {
|
|
8
8
|
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
9
9
|
if (!homeDir)
|
|
@@ -29,7 +29,7 @@ const readOrganizationUuid = () => {
|
|
|
29
29
|
if (envValue)
|
|
30
30
|
return envValue;
|
|
31
31
|
try {
|
|
32
|
-
return fs.readFileSync(path.join(os.homedir(), '
|
|
32
|
+
return fs.readFileSync(path.join(os.homedir(), '.optimuslabs', 'management', 'org', 'organization-uuid.txt'), 'utf8').trim();
|
|
33
33
|
}
|
|
34
34
|
catch {
|
|
35
35
|
return '';
|
package/dist/tofu.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tofu shim — centralises all imports from optimus-tofu.
|
|
3
3
|
*
|
|
4
|
-
* Reads
|
|
4
|
+
* Reads ~/.optimuslabs/management/optimus_dev.env at startup:
|
|
5
5
|
* - No file / unreadable → staging (ignores OPTIMUS_ENVIRONMENT).
|
|
6
6
|
* - File present → environment= line in file, then OPTIMUS_ENVIRONMENT, then staging.
|
|
7
7
|
* - environment=development + local dist present → loads sibling optimus-tofu dist
|
package/dist/tofu_environment.js
CHANGED
|
@@ -5,7 +5,7 @@ export function managementEnvPath() {
|
|
|
5
5
|
const home = homedir();
|
|
6
6
|
if (!home)
|
|
7
7
|
return null;
|
|
8
|
-
return path.join(home, '
|
|
8
|
+
return path.join(home, '.optimuslabs', 'management', 'optimus_dev.env');
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Resolve optimus environment label (matches shell hooks / optimus-tool-call):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "log-llm-config",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.10",
|
|
4
4
|
"description": "CLI helpers for logging hardware UUIDs and posting startup payloads to Optimus Security.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -58,6 +58,6 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"axios": "^1.15.2",
|
|
60
60
|
"canonicalize": "^2.1.0",
|
|
61
|
-
"optimus-tofu": "^0.1.
|
|
61
|
+
"optimus-tofu": "^0.1.18"
|
|
62
62
|
}
|
|
63
63
|
}
|