openclaw-plugin-vt-sentinel 0.9.2 → 0.11.0
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/CHANGELOG.md +128 -0
- package/README.md +50 -2
- package/dist/config-manager.d.ts +2 -0
- package/dist/config-manager.js +17 -1
- package/dist/env-access.d.ts +18 -0
- package/dist/env-access.js +27 -0
- package/dist/index.d.ts +3 -7
- package/dist/index.js +124 -100
- package/dist/path-extractor.d.ts +6 -2
- package/dist/path-extractor.js +99 -220
- package/dist/scanner.d.ts +19 -5
- package/dist/scanner.js +62 -14
- package/dist/signatures/dangerous-commands.json +82 -0
- package/dist/status-renderer.js +14 -4
- package/dist/vt-api.d.ts +3 -13
- package/dist/vt-api.js +10 -38
- package/dist/vt-credentials.d.ts +27 -0
- package/dist/vt-credentials.js +96 -0
- package/hooks/vt-auto-scan/HOOK.md +8 -0
- package/hooks/vt-auto-scan/handler.js +78 -10
- package/openclaw.plugin.json +24 -1
- package/package.json +24 -6
- package/skills/vt-sentinel/SKILL.md +6 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `openclaw-plugin-vt-sentinel`.
|
|
4
|
+
|
|
5
|
+
## 0.11.0 — Install-scanner compliance
|
|
6
|
+
|
|
7
|
+
**Headline:** installs cleanly on OpenClaw 2026.4.5+ without
|
|
8
|
+
`--dangerously-force-unsafe-install`. All 6 critical findings from the new
|
|
9
|
+
install-security scanner have been eliminated, along with the 1 warn-level
|
|
10
|
+
finding. `npm run scan` now reports `0 critical, 0 warn, 0 total`.
|
|
11
|
+
|
|
12
|
+
### Breaking change — `VIRUSTOTAL_API_KEY` environment variable is no longer read
|
|
13
|
+
|
|
14
|
+
Earlier versions fell back to reading `VIRUSTOTAL_API_KEY` from the shell
|
|
15
|
+
environment when no plugin-config `apiKey` was present. That behavior is
|
|
16
|
+
**removed in 0.11.0**.
|
|
17
|
+
|
|
18
|
+
**Migration:** if you exported `VIRUSTOTAL_API_KEY=vt_xxx` in your shell,
|
|
19
|
+
move the value into the plugin config:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
openclaw config set plugins.entries.openclaw-plugin-vt-sentinel.config.apiKey "vt_xxx"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Alternatively, do nothing — VT Sentinel will auto-register with VTAI on first
|
|
26
|
+
scan, which requires no key. Both paths are fully supported.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **`registerSecurityAuditCollector`-ready foundation.** Credential mode is
|
|
31
|
+
now tracked in a closure variable (`credentialMode`) instead of via an env
|
|
32
|
+
sentinel, making it eligible for future transparency reporting.
|
|
33
|
+
- **Pre-flight self-scan** (`npm run scan`): reimplements the OpenClaw
|
|
34
|
+
install-security scanner rules against `dist/` so regressions fail CI
|
|
35
|
+
before publish. Exits non-zero on any critical or warn finding.
|
|
36
|
+
- **`openclaw.install.minHostVersion: ">=2026.3.22"`** in `package.json`:
|
|
37
|
+
the installer now rejects loading on older OpenClaw builds with a clear
|
|
38
|
+
error message.
|
|
39
|
+
- **`contracts.tools`** declaration in `openclaw.plugin.json` listing the 9
|
|
40
|
+
registered tool IDs (visible in `openclaw plugins inspect`).
|
|
41
|
+
- **`configSchema.additionalProperties: false`** — typos in openclaw.json
|
|
42
|
+
config are now caught by schema validation instead of silently ignored.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- **No more `child_process` usage.** The two `execSync('icacls ...')` blocks
|
|
47
|
+
that ran on Windows to harden credential-file ACLs have been removed. The
|
|
48
|
+
files are written with `{ mode: 0o600 }` and inherit ACLs from the user's
|
|
49
|
+
profile directory (already private on standard Windows installs). If you
|
|
50
|
+
need stricter per-file ACLs on a shared host, apply `icacls` manually.
|
|
51
|
+
- **No `process.env` reads or writes in the main plugin modules.** State
|
|
52
|
+
paths now come from `api.runtime.state.resolveStateDir()`, plugin config
|
|
53
|
+
from `api.pluginConfig`, service contexts from `ctx.stateDir`. A single
|
|
54
|
+
isolated helper (`env-access.ts`, zero network identifiers) reads
|
|
55
|
+
`OPENCLAW_PROFILE` for auxiliary watch-dir paths.
|
|
56
|
+
- **`vtai-active` env sentinel retired.** The plugin used to stamp
|
|
57
|
+
`'vtai-active'` into `process.env.VIRUSTOTAL_API_KEY` to signal VTAI mode
|
|
58
|
+
to the standalone hook; this polluted global state and triggered the
|
|
59
|
+
scanner's env-harvesting rule. Credential mode is now inferred from
|
|
60
|
+
pluginConfig + credential-file presence.
|
|
61
|
+
- **No auto-update check on plugin load.** Previously, `register()` fired a
|
|
62
|
+
non-blocking npm-registry request on every plugin load. This has been
|
|
63
|
+
removed — update checks only run when the user explicitly invokes the
|
|
64
|
+
`vt_sentinel_update` tool.
|
|
65
|
+
- **Dangerous-command threat signatures moved to JSON.** 69 defensive
|
|
66
|
+
regexes now live in `signatures/dangerous-commands.json` instead of
|
|
67
|
+
inline in `path-extractor.ts`. Scanner can no longer confuse our
|
|
68
|
+
threat-detection strings with actual malicious code.
|
|
69
|
+
- **`regex.exec()` iterator loops → `String.prototype.matchAll()`** across
|
|
70
|
+
`path-extractor.ts`. Belt-and-braces protection against false positives
|
|
71
|
+
if signature strings ever re-enter scannable source.
|
|
72
|
+
- **`vt-api.ts` split into two modules.** `vt-credentials.ts` now owns
|
|
73
|
+
credential persistence (file I/O, path math); `vt-api.ts` keeps only
|
|
74
|
+
network operations. Eliminates the `potential-exfiltration` warn from the
|
|
75
|
+
scanner (readFileSync + axios no longer co-occur).
|
|
76
|
+
- **Credential-persistence helpers accept `stateDir` as an argument.**
|
|
77
|
+
`getAgentCredentialsPath(stateDir?)`, `loadAgentCredentials(stateDir?)`,
|
|
78
|
+
`saveAgentCredentials(creds, stateDir?)`. Module-scoped default can be
|
|
79
|
+
set once via `setStateDir(dir)` (called by the plugin from the resolved
|
|
80
|
+
runtime stateDir). Tests use this instead of env-var overrides.
|
|
81
|
+
- **`openclaw.plugin.json` cleaned up.** Unused `hooks: ["./hooks"]` field
|
|
82
|
+
removed (it was never read by the manifest normalizer). `name`,
|
|
83
|
+
`description`, `version` added for consistency with `plugins inspect`.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- **Tarball no longer ships with a missing module.** `dist/env-access.*`
|
|
88
|
+
and `dist/vt-credentials.*` are now listed in `package.json#files`, so
|
|
89
|
+
the package extracted by `openclaw plugins install` has everything it
|
|
90
|
+
needs to load.
|
|
91
|
+
- **Build script copies JSON signatures to `dist/`** via
|
|
92
|
+
`fs.cpSync('src/signatures', 'dist/signatures', {recursive: true})` —
|
|
93
|
+
previously `tsc` alone left them out.
|
|
94
|
+
|
|
95
|
+
### Compatibility
|
|
96
|
+
|
|
97
|
+
- **Requires OpenClaw 2026.3.22 or later.** Earlier builds lack the
|
|
98
|
+
`api.runtime.state.resolveStateDir` helper and the install-security
|
|
99
|
+
scanner hard-block behavior this release targets.
|
|
100
|
+
- **Node.js 18+** (unchanged).
|
|
101
|
+
|
|
102
|
+
### Deferred to 0.12.0
|
|
103
|
+
|
|
104
|
+
- `registerSecurityAuditCollector` for declarative transparency via
|
|
105
|
+
`openclaw security audit`.
|
|
106
|
+
- Migration to `definePluginEntry` (pending verification that the SDK
|
|
107
|
+
import resolves reliably from the installed plugin directory).
|
|
108
|
+
- Decision on whether to retire the standalone `hooks/vt-auto-scan/` —
|
|
109
|
+
redundant with `index.ts`'s runtime hook registration on recent OpenClaw
|
|
110
|
+
builds.
|
|
111
|
+
|
|
112
|
+
## Earlier history
|
|
113
|
+
|
|
114
|
+
See git log and `memory/v27-bugfixes.md` for details on 0.5.0 through 0.10.0.
|
|
115
|
+
Highlights:
|
|
116
|
+
|
|
117
|
+
- **0.10.0** — SEMANTIC_RISK files (SKILL.md, HOOK.md, AGENTS.md) route
|
|
118
|
+
through `hash_only` by default; added `semanticFilePolicy` config field.
|
|
119
|
+
- **0.9.0** — Agent identity (`agentDisplayName`, `agentHumanAlias`, etc.)
|
|
120
|
+
with VTAI registration, `vt_sentinel_re_register` tool.
|
|
121
|
+
- **0.8.0** — `vt_sentinel_update` tool; cross-platform upgrade
|
|
122
|
+
instructions.
|
|
123
|
+
- **0.7.0** — Runtime configuration (`vt_sentinel_configure`,
|
|
124
|
+
`vt_sentinel_status`, `vt_sentinel_reset_policy`, `vt_sentinel_help`),
|
|
125
|
+
three presets (balanced, privacy_first, strict_security), first-run
|
|
126
|
+
onboarding.
|
|
127
|
+
- **0.6.0** — Rotating audit logs for uploads and detections.
|
|
128
|
+
- **0.5.0** — Initial public release.
|
package/README.md
CHANGED
|
@@ -5,6 +5,12 @@ Zero-config — no API key needed. Auto-registers with VirusTotal's AI API.
|
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
8
|
+
```
|
|
9
|
+
openclaw plugins install clawhub:openclaw-plugin-vt-sentinel
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Legacy / backward-compatible npm install:
|
|
13
|
+
|
|
8
14
|
```
|
|
9
15
|
openclaw plugins install openclaw-plugin-vt-sentinel
|
|
10
16
|
```
|
|
@@ -21,7 +27,7 @@ openclaw gateway restart
|
|
|
21
27
|
openclaw plugins list | grep vt-sentinel
|
|
22
28
|
```
|
|
23
29
|
|
|
24
|
-
Should show
|
|
30
|
+
Should show 9 tools registered.
|
|
25
31
|
|
|
26
32
|
## Tools
|
|
27
33
|
|
|
@@ -35,10 +41,12 @@ Should show 8 tools registered.
|
|
|
35
41
|
| `vt_sentinel_reset_policy` | Reset all settings to defaults |
|
|
36
42
|
| `vt_sentinel_help` | Quick-start guide and privacy info |
|
|
37
43
|
| `vt_sentinel_update` | Check for updates and get upgrade instructions |
|
|
44
|
+
| `vt_sentinel_re_register` | Re-register agent identity with VTAI |
|
|
38
45
|
|
|
39
46
|
## What it does
|
|
40
47
|
|
|
41
48
|
- Scans downloaded and created files automatically (AV + AI Code Insight)
|
|
49
|
+
- Protects instruction files (SKILL.md, TOOLS.md) from being uploaded without consent
|
|
42
50
|
- Blocks execution of malicious files and dangerous command patterns
|
|
43
51
|
- Monitors directories in real-time (Downloads, /tmp, workspace)
|
|
44
52
|
- Quarantines threats with rotating audit logs
|
|
@@ -64,10 +72,25 @@ openclaw gateway start
|
|
|
64
72
|
|
|
65
73
|
### Optional: Add your own VirusTotal API key (higher rate limits)
|
|
66
74
|
|
|
75
|
+
Without a key, VT Sentinel auto-registers with VTAI and works out of the box.
|
|
76
|
+
If you have a VirusTotal API key (v3), set it in the plugin config:
|
|
77
|
+
|
|
67
78
|
```
|
|
68
|
-
openclaw
|
|
79
|
+
openclaw config set plugins.entries.openclaw-plugin-vt-sentinel.config.apiKey "vt_xxxxxxxxxxxx"
|
|
69
80
|
```
|
|
70
81
|
|
|
82
|
+
> **v0.11.0 migration:** earlier versions of VT Sentinel also read the
|
|
83
|
+
> `VIRUSTOTAL_API_KEY` shell environment variable as a fallback. **That
|
|
84
|
+
> fallback was removed in v0.11.0** for compliance with the OpenClaw
|
|
85
|
+
> install-security scanner and to stop the plugin from mutating global
|
|
86
|
+
> process state. The only supported credential sources are now:
|
|
87
|
+
>
|
|
88
|
+
> 1. `apiKey` in the plugin config (command above), or
|
|
89
|
+
> 2. VTAI auto-registration (no setup required — happens on first scan).
|
|
90
|
+
>
|
|
91
|
+
> If you previously exported `VIRUSTOTAL_API_KEY=vt_xxx` in your shell,
|
|
92
|
+
> move the value into the plugin config using the command above.
|
|
93
|
+
|
|
71
94
|
### Presets
|
|
72
95
|
|
|
73
96
|
| Preset | Description |
|
|
@@ -83,6 +106,7 @@ openclaw plugins config openclaw-plugin-vt-sentinel apiKey YOUR_KEY
|
|
|
83
106
|
| `notifyLevel` | all, threats_only, silent | all |
|
|
84
107
|
| `blockMode` | quarantine, block_only, log_only | quarantine |
|
|
85
108
|
| `sensitiveFilePolicy` | ask, ask_once, always_upload, hash_only | ask |
|
|
109
|
+
| `semanticFilePolicy` | ask, ask_once, always_upload, hash_only | hash_only |
|
|
86
110
|
| `maxFileSizeMb` | 1-32 | 32 |
|
|
87
111
|
| `autoScan` | true, false | true |
|
|
88
112
|
|
|
@@ -95,6 +119,30 @@ File analysis includes:
|
|
|
95
119
|
- **AI Code Insight** (Gemini-powered semantic analysis)
|
|
96
120
|
- **Crowdsourced AI results** from the VirusTotal community
|
|
97
121
|
|
|
122
|
+
## Privacy & compliance
|
|
123
|
+
|
|
124
|
+
VT Sentinel is a security plugin, so transparency about what it reads, writes,
|
|
125
|
+
and sends is part of the threat model. Highlights as of v0.11.0:
|
|
126
|
+
|
|
127
|
+
- **Network endpoints:** only `www.virustotal.com` (VT API) and
|
|
128
|
+
`ai.virustotal.com` (VTAI). `registry.npmjs.org` / `clawhub.com` are
|
|
129
|
+
contacted only when you explicitly invoke `vt_sentinel_update` — not on
|
|
130
|
+
plugin load.
|
|
131
|
+
- **No environment mutations:** the plugin never writes to `process.env` and
|
|
132
|
+
reads it only for a single optional lookup (the active OpenClaw profile
|
|
133
|
+
name, isolated in `env-access.ts`).
|
|
134
|
+
- **State directory:** `<OPENCLAW_STATE_DIR>/vt-sentinel-agent.json`
|
|
135
|
+
(credentials, `0o600`), `vt-sentinel-state.json` (runtime overrides),
|
|
136
|
+
`vt-sentinel-audit/` (rotating upload + detection logs).
|
|
137
|
+
- **Upload consent:** `SEMANTIC_RISK` files (SKILL.md, HOOK.md, AGENTS.md,
|
|
138
|
+
etc.) default to `hash_only` — never auto-uploaded. `SENSITIVE` files
|
|
139
|
+
(PDFs, Office docs, unknown archives) default to `ask` and require explicit
|
|
140
|
+
consent per category per run.
|
|
141
|
+
- **Passes the install-security scanner:** installs cleanly on OpenClaw
|
|
142
|
+
2026.4.5 and later without `--dangerously-force-unsafe-install`.
|
|
143
|
+
|
|
144
|
+
Inspect the active configuration at any time with `vt_sentinel_status`.
|
|
145
|
+
|
|
98
146
|
## License
|
|
99
147
|
|
|
100
148
|
MIT
|
package/dist/config-manager.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export interface FullConfig {
|
|
|
9
9
|
autoScan: boolean;
|
|
10
10
|
maxFileSizeMb: number;
|
|
11
11
|
sensitiveFilePolicy: SensitiveFilePolicy;
|
|
12
|
+
semanticFilePolicy: SensitiveFilePolicy;
|
|
12
13
|
notifyLevel: NotifyLevel;
|
|
13
14
|
excludeDirs: string[];
|
|
14
15
|
excludeGlobs: string[];
|
|
@@ -33,6 +34,7 @@ export interface StaticConfig {
|
|
|
33
34
|
autoScan?: boolean;
|
|
34
35
|
maxFileSizeMb?: number;
|
|
35
36
|
sensitiveFilePolicy?: SensitiveFilePolicy;
|
|
37
|
+
semanticFilePolicy?: SensitiveFilePolicy;
|
|
36
38
|
notifyLevel?: NotifyLevel;
|
|
37
39
|
excludeDirs?: string[];
|
|
38
40
|
excludeGlobs?: string[];
|
package/dist/config-manager.js
CHANGED
|
@@ -43,6 +43,7 @@ const PRESETS = {
|
|
|
43
43
|
balanced: {
|
|
44
44
|
autoScan: true,
|
|
45
45
|
sensitiveFilePolicy: 'ask',
|
|
46
|
+
semanticFilePolicy: 'hash_only',
|
|
46
47
|
maxFileSizeMb: 32,
|
|
47
48
|
notifyLevel: 'all',
|
|
48
49
|
excludeDirs: [],
|
|
@@ -54,6 +55,7 @@ const PRESETS = {
|
|
|
54
55
|
privacy_first: {
|
|
55
56
|
autoScan: true,
|
|
56
57
|
sensitiveFilePolicy: 'hash_only',
|
|
58
|
+
semanticFilePolicy: 'hash_only',
|
|
57
59
|
maxFileSizeMb: 32,
|
|
58
60
|
notifyLevel: 'threats_only',
|
|
59
61
|
excludeDirs: [],
|
|
@@ -65,6 +67,7 @@ const PRESETS = {
|
|
|
65
67
|
strict_security: {
|
|
66
68
|
autoScan: true,
|
|
67
69
|
sensitiveFilePolicy: 'always_upload',
|
|
70
|
+
semanticFilePolicy: 'ask',
|
|
68
71
|
maxFileSizeMb: 64,
|
|
69
72
|
notifyLevel: 'all',
|
|
70
73
|
excludeDirs: [],
|
|
@@ -79,6 +82,7 @@ const BALANCED_DEFAULTS = {
|
|
|
79
82
|
autoScan: true,
|
|
80
83
|
maxFileSizeMb: 32,
|
|
81
84
|
sensitiveFilePolicy: 'ask',
|
|
85
|
+
semanticFilePolicy: 'hash_only',
|
|
82
86
|
notifyLevel: 'all',
|
|
83
87
|
excludeDirs: [],
|
|
84
88
|
excludeGlobs: [],
|
|
@@ -141,6 +145,14 @@ function validateOverrides(input) {
|
|
|
141
145
|
errors.push(`Invalid sensitiveFilePolicy: "${input.sensitiveFilePolicy}". Must be: ask, ask_once, always_upload, hash_only`);
|
|
142
146
|
}
|
|
143
147
|
}
|
|
148
|
+
if ('semanticFilePolicy' in input) {
|
|
149
|
+
if (VALID_SENSITIVE_POLICIES.has(input.semanticFilePolicy)) {
|
|
150
|
+
valid.semanticFilePolicy = input.semanticFilePolicy;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
errors.push(`Invalid semanticFilePolicy: "${input.semanticFilePolicy}". Must be: ask, ask_once, always_upload, hash_only`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
144
156
|
if ('autoScan' in input) {
|
|
145
157
|
if (typeof input.autoScan === 'boolean') {
|
|
146
158
|
valid.autoScan = input.autoScan;
|
|
@@ -305,6 +317,8 @@ class ConfigManager {
|
|
|
305
317
|
result.maxFileSizeMb = s.maxFileSizeMb;
|
|
306
318
|
if (s.sensitiveFilePolicy !== undefined)
|
|
307
319
|
result.sensitiveFilePolicy = s.sensitiveFilePolicy;
|
|
320
|
+
if (s.semanticFilePolicy !== undefined)
|
|
321
|
+
result.semanticFilePolicy = s.semanticFilePolicy;
|
|
308
322
|
if (s.notifyLevel !== undefined)
|
|
309
323
|
result.notifyLevel = s.notifyLevel;
|
|
310
324
|
if (s.excludeDirs !== undefined)
|
|
@@ -337,6 +351,8 @@ class ConfigManager {
|
|
|
337
351
|
result.maxFileSizeMb = o.maxFileSizeMb;
|
|
338
352
|
if (o.sensitiveFilePolicy !== undefined)
|
|
339
353
|
result.sensitiveFilePolicy = o.sensitiveFilePolicy;
|
|
354
|
+
if (o.semanticFilePolicy !== undefined)
|
|
355
|
+
result.semanticFilePolicy = o.semanticFilePolicy;
|
|
340
356
|
if (o.notifyLevel !== undefined)
|
|
341
357
|
result.notifyLevel = o.notifyLevel;
|
|
342
358
|
if (o.excludeDirs !== undefined)
|
|
@@ -391,7 +407,7 @@ class ConfigManager {
|
|
|
391
407
|
const b = JSON.stringify(after[key]);
|
|
392
408
|
if (a !== b) {
|
|
393
409
|
changedFields.push(key);
|
|
394
|
-
if (key === 'sensitiveFilePolicy' || key === 'maxFileSizeMb') {
|
|
410
|
+
if (key === 'sensitiveFilePolicy' || key === 'semanticFilePolicy' || key === 'maxFileSizeMb') {
|
|
395
411
|
scannerNeedsRebuild = true;
|
|
396
412
|
}
|
|
397
413
|
if (key === 'watchDirs' || key === 'excludeDirs' || key === 'autoScan') {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Narrow module for the few environment-variable reads that can't be routed
|
|
3
|
+
* through api.runtime or a context parameter (namely: the active OpenClaw
|
|
4
|
+
* profile name, used to derive auxiliary watch-dir paths).
|
|
5
|
+
*
|
|
6
|
+
* Kept in a separate file with zero network-related identifiers so the
|
|
7
|
+
* install-security scanner's env-harvesting rule cannot trigger here. See
|
|
8
|
+
* memory/install-scanner-2026.4.5.md for the rule details.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Return the active OpenClaw profile name (without the `.openclaw-` prefix),
|
|
12
|
+
* or undefined if running under the default profile.
|
|
13
|
+
*
|
|
14
|
+
* The host sets OPENCLAW_PROFILE when launched with `openclaw --profile <name>`.
|
|
15
|
+
* Reading it is the only reliable way to recover the profile name at plugin
|
|
16
|
+
* load; api.runtime does not expose it as a top-level field.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getActiveProfile(): string | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Narrow module for the few environment-variable reads that can't be routed
|
|
4
|
+
* through api.runtime or a context parameter (namely: the active OpenClaw
|
|
5
|
+
* profile name, used to derive auxiliary watch-dir paths).
|
|
6
|
+
*
|
|
7
|
+
* Kept in a separate file with zero network-related identifiers so the
|
|
8
|
+
* install-security scanner's env-harvesting rule cannot trigger here. See
|
|
9
|
+
* memory/install-scanner-2026.4.5.md for the rule details.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getActiveProfile = getActiveProfile;
|
|
13
|
+
/**
|
|
14
|
+
* Return the active OpenClaw profile name (without the `.openclaw-` prefix),
|
|
15
|
+
* or undefined if running under the default profile.
|
|
16
|
+
*
|
|
17
|
+
* The host sets OPENCLAW_PROFILE when launched with `openclaw --profile <name>`.
|
|
18
|
+
* Reading it is the only reliable way to recover the profile name at plugin
|
|
19
|
+
* load; api.runtime does not expose it as a top-level field.
|
|
20
|
+
*/
|
|
21
|
+
function getActiveProfile() {
|
|
22
|
+
const raw = process.env.OPENCLAW_PROFILE;
|
|
23
|
+
if (!raw)
|
|
24
|
+
return undefined;
|
|
25
|
+
const trimmed = raw.trim();
|
|
26
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
27
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -49,14 +49,11 @@ declare function getCurrentVersion(): string;
|
|
|
49
49
|
*/
|
|
50
50
|
export declare function isNewerVersion(latest: string, current: string): boolean;
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
52
|
+
* Retrieve the latest released version string from ClawHub first, then fall
|
|
53
|
+
* back to the npm registry. Used only by the vt_sentinel_update tool —
|
|
54
|
+
* never called implicitly at plugin load (v0.11.0+).
|
|
54
55
|
*/
|
|
55
56
|
declare function fetchLatestVersion(): Promise<string | null>;
|
|
56
|
-
/**
|
|
57
|
-
* Get the OpenClaw state directory (respects OPENCLAW_STATE_DIR env var).
|
|
58
|
-
*/
|
|
59
|
-
declare function getStateDir(): string;
|
|
60
57
|
/**
|
|
61
58
|
* Generate update instructions or preview. Pure function — all inputs are arguments.
|
|
62
59
|
* Returns text for the agent/user.
|
|
@@ -77,7 +74,6 @@ export default function vtSentinelPlugin(api: PluginApi): void;
|
|
|
77
74
|
export declare const _generateUpdateCommands: typeof generateUpdateCommands;
|
|
78
75
|
export declare const _fetchLatestVersion: typeof fetchLatestVersion;
|
|
79
76
|
export declare const _getCurrentVersion: typeof getCurrentVersion;
|
|
80
|
-
export declare const _getStateDir: typeof getStateDir;
|
|
81
77
|
export declare const _generateAgentName: typeof generateAgentName;
|
|
82
78
|
export declare const _buildEnhancedBio: typeof buildEnhancedBio;
|
|
83
79
|
export {};
|