@excitedjs/dreamux 0.26.0-beta.242 → 0.26.0-beta.243
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/channel/conversation-projection.js +17 -138
- package/dist/channel/conversation-projection.js.map +1 -1
- package/dist/config/config-helpers.js +7 -20
- package/dist/config/config-helpers.js.map +1 -1
- package/dist/platform/logger.js +2 -2
- package/dist/platform/logger.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,33 +1,5 @@
|
|
|
1
|
+
import { redactJson, redactText } from '@excitedjs/dreamux-utils';
|
|
1
2
|
import { errorInfo } from '../platform/error-info.js';
|
|
2
|
-
/**
|
|
3
|
-
* `key: value` / `key=value` pairs whose key names a secret. The value is one
|
|
4
|
-
* quoted string (a JSON string with its escapes, or a shell-style single- or
|
|
5
|
-
* back-quoted one) or one bare word. A bare word stops at whitespace, a
|
|
6
|
-
* separator, a quote, or a closing bracket, so the shape *around* the secret
|
|
7
|
-
* survives: a structured result carries redaction inside its own string and is
|
|
8
|
-
* still the same JSON afterwards (the Channel parses it to decide how to show
|
|
9
|
-
* it), and a `token: xyz` phrase inside a JSON string does not swallow the
|
|
10
|
-
* quote and bracket that close it.
|
|
11
|
-
*/
|
|
12
|
-
const INLINE_SECRET_RE = /(["']?\b(?:secret|password|passwd|token|authorization|cookie|credential|api[_-]?key|private[_-]?key|client[_-]?secret)\b["']?)(\s*[:=]\s*)("(?:[^"\\]|\\.)*"|'[^']*'|`[^`]*`|[^\s,;"'`)\]}]+)/giu;
|
|
13
|
-
const BEARER_RE = /\bBearer\s+[A-Za-z0-9._~+/-]+=*/giu;
|
|
14
|
-
const PRIVATE_KEY_RE = /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/giu;
|
|
15
|
-
const JWT_RE = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/gu;
|
|
16
|
-
const COMMON_ACCESS_KEY_RE = /\b(?:AKIA|ASIA|AKLT)[A-Z0-9]{12,}\b/gu;
|
|
17
|
-
/**
|
|
18
|
-
* What may sit inside a path without ending it.
|
|
19
|
-
*
|
|
20
|
-
* A prefix only counts as a path when the characters around it agree that it is
|
|
21
|
-
* one: `~/work` is this operator's home, `/home/alicexyz` is somebody else's
|
|
22
|
-
* directory that merely starts with the same letters, and `not/home/alice` is a
|
|
23
|
-
* fragment of a longer path that was never rooted here. Letters, digits, and
|
|
24
|
-
* the separators/punctuation that appear inside real path segments continue a
|
|
25
|
-
* token; anything else — whitespace, a quote, a colon, a comma — ends it.
|
|
26
|
-
* Two narrower exceptions are handled at a match: a period closes prose only
|
|
27
|
-
* when what follows is already a boundary, and a preceding slash starts a path
|
|
28
|
-
* only when it completes a URL scheme's `://`.
|
|
29
|
-
*/
|
|
30
|
-
const PATH_TOKEN_CHARACTER_RE = /[\p{L}\p{N}_.~\\/-]/u;
|
|
31
3
|
export function createConversationProjection(input) {
|
|
32
4
|
const guarded = (agent, entryPoint, operation) => {
|
|
33
5
|
try {
|
|
@@ -131,14 +103,15 @@ function projectedActivity(activity, cwd, homePathPrefixes) {
|
|
|
131
103
|
};
|
|
132
104
|
}
|
|
133
105
|
case 'tool.call': {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
106
|
+
const redact = (text) => text === null ? null : redactText(text, cwd, homePathPrefixes);
|
|
107
|
+
const summary = redact(activity.summary);
|
|
108
|
+
const invocation = redact(activity.invocation);
|
|
137
109
|
const items = activity.items.map((item) => redactText(item, cwd, homePathPrefixes));
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
110
|
+
// A call's payloads arrive as structure, so they are walked rather than
|
|
111
|
+
// read as one string: a key that names a secret is answered by its name,
|
|
112
|
+
// and every string leaf is ordinary text by the time it is redacted.
|
|
113
|
+
const args = redactJson(activity.arguments, cwd, homePathPrefixes);
|
|
114
|
+
const result = redactJson(activity.error ?? activity.result, cwd, homePathPrefixes);
|
|
142
115
|
return {
|
|
143
116
|
kind: 'tool.call',
|
|
144
117
|
event_id: activity.id,
|
|
@@ -146,17 +119,13 @@ function projectedActivity(activity, cwd, homePathPrefixes) {
|
|
|
146
119
|
tool_name: activity.toolName,
|
|
147
120
|
tool_action: activity.action,
|
|
148
121
|
summary: summary?.value ?? null,
|
|
149
|
-
|
|
150
|
-
// is a command nobody can judge — the operator asked to read the real
|
|
151
|
-
// one — so these two members skip the redactor while every payload
|
|
152
|
-
// around them keeps it.
|
|
153
|
-
invocation: activity.invocation,
|
|
122
|
+
invocation: invocation?.value ?? null,
|
|
154
123
|
items: items.map((item) => item.value),
|
|
155
124
|
status: activity.status,
|
|
156
|
-
arguments_json: jsonText(
|
|
157
|
-
result_json: result
|
|
158
|
-
redacted:
|
|
159
|
-
|
|
125
|
+
arguments_json: jsonText(args.value),
|
|
126
|
+
result_json: jsonText(result.value),
|
|
127
|
+
redacted: [summary, invocation, args, result, ...items]
|
|
128
|
+
.some((member) => member?.redacted ?? false),
|
|
160
129
|
};
|
|
161
130
|
}
|
|
162
131
|
case 'turn.ended': {
|
|
@@ -174,103 +143,13 @@ function projectedActivity(activity, cwd, homePathPrefixes) {
|
|
|
174
143
|
}
|
|
175
144
|
/**
|
|
176
145
|
* A structured value travels as its compact JSON text; a value that already is
|
|
177
|
-
* a string travels as itself.
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* inside a JSON string can leave text no parser accepts — so a consumer that
|
|
181
|
-
* wants the structure back treats a parse failure as "this is text", which is
|
|
182
|
-
* what a display does with any payload it cannot read as JSON.
|
|
146
|
+
* a string travels as itself. The text is whole, never cut, and it is written
|
|
147
|
+
* after redaction rather than before, so a structured payload is still valid
|
|
148
|
+
* JSON when it arrives.
|
|
183
149
|
*/
|
|
184
150
|
function jsonText(value) {
|
|
185
151
|
if (value === null)
|
|
186
152
|
return null;
|
|
187
153
|
return typeof value === 'string' ? value : JSON.stringify(value);
|
|
188
154
|
}
|
|
189
|
-
/**
|
|
190
|
-
* Rewrite what a projected conversation must not publish verbatim.
|
|
191
|
-
*
|
|
192
|
-
* Two different jobs share this function. Secrets are *destroyed* — a token has
|
|
193
|
-
* no legible form worth keeping. Paths are only *renamed*: an operator reading
|
|
194
|
-
* a card still needs to know which file was touched, so the workspace becomes
|
|
195
|
-
* `.` and this host's home becomes `~`, exactly the way the operator's own shell
|
|
196
|
-
* prints them. Order matters: the workspace usually sits under the home, so
|
|
197
|
-
* relativizing it first keeps the shorter, more useful form.
|
|
198
|
-
*
|
|
199
|
-
* `homePathPrefixes` is explicit so this pure projection never depends on
|
|
200
|
-
* process-global resolution state.
|
|
201
|
-
*/
|
|
202
|
-
export function redactText(value, cwd, homePaths) {
|
|
203
|
-
let redacted = replacePathPrefix(value, cwd, '.', '', true);
|
|
204
|
-
redacted = redacted.replace(PRIVATE_KEY_RE, '<redacted-private-key>');
|
|
205
|
-
for (const homePath of homePaths) {
|
|
206
|
-
redacted = replacePathPrefix(redacted, homePath, '~', '~', false);
|
|
207
|
-
}
|
|
208
|
-
redacted = redacted.replace(BEARER_RE, 'Bearer <redacted>');
|
|
209
|
-
redacted = redacted.replace(JWT_RE, '<redacted-jwt>');
|
|
210
|
-
redacted = redacted.replace(COMMON_ACCESS_KEY_RE, '<redacted-access-key>');
|
|
211
|
-
redacted = redacted.replace(INLINE_SECRET_RE, (_match, key, separator, secret) => {
|
|
212
|
-
// A quoted secret stays a quoted (now empty of meaning) string, so the
|
|
213
|
-
// text around it keeps whatever grammar it had — JSON included.
|
|
214
|
-
const quote = /^["'`]/u.test(secret) ? secret[0] : '';
|
|
215
|
-
return `${key}${separator}${quote}<redacted>${quote}`;
|
|
216
|
-
});
|
|
217
|
-
return { value: redacted, redacted: redacted !== value };
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Replace every occurrence of `rawPrefix` that is actually the head of a path.
|
|
221
|
-
*
|
|
222
|
-
* Scanning for a known prefix is what makes this honest where a regex is not: a
|
|
223
|
-
* pattern like `/home/<name>/...` matches any string of that *shape*, including
|
|
224
|
-
* a directory on some other machine quoted in a log, and blanking those costs
|
|
225
|
-
* legibility for no privacy gain. Only the prefixes this host really uses are
|
|
226
|
-
* offered here, and each hit must still be bounded on both sides — preceded by
|
|
227
|
-
* a non-path character and followed by a separator or the end of a token.
|
|
228
|
-
*
|
|
229
|
-
* A hit with a path continuing after it (`<prefix>/rest`) takes
|
|
230
|
-
* `nestedReplacement`, and `stripNestedSeparator` drops the separator with it so
|
|
231
|
-
* a workspace `<cwd>/rest` turns into `rest`. A hit that ends there takes
|
|
232
|
-
* `exactReplacement`, so a bare workspace becomes `.`.
|
|
233
|
-
*/
|
|
234
|
-
function replacePathPrefix(value, rawPrefix, exactReplacement, nestedReplacement, stripNestedSeparator) {
|
|
235
|
-
const prefix = rawPrefix.replace(/[\\/]+$/u, '');
|
|
236
|
-
if (prefix === '')
|
|
237
|
-
return value;
|
|
238
|
-
let cursor = 0;
|
|
239
|
-
let searchFrom = 0;
|
|
240
|
-
let result = '';
|
|
241
|
-
while (searchFrom < value.length) {
|
|
242
|
-
const matchAt = value.indexOf(prefix, searchFrom);
|
|
243
|
-
if (matchAt < 0)
|
|
244
|
-
break;
|
|
245
|
-
const suffixAt = matchAt + prefix.length;
|
|
246
|
-
const next = value[suffixAt];
|
|
247
|
-
const nested = next === '/' || next === '\\';
|
|
248
|
-
const ends = isPathPrefixEnd(value, suffixAt);
|
|
249
|
-
if (isPathPrefixBoundary(value, matchAt) && (nested || ends)) {
|
|
250
|
-
result += value.slice(cursor, matchAt);
|
|
251
|
-
result += nested ? nestedReplacement : exactReplacement;
|
|
252
|
-
cursor = suffixAt + (nested && stripNestedSeparator ? 1 : 0);
|
|
253
|
-
searchFrom = cursor;
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
searchFrom = suffixAt;
|
|
257
|
-
}
|
|
258
|
-
return cursor === 0 ? value : result + value.slice(cursor);
|
|
259
|
-
}
|
|
260
|
-
function isPathPrefixBoundary(value, matchAt) {
|
|
261
|
-
if (matchAt === 0 || isPathTokenBoundary(value[matchAt - 1]))
|
|
262
|
-
return true;
|
|
263
|
-
return matchAt >= 3 && value.slice(matchAt - 3, matchAt) === '://';
|
|
264
|
-
}
|
|
265
|
-
function isPathPrefixEnd(value, suffixAt) {
|
|
266
|
-
const next = value[suffixAt];
|
|
267
|
-
if (next === undefined)
|
|
268
|
-
return true;
|
|
269
|
-
return next === '.'
|
|
270
|
-
? isPathTokenBoundary(value[suffixAt + 1])
|
|
271
|
-
: isPathTokenBoundary(next);
|
|
272
|
-
}
|
|
273
|
-
function isPathTokenBoundary(character) {
|
|
274
|
-
return character === undefined || !PATH_TOKEN_CHARACTER_RE.test(character);
|
|
275
|
-
}
|
|
276
155
|
//# sourceMappingURL=conversation-projection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-projection.js","sourceRoot":"","sources":["../../src/channel/conversation-projection.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"conversation-projection.js","sourceRoot":"","sources":["../../src/channel/conversation-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
2
|
import { isAbsolute, join } from 'node:path';
|
|
3
|
-
import { describeType, isPlainObject, } from '@excitedjs/dreamux-utils';
|
|
3
|
+
import { describeType, isPlainObject, redactSecretKeyValues, } from '@excitedjs/dreamux-utils';
|
|
4
4
|
import { InvalidProviderRefError, ReservedExternalProviderError, UnknownBuiltinProviderError, formatProviderRef, parseProviderRef, } from '../registry/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* What `dreamux config show` must not print. The walk and the secret key names
|
|
7
|
+
* are the one redaction capability in `@excitedjs/dreamux-utils`; this name
|
|
8
|
+
* stays because config is what the CLI asks for.
|
|
9
|
+
*/
|
|
10
|
+
export const redactConfigSecrets = redactSecretKeyValues;
|
|
5
11
|
export function resolveConfigProvider(rawProvider, expectedKind, file, prefix, providerRegistry) {
|
|
6
12
|
try {
|
|
7
13
|
const descriptor = providerRegistry.resolve(rawProvider);
|
|
@@ -82,25 +88,6 @@ export function readOptionalBoolean(obj, key, fallback, file, prefix = '') {
|
|
|
82
88
|
return v;
|
|
83
89
|
throw new Error(`dreamux config error in ${file}: ${prefix}${key} must be a boolean (got ${describeType(v)})`);
|
|
84
90
|
}
|
|
85
|
-
export function redactConfigSecrets(value) {
|
|
86
|
-
if (Array.isArray(value)) {
|
|
87
|
-
for (const item of value)
|
|
88
|
-
redactConfigSecrets(item);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (!isPlainObject(value))
|
|
92
|
-
return;
|
|
93
|
-
for (const [key, child] of Object.entries(value)) {
|
|
94
|
-
if (isSecretConfigKey(key)) {
|
|
95
|
-
value[key] = '<redacted>';
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
redactConfigSecrets(child);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function isSecretConfigKey(key) {
|
|
102
|
-
return /(?:secret|password|passwd|token|authorization|cookie|credential|api[_-]?key|private[_-]?key|client[_-]?secret)/i.test(key);
|
|
103
|
-
}
|
|
104
91
|
export function expandHome(path) {
|
|
105
92
|
if (path === '~')
|
|
106
93
|
return homedir();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-helpers.js","sourceRoot":"","sources":["../../src/config/config-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG7C,OAAO,EACL,YAAY,EACZ,aAAa,
|
|
1
|
+
{"version":3,"file":"config-helpers.js","sourceRoot":"","sources":["../../src/config/config-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/platform/logger.js
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
* inject a tmp `filePath`; they must not expect an env var to move logs.
|
|
37
37
|
*/
|
|
38
38
|
import { chmod } from 'node:fs/promises';
|
|
39
|
+
import { isSecretKeyName } from '@excitedjs/dreamux-utils';
|
|
39
40
|
import pino from 'pino';
|
|
40
41
|
import { errorInfo } from './error-info.js';
|
|
41
42
|
/**
|
|
@@ -50,7 +51,6 @@ import { errorInfo } from './error-info.js';
|
|
|
50
51
|
const _pinoSatisfiesContract = pino();
|
|
51
52
|
void _pinoSatisfiesContract;
|
|
52
53
|
const REDACTED_VALUE = '[REDACTED]';
|
|
53
|
-
const SECRET_KEY_RE = /(secret|password|passwd|token|authorization|cookie|credential)/i;
|
|
54
54
|
function resolveLevel(level) {
|
|
55
55
|
if (level !== undefined)
|
|
56
56
|
return level;
|
|
@@ -120,7 +120,7 @@ function redactLogValue(value, seen = new WeakSet()) {
|
|
|
120
120
|
seen.add(value);
|
|
121
121
|
const out = {};
|
|
122
122
|
for (const [key, entry] of Object.entries(value)) {
|
|
123
|
-
out[key] =
|
|
123
|
+
out[key] = isSecretKeyName(key)
|
|
124
124
|
? REDACTED_VALUE
|
|
125
125
|
: redactLogValue(entry, seen);
|
|
126
126
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/platform/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,OAAO,IAGN,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;GAQG;AACH,MAAM,sBAAsB,GAAkB,IAAI,EAAE,CAAC;AACrD,KAAK,sBAAsB,CAAC;AA8B5B,MAAM,cAAc,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/platform/logger.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@excitedjs/dreamux",
|
|
3
|
-
"version": "0.26.0-beta.
|
|
3
|
+
"version": "0.26.0-beta.243",
|
|
4
4
|
"description": "Dreamux core host for multi-dispatcher agent orchestration through provider interfaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
"CHANGELOG.json"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@excitedjs/agent-runtime-claude-code": "0.7.1-beta.
|
|
30
|
-
"@excitedjs/agent-runtime-codex": "0.6.1-beta.
|
|
31
|
-
"@excitedjs/dreamux-types": "0.11.0-beta.
|
|
32
|
-
"@excitedjs/dreamux-utils": "0.
|
|
33
|
-
"@excitedjs/feishu-channel": "6.3.0-beta.
|
|
29
|
+
"@excitedjs/agent-runtime-claude-code": "0.7.1-beta.243",
|
|
30
|
+
"@excitedjs/agent-runtime-codex": "0.6.1-beta.243",
|
|
31
|
+
"@excitedjs/dreamux-types": "0.11.0-beta.243",
|
|
32
|
+
"@excitedjs/dreamux-utils": "0.6.0-beta.243",
|
|
33
|
+
"@excitedjs/feishu-channel": "6.3.0-beta.243",
|
|
34
34
|
"@modelcontextprotocol/server": "2.0.0",
|
|
35
35
|
"acorn": "^8.16.0",
|
|
36
36
|
"croner": "^10.0.1",
|