clawdi 0.14.50 → 0.14.52
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
|
@@ -1113,7 +1113,7 @@ const managedSocketMetadata = (creds) => {
|
|
|
1113
1113
|
`:`
|
|
1114
1114
|
|
|
1115
1115
|
`;a=`${n}${l}${t}
|
|
1116
|
-
`}return{existing:n,next:a}}function Eae(e,t){let{existing:n,next:r}=S$(e,t);if(r===n)return e;return le(e,r,{mode:384,dirMode:448}),e}function W3e(e,t){gn(e,"dashboard.basic_auth",{username:t.username,session_ttl_seconds:t.sessionTtlSeconds}),gn(e,"dashboard.public_url",t.publicUrl);let n=ol(e,"plugins.disabled");if(n.exists&&(!Array.isArray(n.value)||n.value.some((i)=>typeof i!=="string")))throw Error("Hermes config field plugins.disabled must be a string array");let r=new Set((n.exists?n.value:[]).filter((i)=>i!=="dashboard_auth/basic"));r.add("dashboard_auth/nous"),r.add("dashboard_auth/self_hosted"),gn(e,"plugins.disabled",[...r].sort())}function $ae(e,t,n,r,i,o){if(t.runtimes[e]?.enabled!==!0)return null;let s=t.locale;if(e==="openclaw"){if(!r)throw Error("OpenClaw official agent workspace is unavailable");return s?Eae(L2(r,"SOUL.md"),Af(s)):null}if(e==="hermes"){if(!o)throw Error("Hermes config command is unavailable");let a=t.hermesDashboardAuth,l=L2(n,".hermes");if(gn(o,"terminal.cwd",i),a)W3e(o,a);if(s)gn(o,"timezone",s.timezone);return s?Eae(L2(l,"SOUL.md"),Af(s)):null}return null}function xae(e,t,n,r,i){let o=hz(t,r,i,n);return t==="hermes"&&n==="dashboard"?G3e(e,o)??o:o}function k$(e,t,n){return hz(e,t,n)}function Pw(e,t,n,r){let i=`runtime ${e}${r?` service ${r}`:""}`,o={...n},s=t?.secretEnv??{};for(let[a,l]of Object.entries(s)){let c=o[a];if(c!==void 0&&c!==l)throw Error(`${i} secretEnv.${a} conflicts with provider secret ref ${c}`);o[a]=l}for(let a of Object.keys(t?.env??{}))if(o[a]!==void 0)throw Error(`${i} defines ${a} in both env and secretEnv`);return o}function G3e(e,t){let n=e.hermesDashboardAuth;if(!n)return t;if(!n.activation.enabled)throw Error("Hermes password authentication is disabled");return{...t??{},prependPath:t?.prependPath??[],env:t?.env??{},secretEnv:{...t?.secretEnv??{},HERMES_DASHBOARD_BASIC_AUTH_PASSWORD:n.passwordSecretRef,HERMES_DASHBOARD_BASIC_AUTH_SECRET:n.sessionSecretRef}}}var b$="<!-- >>> clawdi managed locale >>>",Aw="<!-- <<< clawdi managed locale <<< -->";var R$=_(()=>{ht();sl();jm()});import{createHash as K3e}from"node:crypto";import{chmodSync as U2,chownSync as Z3e,existsSync as Ql,lstatSync as Iae,mkdirSync as Oae,readdirSync as A$,readFileSync as Ew,rmdirSync as Tae,rmSync as z2}from"node:fs";import{dirname as Cs,isAbsolute as J3e,join as Sr}from"node:path";function Y3e(e,t,n,r,i){if(!t)return null;if(r?.status!=="ready")return null;if(!i)return null;return{profileBundlePath:t,envFilePath:e.egressTransparentEnv,transparentPort:Qq,addonPath:i.path,addonSha256:i.sha256,engine:r,systemCaBundle:e.egressSystemCaFile,secretFilePath:n}}function Dae(e){let t=Y3e(e.paths,e.profileBundlePath,e.secretFilePath,e.engine,e.addon);if(!t)return{egressProgram:null,identity:null};return{egressProgram:t,identity:{runtimeUid:e.runtimeIdentity.uid,runtimeGid:e.runtimeIdentity.gid,egressUid:Bb(),egressGid:xc()}}}function F2(e){if(!e.config.enabled)return null;let t=nv(Nae(e.paths),Cs(e.paths.cliManagedBin)),n=e.config.prependPath.join(":"),r={...e.config.env,PATH:n?[n,t].filter(Boolean).join(":"):t},i={};for(let[s,a]of Object.entries(e.config.secretEnv)){let l=zt(e.secretValues??{},a);if(!l)throw Error(`Runtime secret ${a} for ${s} is unavailable.`);r[s]=l,i[s]=l}if(e.egress)Wa(r,{caFile:e.egress.systemCaBundle});let o=e.config.commandPath&&Ql(e.config.commandPath)?e.config.commandPath:e.config.command;return{programKind:"runtime",runtime:e.config.runtime,service:e.config.service,command:o,args:e.config.defaultArgs,cwd:e.config.cwd??e.paths.workspaceRoot,env:r,resolvedSecretEnv:i}}function Wi(e){if(e.programKind==="file-browser")return"clawdi-files";let t=jae(e);if(t)return t;if(!e.service)return`clawdi-${P$(e.runtime)}`;return Q3e(e.runtime,e.service)}function jae(e){return $w(e)?.programName??null}function X3e(e,t,n,r={},i){if(t.programKind==="file-browser")return $t({companion:e.companions?.filebrowser??null,providerProjectionRevision:null});if(t.service)return NX(t);return i(e,t.runtime,n,r[t.runtime]??null)}function Q3e(e,t){let n=x$.find((r)=>r.runtime===e&&r.service===t);if(n)return n.programName;if(e==="hermes"&&t==="dashboard")return"clawdi-hermes-dashboard";return`clawdi-${P$(e)}-${P$(t)}`}function P$(e){return e.replace(/[^A-Za-z0-9_-]+/g,"-")}function Nae(e){
|
|
1116
|
+
`}return{existing:n,next:a}}function Eae(e,t){let{existing:n,next:r}=S$(e,t);if(r===n)return e;return le(e,r,{mode:384,dirMode:448}),e}function W3e(e,t){gn(e,"dashboard.basic_auth",{username:t.username,session_ttl_seconds:t.sessionTtlSeconds}),gn(e,"dashboard.public_url",t.publicUrl);let n=ol(e,"plugins.disabled");if(n.exists&&(!Array.isArray(n.value)||n.value.some((i)=>typeof i!=="string")))throw Error("Hermes config field plugins.disabled must be a string array");let r=new Set((n.exists?n.value:[]).filter((i)=>i!=="dashboard_auth/basic"));r.add("dashboard_auth/nous"),r.add("dashboard_auth/self_hosted"),gn(e,"plugins.disabled",[...r].sort())}function $ae(e,t,n,r,i,o){if(t.runtimes[e]?.enabled!==!0)return null;let s=t.locale;if(e==="openclaw"){if(!r)throw Error("OpenClaw official agent workspace is unavailable");return s?Eae(L2(r,"SOUL.md"),Af(s)):null}if(e==="hermes"){if(!o)throw Error("Hermes config command is unavailable");let a=t.hermesDashboardAuth,l=L2(n,".hermes");if(gn(o,"terminal.cwd",i),a)W3e(o,a);if(s)gn(o,"timezone",s.timezone);return s?Eae(L2(l,"SOUL.md"),Af(s)):null}return null}function xae(e,t,n,r,i){let o=hz(t,r,i,n);return t==="hermes"&&n==="dashboard"?G3e(e,o)??o:o}function k$(e,t,n){return hz(e,t,n)}function Pw(e,t,n,r){let i=`runtime ${e}${r?` service ${r}`:""}`,o={...n},s=t?.secretEnv??{};for(let[a,l]of Object.entries(s)){let c=o[a];if(c!==void 0&&c!==l)throw Error(`${i} secretEnv.${a} conflicts with provider secret ref ${c}`);o[a]=l}for(let a of Object.keys(t?.env??{}))if(o[a]!==void 0)throw Error(`${i} defines ${a} in both env and secretEnv`);return o}function G3e(e,t){let n=e.hermesDashboardAuth;if(!n)return t;if(!n.activation.enabled)throw Error("Hermes password authentication is disabled");return{...t??{},prependPath:t?.prependPath??[],env:t?.env??{},secretEnv:{...t?.secretEnv??{},HERMES_DASHBOARD_BASIC_AUTH_PASSWORD:n.passwordSecretRef,HERMES_DASHBOARD_BASIC_AUTH_SECRET:n.sessionSecretRef}}}var b$="<!-- >>> clawdi managed locale >>>",Aw="<!-- <<< clawdi managed locale <<< -->";var R$=_(()=>{ht();sl();jm()});import{createHash as K3e}from"node:crypto";import{chmodSync as U2,chownSync as Z3e,existsSync as Ql,lstatSync as Iae,mkdirSync as Oae,readdirSync as A$,readFileSync as Ew,rmdirSync as Tae,rmSync as z2}from"node:fs";import{dirname as Cs,isAbsolute as J3e,join as Sr}from"node:path";function Y3e(e,t,n,r,i){if(!t)return null;if(r?.status!=="ready")return null;if(!i)return null;return{profileBundlePath:t,envFilePath:e.egressTransparentEnv,transparentPort:Qq,addonPath:i.path,addonSha256:i.sha256,engine:r,systemCaBundle:e.egressSystemCaFile,secretFilePath:n}}function Dae(e){let t=Y3e(e.paths,e.profileBundlePath,e.secretFilePath,e.engine,e.addon);if(!t)return{egressProgram:null,identity:null};return{egressProgram:t,identity:{runtimeUid:e.runtimeIdentity.uid,runtimeGid:e.runtimeIdentity.gid,egressUid:Bb(),egressGid:xc()}}}function F2(e){if(!e.config.enabled)return null;let t=nv(Nae(e.paths),Cs(e.paths.cliManagedBin)),n=e.config.prependPath.join(":"),r={...e.config.env,PATH:n?[n,t].filter(Boolean).join(":"):t},i={};for(let[s,a]of Object.entries(e.config.secretEnv)){let l=zt(e.secretValues??{},a);if(!l)throw Error(`Runtime secret ${a} for ${s} is unavailable.`);r[s]=l,i[s]=l}if(e.egress)Wa(r,{caFile:e.egress.systemCaBundle});let o=e.config.commandPath&&Ql(e.config.commandPath)?e.config.commandPath:e.config.command;return{programKind:"runtime",runtime:e.config.runtime,service:e.config.service,command:o,args:e.config.defaultArgs,cwd:e.config.cwd??e.paths.workspaceRoot,env:r,resolvedSecretEnv:i}}function Wi(e){if(e.programKind==="file-browser")return"clawdi-files";let t=jae(e);if(t)return t;if(!e.service)return`clawdi-${P$(e.runtime)}`;return Q3e(e.runtime,e.service)}function jae(e){return $w(e)?.programName??null}function X3e(e,t,n,r={},i){if(t.programKind==="file-browser")return $t({companion:e.companions?.filebrowser??null,providerProjectionRevision:null});if(t.service)return NX(t);return i(e,t.runtime,n,r[t.runtime]??null)}function Q3e(e,t){let n=x$.find((r)=>r.runtime===e&&r.service===t);if(n)return n.programName;if(e==="hermes"&&t==="dashboard")return"clawdi-hermes-dashboard";return`clawdi-${P$(e)}-${P$(t)}`}function P$(e){return e.replace(/[^A-Za-z0-9_-]+/g,"-")}function Nae(e){let t=process.env.PATH||"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";return[...new Set([e.userLocalBin,Sr(e.userHome,".openclaw","bin"),...t.split(":")])].join(":")}function Is(e){return`${P$(e)}.service`}function Cae(e){return Is(Wi(e))}function Mae(e,t){return Sr(e.systemdUserRoot,`${Is(t)}.d`,AP)}function Lae(e){if(/[\r\n]/.test(e))throw Error("systemd unit values must be single-line strings");return`"${e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/%/g,"%%").replace(/\$/g,"$$")}"`}function $$(e,t){return[e,...t].map(Lae).join(" ")}function e8e(e,t){return $$(e,["-c",t])}function t8e(e,t,n){return $$("/bin/sh",["-c",'output=$("$1" version 2>&1) || exit $?; case "$output" in *"$2"*) ;; *) exit 65 ;; esac; case "$output" in *"$3"*) ;; *) exit 65 ;; esac',"sh",e,t,n.slice(0,7)])}function ir(e){if(!J3e(e))throw Error(`systemd unit paths must be absolute: ${e}`);if(/[\r\n]/.test(e))throw Error("systemd unit paths must be single-line strings");return e.replace(/\\/g,"\\\\").replace(/%/g,"%%").replace(/ /g,"\\x20").replace(/\t/g,"\\x09")}function n8e(e){return Object.entries(e).map(([t,n])=>`Environment=${Lae(`${t}=${n}`)}`)}function r8e(e,t){return Sr(e.systemdEnvRoot,`${Is(t)}.env`)}function Uae(e){if(/[\r\n]/.test(e))throw Error("systemd environment files only support single-line values");return`"${e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function $w(e){return x$.find((t)=>t.runtime===e.runtime&&t.matchesProgram(e))??null}function i8e(e){return x$.find((t)=>Is(t.programName)===e)??null}function H2(e,t){let n=fa(e.runtime,t.userHome);return n&&Wt(n)?n:e.command}function zae(e,t){let n=$w(e);if(!n)return null;let r=Is(n.programName),i=Sr(t.systemdUserRoot,r),o;try{if(!Iae(i).isFile())throw Error(`official ${r} unit is not a regular file`);o=Ew(i)}catch(l){if(l instanceof Error&&"code"in l&&l.code==="ENOENT")return null;throw l}if(RP(o.toString("utf8")))return null;let s=H2(n,t),a=n.runtime==="hermes"?Zt(s):Sv(s,t.userHome,t.userHome);if(!a)throw Error(`official ${r} command revision is unavailable; refusing service reinstall`);return K3e("sha256").update(a).update("\x00").update(o).digest("hex")}function Fae(e,t,n){let r=[],i={};if(!n)return{pending:r,serviceRevisions:i};for(let o of _8e(e)){let s=Is(Wi(o)),a=zae(o,t);if(a)i[s]=a;if(!a)r.push({unitName:s,program:o,serviceRevision:a})}return{pending:r,serviceRevisions:i}}function u8e(e){Pi(e.paths.runRoot,e.paths.systemdRuntimeRoot,{mode:457}),U2(e.paths.systemdRuntimeRoot,457),Pi(e.paths.runRoot,e.paths.systemdEnvRoot,{mode:457}),U2(e.paths.systemdEnvRoot,457);let t=r8e(e.paths,e.name),n=Object.entries(e.env).sort(([i],[o])=>i.localeCompare(o)).map(([i,o])=>{if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))throw Error(`invalid systemd environment key: ${i}`);return`${i}=${Uae(o)}`}),r=`${kP}
|
|
1117
1117
|
${n.join(`
|
|
1118
1118
|
`)}
|
|
1119
1119
|
`;return B2({path:t,content:r,mode:384,dirMode:457,trustedRoot:e.paths.runRoot,owner:e.owner}),t}function B2(e){let t=!1;try{let n=Iae(e.path);t=n.isFile()&&n.nlink===1&&Ew(e.path,"utf8")===e.content}catch{}if(t)U2(e.path,e.mode);else le(e.path,e.content,{mode:e.mode,dirMode:e.dirMode,trustedRoot:e.trustedRoot});if(e.owner==="runtime-user")qg(e.path);else if(Pn())Z3e(e.path,0,0)}function Hae(e){return u8e(e)}function C$(e){return En(e)}function Bae(e){let t=Sr(e.root,Is(e.name)),n=Hae({paths:e.paths,name:e.name,owner:e.owner,env:e.env}),r=[kP,"[Unit]",`Description=${e.description}`,...e.owner==="runtime-user"?["# The environment file is regenerated by convergence each boot; this unit must not start before it exists.",`ConditionPathExists=${ir(n)}`]:[],...e.extraUnitLines??[],"","[Service]",`Type=${e.serviceType??"simple"}`,`WorkingDirectory=${ir(e.cwd)}`,...e.directoryKind==="platform"?[`ConfigurationDirectory=${Wb}`,"ConfigurationDirectoryMode=0700",`StateDirectory=${Wb}`,"StateDirectoryMode=0700",`CacheDirectory=${Wb}`,"CacheDirectoryMode=0700"]:e.directoryKind==="file-browser"?[`StateDirectory=${c0}`,"StateDirectoryMode=0700",`RuntimeDirectory=${c0}`,"RuntimeDirectoryMode=0700"]:[],...e.unitEnv?n8e(e.unitEnv):[],...e.unsetEnvironment?.length?[`UnsetEnvironment=${e.unsetEnvironment.join(" ")}`]:[],...e.extraServiceLines??[],`EnvironmentFile=${ir(n)}`,`ExecStart=${e.execStart??$$(e.command,e.args)}`,...e.restart===!1?[]:["Restart=always","RestartSec=2","KillMode=mixed","TimeoutStopSec=30"],"","[Install]",`WantedBy=${e.wantedBy}`,""],i=()=>{if(e.owner==="runtime-user")Oae(e.root,{recursive:!0});return Pi(e.root,e.root),B2({path:t,content:r.join(`
|
|
Binary file
|
|
@@ -13,7 +13,7 @@ import re
|
|
|
13
13
|
from datetime import UTC, datetime
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from typing import Any
|
|
16
|
-
from urllib.parse import parse_qs, urlsplit
|
|
16
|
+
from urllib.parse import parse_qs, quote, urlsplit
|
|
17
17
|
|
|
18
18
|
try: # pragma: no cover - exercised only under mitmdump.
|
|
19
19
|
from mitmproxy import ctx, http
|
|
@@ -408,13 +408,26 @@ def path_matcher_matches(path: str, matcher: dict[str, Any], secrets: dict[str,
|
|
|
408
408
|
secret = secrets.get(str(matcher.get("secretRef", "")))
|
|
409
409
|
if secret is None:
|
|
410
410
|
return False
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
411
|
+
matched = match_secret_path_prefix(path, matcher, secret)
|
|
412
|
+
return matched is not None and (
|
|
413
|
+
matcher_type == "secretRefPrefix" or matched.end() == len(path)
|
|
414
|
+
)
|
|
415
415
|
return False
|
|
416
416
|
|
|
417
417
|
|
|
418
|
+
def match_secret_path_prefix(
|
|
419
|
+
path: str, matcher: dict[str, Any], secret: str
|
|
420
|
+
) -> re.Match[str] | None:
|
|
421
|
+
# Encode only credential characters, never path structure or incoming escapes.
|
|
422
|
+
parts = [re.escape(str(matcher.get("prefix", "")))]
|
|
423
|
+
for char in secret:
|
|
424
|
+
encoded = quote(char, safe="/\\")
|
|
425
|
+
literal = re.escape(char)
|
|
426
|
+
parts.append(literal if encoded == char else f"(?:(?i:{encoded})|{literal})")
|
|
427
|
+
parts.append(re.escape(str(matcher.get("suffix", ""))))
|
|
428
|
+
return re.match("".join(parts), path)
|
|
429
|
+
|
|
430
|
+
|
|
418
431
|
def matcher_matches(value: str | None, matcher: Any, secrets: dict[str, str]) -> bool:
|
|
419
432
|
if not isinstance(matcher, dict):
|
|
420
433
|
return False
|
|
@@ -523,10 +536,12 @@ def apply_path_replace(request_path: str, rewrite: dict[str, Any], secrets: dict
|
|
|
523
536
|
split = urlsplit(request_path or "/")
|
|
524
537
|
prefix = str(replacement.get("prefix", ""))
|
|
525
538
|
suffix = str(replacement.get("suffix", ""))
|
|
526
|
-
|
|
527
|
-
if
|
|
539
|
+
matched = match_secret_path_prefix(split.path, replacement, placeholder)
|
|
540
|
+
if matched is None:
|
|
528
541
|
return request_path
|
|
529
|
-
|
|
542
|
+
# Keep path characters, but encode data that could start a query or fragment.
|
|
543
|
+
actual = quote(actual, safe="/:@!$&'()*+,;=")
|
|
544
|
+
replaced_path = f"{prefix}{actual}{suffix}{split.path[matched.end():]}"
|
|
530
545
|
return f"{replaced_path}?{split.query}" if split.query else replaced_path
|
|
531
546
|
|
|
532
547
|
|
package/package.json
CHANGED