@songsid/agend 2.3.0-beta.16 → 2.3.0-beta.17
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/README.zh-TW.md +1 -1
- package/dist/backend/claude-code.js +13 -4
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.js +15 -2
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend-command.d.ts +2 -0
- package/dist/backend-command.js +3 -1
- package/dist/backend-command.js.map +1 -1
- package/dist/bug-report-cli.d.ts +30 -0
- package/dist/bug-report-cli.js +138 -0
- package/dist/bug-report-cli.js.map +1 -0
- package/dist/bug-report.d.ts +47 -0
- package/dist/bug-report.js +136 -0
- package/dist/bug-report.js.map +1 -0
- package/dist/channel/mcp-tools.js +1 -1
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/cli.js +93 -8
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +6 -0
- package/dist/config-validator.js +13 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +14 -1
- package/dist/daemon.js +59 -3
- package/dist/daemon.js.map +1 -1
- package/dist/diagnostic-redaction.d.ts +10 -0
- package/dist/diagnostic-redaction.js +167 -0
- package/dist/diagnostic-redaction.js.map +1 -0
- package/dist/fleet-manager.d.ts +18 -0
- package/dist/fleet-manager.js +109 -8
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/bug-report/SKILL.md +31 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +22 -1
- package/dist/instance-lifecycle.d.ts +8 -1
- package/dist/instance-lifecycle.js +68 -12
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +55 -2
- package/dist/locale.js.map +1 -1
- package/dist/login-controller.d.ts +45 -0
- package/dist/login-controller.js +66 -3
- package/dist/login-controller.js.map +1 -1
- package/dist/ls-attach-resolve.d.ts +3 -2
- package/dist/ls-attach-resolve.js +10 -4
- package/dist/ls-attach-resolve.js.map +1 -1
- package/dist/ls-rows.d.ts +12 -0
- package/dist/ls-rows.js +82 -3
- package/dist/ls-rows.js.map +1 -1
- package/dist/needs-you.d.ts +10 -0
- package/dist/needs-you.js +2 -1
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.js +31 -5
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/quickstart-api.d.ts +9 -0
- package/dist/quickstart-api.js +82 -0
- package/dist/quickstart-api.js.map +1 -1
- package/dist/service-installer.js +12 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-effect.js +15 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +23 -7
- package/dist/setup-form.js.map +1 -1
- package/dist/ui/backend-signin.js +297 -0
- package/dist/ui/chat-msg-actions.js +176 -0
- package/dist/ui/chat-store.js +33 -3
- package/dist/ui/chat-strings.js +8 -2
- package/dist/ui/chat-thread.js +44 -2
- package/dist/ui/panel-chat.js +37 -0
- package/dist/ui/panel-needs.js +4 -2
- package/dist/ui/panel-settings.js +6 -3
- package/dist/ui/shared/app-shell.js +2 -1
- package/dist/ui/shared/app-stream.js +2 -1
- package/dist/ui/shared/app.css +42 -0
- package/dist/ui/shared/app.js +2 -0
- package/dist/ui/shared/usage-dialog.js +26 -3
- package/dist/ui/shared/view-strings.js +10 -0
- package/dist/ui/web-terminal/terminal.html +1 -1
- package/dist/update-launch.d.ts +9 -0
- package/dist/update-launch.js +38 -12
- package/dist/update-launch.js.map +1 -1
- package/dist/usage/format-rich.js +6 -3
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +2 -1
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/i18n.d.ts +13 -1
- package/dist/usage/i18n.js +29 -0
- package/dist/usage/i18n.js.map +1 -1
- package/dist/usage/providers.d.ts +43 -8
- package/dist/usage/providers.js +58 -20
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/usage-api.d.ts +2 -0
- package/dist/usage/usage-api.js +180 -55
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/user-systemd.d.ts +24 -0
- package/dist/user-systemd.js +75 -0
- package/dist/user-systemd.js.map +1 -0
- package/dist/web-api.d.ts +10 -1
- package/dist/web-api.js +134 -5
- package/dist/web-api.js.map +1 -1
- package/dist/web-backend-login.d.ts +130 -0
- package/dist/web-backend-login.js +225 -0
- package/dist/web-backend-login.js.map +1 -0
- package/dist/web-chat-history.d.ts +31 -0
- package/dist/web-chat-history.js +49 -1
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +5 -1
- package/dist/web-commands.js +1 -1
- package/dist/web-commands.js.map +1 -1
- package/dist/web-guest-access.d.ts +3 -2
- package/dist/web-guest-access.js +10 -6
- package/dist/web-guest-access.js.map +1 -1
- package/dist/windows-shortcuts.d.ts +78 -0
- package/dist/windows-shortcuts.js +203 -0
- package/dist/windows-shortcuts.js.map +1 -0
- package/launcher/agend-install.cjs +548 -0
- package/launcher/install-admission.cjs +4 -39
- package/launcher/postinstall.cjs +14 -12
- package/package.json +3 -2
- package/scripts/preinstall-guard.cjs +2 -5
- package/templates/windows-shortcuts.ps1 +181 -0
- package/launcher/old-updater-note.cjs +0 -48
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Public diagnostic export boundary. Never use a privacy opt-in to disable credentials. */
|
|
2
|
+
export declare const REDACTED = "[REDACTED]";
|
|
3
|
+
export interface RedactionOptions {
|
|
4
|
+
keepIdentifiers?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function redactDiagnostics(input: string, options?: RedactionOptions): string;
|
|
7
|
+
/** Log prose may itself be chat. Export only recognized diagnostics and stack locations. */
|
|
8
|
+
export declare function diagnosticLine(line: string, options?: RedactionOptions): string | null;
|
|
9
|
+
/** Unknown and arbitrary string fields are deliberately omitted, even inside nested objects. */
|
|
10
|
+
export declare function diagnosticRecord(record: Record<string, unknown>, options?: RedactionOptions): string;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
import { stripVTControlCharacters } from "node:util";
|
|
3
|
+
import { constants as osConstants } from "node:os";
|
|
4
|
+
/** Public diagnostic export boundary. Never use a privacy opt-in to disable credentials. */
|
|
5
|
+
export const REDACTED = '[REDACTED]';
|
|
6
|
+
const credentialKey = /(?:token|secret|password|passwd|credential|authorization|cookie|api[_-]?key|private[_-]?key|session|^code$|^state$)/i;
|
|
7
|
+
const contentKey = /(?:^msg$|^host$|^ip$|message|content|prompt|text|body|conversation|transcript|topic|chat|user|sender|recipient|instance|channel|guild|email|hostname|address|url|path|argv|args)/i;
|
|
8
|
+
const personalKey = /^(?:emails?|ip(?:v[46])?(?:address)?|host(?:name)?|user[_-]?name|path)$/i;
|
|
9
|
+
const safeCodes = /\b(?:E[A-Z_]{3,30}|SIG[A-Z]{2,10}|ERR_[A-Z_]+)\b/g;
|
|
10
|
+
const knownCodes = new Set([...Object.keys(osConstants.errno), ...Object.keys(osConstants.signals),
|
|
11
|
+
'EAI_AGAIN', 'EAI_NONAME', 'ERR_STREAM_DESTROYED', 'ERR_STREAM_PREMATURE_CLOSE', 'ERR_UNHANDLED_ERROR',
|
|
12
|
+
'ERR_HTTP_HEADERS_SENT', 'ERR_SOCKET_CLOSED', 'ERR_TLS_CERT_ALTNAME_INVALID', 'ERR_WORKER_OUT_OF_MEMORY',
|
|
13
|
+
'ERR_MODULE_NOT_FOUND', 'ERR_REQUIRE_ESM', 'ERR_DLOPEN_FAILED', 'ERR_INVALID_STATE']);
|
|
14
|
+
const safePhrases = /Opening handshake has timed out|Connect Timeout Error|uncaught exception|unhandled rejection|gateway watchdog|MCP server died|web_terminal_created|adapter retry exhausted|out of memory|heap limit|allocation failed/gi;
|
|
15
|
+
/** Decode common wrappers before matching; don't preserve encoded copies of credentials. */
|
|
16
|
+
function decode(text) {
|
|
17
|
+
for (let pass = 0; pass < 4; pass++) {
|
|
18
|
+
const previous = text;
|
|
19
|
+
text = text.replace(/\\u([0-9a-f]{4})/gi, (_, n) => String.fromCharCode(parseInt(n, 16)))
|
|
20
|
+
.replace(/\\x([0-9a-f]{2})/gi, (_, n) => String.fromCharCode(parseInt(n, 16)))
|
|
21
|
+
.replace(/(?:%[0-9a-f]{2})+/gi, s => { try {
|
|
22
|
+
return decodeURIComponent(s);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return REDACTED;
|
|
26
|
+
} });
|
|
27
|
+
if (text === previous)
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
// Ambiguous deeply encoded data is withheld, not partially decoded and exported.
|
|
31
|
+
return stripVTControlCharacters(text).replace(/(?:%[0-9a-f]{2})+/gi, REDACTED).replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f\u200b-\u200f\u202a-\u202e\u2060-\u206f\ufeff]/g, '');
|
|
32
|
+
}
|
|
33
|
+
/** A credential field can contain a whole object/list or YAML block, not just a string. */
|
|
34
|
+
function redactContainers(text) {
|
|
35
|
+
const fields = /["']?[\w.-]{0,128}(?:token|secret|password|passwd|credential|authorization|cookie|session|api[_-]?key|private[_-]?key)[\w.-]{0,128}["']?\s*[:=]\s*/gi;
|
|
36
|
+
let cursor = 0, out = '', match;
|
|
37
|
+
while ((match = fields.exec(text))) {
|
|
38
|
+
const start = fields.lastIndex, opener = text[start];
|
|
39
|
+
if ((opener !== '{' && opener !== '[') || text.startsWith(REDACTED, start))
|
|
40
|
+
continue;
|
|
41
|
+
const stack = [], pairs = { '{': '}', '[': ']' };
|
|
42
|
+
let quote = '', escaped = false, end = text.length;
|
|
43
|
+
for (let i = start; i < text.length; i++) {
|
|
44
|
+
const c = text[i];
|
|
45
|
+
if (quote) {
|
|
46
|
+
if (escaped)
|
|
47
|
+
escaped = false;
|
|
48
|
+
else if (c === '\\')
|
|
49
|
+
escaped = true;
|
|
50
|
+
else if (c === quote)
|
|
51
|
+
quote = '';
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (c === '"' || c === "'") {
|
|
55
|
+
quote = c;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (pairs[c])
|
|
59
|
+
stack.push(pairs[c]);
|
|
60
|
+
else if (c === '}' || c === ']') {
|
|
61
|
+
if (stack.pop() !== c)
|
|
62
|
+
break; // malformed container: withhold the rest
|
|
63
|
+
if (!stack.length) {
|
|
64
|
+
end = i + 1;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
out += text.slice(cursor, start) + REDACTED;
|
|
70
|
+
cursor = end;
|
|
71
|
+
fields.lastIndex = end;
|
|
72
|
+
}
|
|
73
|
+
text = out + text.slice(cursor);
|
|
74
|
+
return text.replace(/^([ \t]*["']?[\w.-]{0,128}(?:token|secret|password|passwd|credential|cookie|api[_-]?key)[\w.-]{0,128}["']?\s*:\s*)[>|][-+]?[^\r\n]*(?:\r?\n[ \t]+[^\r\n]*)*/gmi, '$1' + REDACTED);
|
|
75
|
+
}
|
|
76
|
+
export function redactDiagnostics(input, options = {}) {
|
|
77
|
+
// Whole structured values (including nested cookie/token objects) cannot be redacted safely token by token.
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(input);
|
|
80
|
+
if (parsed && typeof parsed === 'object') {
|
|
81
|
+
const scrub = (value, depth) => {
|
|
82
|
+
if (depth > 16)
|
|
83
|
+
return REDACTED;
|
|
84
|
+
if (typeof value === 'string')
|
|
85
|
+
return redactDiagnostics(value, options);
|
|
86
|
+
if (Array.isArray(value))
|
|
87
|
+
return value.map(v => scrub(v, depth + 1));
|
|
88
|
+
if (value && typeof value === 'object')
|
|
89
|
+
return Object.fromEntries(Object.entries(value).map(([key, v]) => [redactDiagnostics(key, options), credentialKey.test(key) || (contentKey.test(key) && !(options.keepIdentifiers && personalKey.test(key))) ? REDACTED : scrub(v, depth + 1)]));
|
|
90
|
+
return value;
|
|
91
|
+
};
|
|
92
|
+
return JSON.stringify(scrub(parsed, 0));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch { /* Free-form diagnostic/description, handled below. */ }
|
|
96
|
+
let text = redactContainers(decode(input));
|
|
97
|
+
text = text.replace(/-----BEGIN [^-\r\n]*(?:PRIVATE KEY|CERTIFICATE)-----[\s\S]*?(?:-----END [^-\r\n]+-----|$)/gi, REDACTED);
|
|
98
|
+
// Entire header values, including folded continuation lines; not just Bearer tokens.
|
|
99
|
+
text = text.replace(/\b(?:authorization|proxy-authorization|cookie|set-cookie)\s*:[^\r\n]*(?:\r?\n[ \t]+[^\r\n]*)*/gi, REDACTED);
|
|
100
|
+
// Quoted JSON/YAML/env/query credential values, including whitespace and multiline strings.
|
|
101
|
+
text = text.replace(/(["']?[\w.-]{0,128}(?:tokens?|secrets?|passwords?|passwd|credentials?[\w.-]{0,128}|authorization|cookies?|api[_-]?key|private[_-]?key|session(?:[_-]?(?:key|id))?)[\w.-]{0,128}["']?\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\[REDACTED\]|[^\s,;&}\]\r\n]+)/gi, '$1' + REDACTED);
|
|
102
|
+
text = text.replace(/\b(?:Bearer|Basic)\s+[^\s,;"'<>]+/gi, REDACTED)
|
|
103
|
+
.replace(/\b(?:mfa\.[\w-]+|[\w-]{20,}\.[\w-]{6,}\.[\w-]{20,})\b/g, REDACTED)
|
|
104
|
+
.replace(/\b\d{5,}:[A-Za-z0-9_-]{15,}\b/g, REDACTED)
|
|
105
|
+
.replace(/\b(?:ya29\.[\w.-]+|1\/\/[\w.-]+|sk-[\w-]+|gh[pousr]_[\w]+|github_pat_[\w]+|xox[baprs]-[\w-]+|AKIA[A-Z0-9]{12,}|ASIA[A-Z0-9]{12,}|AIza[\w-]{20,}|npm_[\w]+|glpat-[\w-]+)\b/g, REDACTED)
|
|
106
|
+
.replace(/\beyJ[\w-]*\.[\w-]+\.[\w-]+\b/g, REDACTED)
|
|
107
|
+
.replace(/\b[a-z][a-z\d+.-]{0,127}:\/\/[^\s<>"']+/gi, REDACTED);
|
|
108
|
+
// Protect only recognized diagnostic locations/fields AFTER explicit credential rules.
|
|
109
|
+
// Do not treat scoped npm paths as emails, long module names as opaque tokens, or
|
|
110
|
+
// trusted line numbers/durations as chat IDs during the general privacy pass.
|
|
111
|
+
const kept = new Map();
|
|
112
|
+
const keep = (value) => { const marker = 'AGENDKEEP' + kept.size.toString(36) + 'Q'; kept.set(marker, value); return marker; };
|
|
113
|
+
const safePath = (value) => value.split(/[\\/]/).map(part => part.replace(/[A-Za-z0-9_+=]{24,}|\b\d{5,}\b/g, REDACTED)).join('/');
|
|
114
|
+
text = text.replace(/(?:…+)?(?:[a-z]:[\\/]|\/)[^\r\n<>"()]{0,512}?@songsid[\\/]agend[\\/]((?:[@\w.-]+[\\/]){0,12}[\w.-]+\.(?:[cm]?js|ts)):(\d{1,7}):(\d{1,7})/gi, (_all, relative, line, column) => keep('…/@songsid/agend/' + safePath(relative) + ':' + line + ':' + column))
|
|
115
|
+
.replace(/\bnode:([a-z_]+(?:\/[\w.-]+){0,12}):(\d{1,7}):(\d{1,7})/g, (_all, relative, line, column) => keep('node:' + safePath(relative) + ':' + line + ':' + column))
|
|
116
|
+
.replace(/"(?:duration|durationMs|attempt|exitCode|statusCode)"\s*:\s*-?\d{1,24}(?:\.\d{1,12})?(?:e[+-]?\d{1,3})?/gi, keep);
|
|
117
|
+
text = text
|
|
118
|
+
// Opaque unknown keys and unlabelled IDs. Over-redaction is intentional.
|
|
119
|
+
.replace(/[A-Za-z0-9_+/=-]{24,}/g, REDACTED)
|
|
120
|
+
.replace(/\b\d{5,}\b/g, REDACTED)
|
|
121
|
+
.replace(/[\"']?\b[\w.-]{0,128}(?:topic|chat|user|sender|recipient|instance|channel|guild)[_-]?id[\"']?\s*[=:]\s*(?:\[REDACTED\]|[^\s,;]+)/gi, REDACTED)
|
|
122
|
+
.replace(/\b(?:message|content|prompt|chat[_-]?text)\s*[=:]\s*[^\r\n]*/gi, REDACTED);
|
|
123
|
+
if (!options.keepIdentifiers) {
|
|
124
|
+
text = text.replace(/[^\s@<>"'(),;\[\]\\/:]{1,320}@[^\s@<>"'(),;\[\]\\/:]{1,320}/gu, REDACTED)
|
|
125
|
+
.replace(/(?:\b\d{1,3}\.){3}\d{1,3}\b/g, REDACTED)
|
|
126
|
+
.replace(/\[?[a-f\d:.]{0,64}:[a-f\d:.]{1,64}(?:%[\w.-]{1,64})?\]?/gi, value => isIP(value.replace(/^\[|\]$/g, '').split('%')[0]) === 6 ? REDACTED : value)
|
|
127
|
+
.replace(/(?<![\p{L}\p{N}_-])[\p{L}\p{N}-][\p{L}\p{N}.-]{0,252}\.[\p{L}][\p{L}\p{N}-]{0,62}(?![\p{L}\p{N}_-])/gu, value => /\.(?:ya?ml|json|log|[cm]?js|tsx?|md|txt|sh|ps1)$/i.test(value) || /^(?:e\.g|i\.e)$/i.test(value) ? value : REDACTED)
|
|
128
|
+
.replace(/(\/(?:home|Users|mnt\/[a-z]\/Users)\/)[^\/\s]+/gi, '$1' + REDACTED)
|
|
129
|
+
.replace(/([a-z]:\\Users\\)[^\\\s]+/gi, '$1' + REDACTED)
|
|
130
|
+
.replace(/[\"']?\b(?:host(?:name)?|user(?:name)?)[\"']?\s*[=:]\s*(?:\[REDACTED\]|[^\s,;]+)/gi, REDACTED);
|
|
131
|
+
}
|
|
132
|
+
return text.replace(/AGENDKEEP[0-9a-z]+Q/g, value => kept.get(value) ?? value);
|
|
133
|
+
}
|
|
134
|
+
/** Log prose may itself be chat. Export only recognized diagnostics and stack locations. */
|
|
135
|
+
export function diagnosticLine(line, options = {}) {
|
|
136
|
+
const codes = [...new Set((line.match(safeCodes) ?? []).filter(code => knownCodes.has(code)))];
|
|
137
|
+
const phrases = [...new Set(line.match(safePhrases) ?? [])];
|
|
138
|
+
const stack = line.match(/^\s*at\s+(?:[\w.$<>]+\s+)?\(?((?:\/|[a-z]:\\|node:)[^\r\n]*?:\d+:\d+)\)?\s*$/i);
|
|
139
|
+
if (stack)
|
|
140
|
+
return redactDiagnostics('at ' + stack[1], options);
|
|
141
|
+
const diagnostic = [...phrases, ...codes].join('; ');
|
|
142
|
+
return diagnostic ? redactDiagnostics(diagnostic, options) : null;
|
|
143
|
+
}
|
|
144
|
+
/** Unknown and arbitrary string fields are deliberately omitted, even inside nested objects. */
|
|
145
|
+
export function diagnosticRecord(record, options = {}) {
|
|
146
|
+
const out = {};
|
|
147
|
+
for (const [key, value] of Object.entries(record)) {
|
|
148
|
+
if (credentialKey.test(key) || contentKey.test(key))
|
|
149
|
+
continue;
|
|
150
|
+
if (/^(?:level|duration|durationMs|attempt|exitCode|statusCode)$/.test(key) && typeof value === 'number')
|
|
151
|
+
out[key] = value;
|
|
152
|
+
if (/^(?:backend|runtime)$/.test(key) && typeof value === 'string' && /^(?:claude-code|codex|kiro-cli|opencode|grok|muse|antigravity|node)$/.test(value))
|
|
153
|
+
out[key] = value;
|
|
154
|
+
if (/^(?:version|cliVersion|backendVersion)$/.test(key) && typeof value === 'string' && /^\d{1,3}\.\d{1,3}\.\d{1,3}(?:-[a-z]+\.\d{1,3})?$/.test(value))
|
|
155
|
+
out[key] = value;
|
|
156
|
+
if (key === 'err' || key === 'error') {
|
|
157
|
+
const error = value && typeof value === 'object' ? value : { message: value };
|
|
158
|
+
const lines = Object.values(error).filter((s) => typeof s === 'string').flatMap(s => s.split('\n'));
|
|
159
|
+
out.error = lines.map(l => diagnosticLine(l, options)).filter(Boolean).join('\n') || '[Free-form error details withheld]';
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// msg is inspected for canonical diagnostics, never exported as raw prose.
|
|
163
|
+
if (typeof record.msg === 'string')
|
|
164
|
+
out.diagnostic = diagnosticLine(record.msg, options) ?? '[Free-form log text withheld]';
|
|
165
|
+
return JSON.stringify(out);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=diagnostic-redaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostic-redaction.js","sourceRoot":"","sources":["../src/diagnostic-redaction.ts"],"names":[],"mappings":"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"}
|
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ import { AgentMods } from "./web-mod-agent.js";
|
|
|
76
76
|
import { type CachedImage } from "./web-images.js";
|
|
77
77
|
import { WebSettingsTools } from "./web-settings-tools.js";
|
|
78
78
|
import { type Delegation, type TrafficItem } from "./fleet-traffic.js";
|
|
79
|
+
import { WebBackendLogins, type SignInTarget } from "./web-backend-login.js";
|
|
79
80
|
import { type RawConfigPatch } from "./settings-api.js";
|
|
80
81
|
import { type AgentEndpointContext } from "./agent-endpoint.js";
|
|
81
82
|
import { ClassicChannelManager } from "./classic-channel-manager.js";
|
|
@@ -3057,6 +3058,23 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
3057
3058
|
*/
|
|
3058
3059
|
private readonly loginWindow;
|
|
3059
3060
|
private get webLogin();
|
|
3061
|
+
/** #2233: sign-ins started from the web dashboard (local admin sessions), on the same controller as chat's. */
|
|
3062
|
+
private webBackendLoginsInstance;
|
|
3063
|
+
get webBackendLogins(): WebBackendLogins;
|
|
3064
|
+
/** #2233: the login a paused-for-sign-in instance needs, when the dashboard can sign it in. */
|
|
3065
|
+
private signInFor;
|
|
3066
|
+
/**
|
|
3067
|
+
* #2233: Settings → Agents' sign-in list — every backend's default login as the availability snapshot has it, then
|
|
3068
|
+
* each credential profile an agent uses (its own login state, read offline).
|
|
3069
|
+
*/
|
|
3070
|
+
backendSignInTargets(): SignInTarget[];
|
|
3071
|
+
/** #2233: the session with this handle is live, admin, local and of the current dashboard token. */
|
|
3072
|
+
private isLocalAdminSession;
|
|
3073
|
+
/**
|
|
3074
|
+
* #2233: `/login` for a dashboard requester. The same controller and checks; a CLI that is not installed is refused
|
|
3075
|
+
* with its install command (chat's install-first runs a terminal of its own, which the dashboard does not offer).
|
|
3076
|
+
*/
|
|
3077
|
+
private startWebDashboardLogin;
|
|
3060
3078
|
/**
|
|
3061
3079
|
* Post the backend chooser for a bare `/login`. Caller enforces admin.
|
|
3062
3080
|
* Returns why the chooser could not be posted, for the caller to tell the
|
package/dist/fleet-manager.js
CHANGED
|
@@ -190,6 +190,7 @@ import { installedChannel, updateNoticeKey } from "./update-check.js";
|
|
|
190
190
|
import { resolveInstalledAgend } from "./update-dispatch.js";
|
|
191
191
|
import { resolveUpdateLaunch, openUpdateLog, updateLogPath, watchUpdateLaunch } from "./update-launch.js";
|
|
192
192
|
import { admitProfileLogin, LoginController, LOGIN_TOKEN_RESEND_PREFIX, POST_LOGIN_RECOVERY_DEADLINE_MS } from "./login-controller.js";
|
|
193
|
+
import { WebBackendLogins, dashboardSignInSupported } from "./web-backend-login.js";
|
|
193
194
|
import { runBeforeDeadline } from "./deadline.js";
|
|
194
195
|
import { LoginWindowLock } from "./login-window-lock.js";
|
|
195
196
|
import { handleSettingsRequest } from "./settings-api.js";
|
|
@@ -248,7 +249,7 @@ import { PROVIDER_SECRET_SPECS, providerSecretSpec, providerRegistryEnvKeys, isR
|
|
|
248
249
|
/** A self-restart is a whole service restart; 120s is the apply budget, not this. */
|
|
249
250
|
const SELF_RESTART_DEADLINE_MS = 300_000;
|
|
250
251
|
import { APPLY_FLEET_TARGET, ApplyJobStore, viewOf, } from "./apply-job.js";
|
|
251
|
-
import { CHAT_PROFILE_LOGIN_BACKENDS, credentialHomeSpec, credentialProfileHome, credentialProfileLogin, credentialProfileStoreHome, credentialSwitchCarriesConversation, credentialSwitchStartsFresh, instanceCredentialProfile } from "./backend/credential-profile.js";
|
|
252
|
+
import { CHAT_PROFILE_LOGIN_BACKENDS, credentialHomeSpec, credentialProfileHome, credentialProfileLogin, credentialProfileLoginCommand, credentialProfileStoreHome, credentialSwitchCarriesConversation, credentialSwitchStartsFresh, instanceCredentialProfile } from "./backend/credential-profile.js";
|
|
252
253
|
import { carryClaudeConversation } from "./backend/claude-carry.js";
|
|
253
254
|
import { mergeBackendOptions, profileKey, profileName, profileOf } from "./classic-bindings.js";
|
|
254
255
|
import { classifyInstanceChange, CLASSIC_HOT_CONFIG_KEYS, HOT_INSTANCE_CONFIG_KEYS, hotConfigUpdate, } from "./instance-config-impact.js";
|
|
@@ -261,6 +262,14 @@ import { SpawnGate } from "./spawn-gate.js";
|
|
|
261
262
|
import { BackendOutageTracker } from "./backend-outage.js";
|
|
262
263
|
import { canUnlockAdvancedTips, DailyTipScheduler, selectTip, visibleTipLevels, } from "./tips.js";
|
|
263
264
|
import { getTmuxSession } from "./config.js";
|
|
265
|
+
// Closed migration cohort: these 11 names existed immediately before the first
|
|
266
|
+
// managed-skill publisher (a1ac499f; parent e267e684). Never grow this set when
|
|
267
|
+
// adding a bundled skill: its new name is not proof of old AgEnD ownership.
|
|
268
|
+
const PRE_MANIFEST_KIRO_SKILLS = new Set([
|
|
269
|
+
"backend-providers", "cross-instance-messaging", "fleet-config", "fleet-health",
|
|
270
|
+
"fleet-restart", "instance-lifecycle", "model-discovery", "multi-channel",
|
|
271
|
+
"scheduling", "session-management", "tui-effort",
|
|
272
|
+
]);
|
|
264
273
|
export function resolveReplyThreadId(argsThreadId, instanceConfig) {
|
|
265
274
|
if (typeof argsThreadId === "string" && argsThreadId.length > 0) {
|
|
266
275
|
return argsThreadId;
|
|
@@ -7384,6 +7393,10 @@ export class FleetManager {
|
|
|
7384
7393
|
// operation so an older stop never reports. No pending operation means
|
|
7385
7394
|
// a plain boot — nothing was stopped by an operation, report nothing.
|
|
7386
7395
|
const backgroundWorkEndedNames = this.collectBackgroundWorkEndedNames(configuredNames, pendingUpdateProgress?.startedAt ?? null);
|
|
7396
|
+
// #2264: an update whose fleet comes back on another version did not land — say so in its final message (the
|
|
7397
|
+
// version it aimed for, the one running, and the one repair), never just "updated".
|
|
7398
|
+
const aimedAt = pendingProgressOperation === "update" ? pendingUpdateProgress?.progress.version : undefined;
|
|
7399
|
+
const notLanded = aimedAt && agendVersion !== "unknown" && aimedAt !== agendVersion ? t("update.not_landed", aimedAt, agendVersion) : null;
|
|
7387
7400
|
const completionSummary = {
|
|
7388
7401
|
running: started,
|
|
7389
7402
|
total,
|
|
@@ -7393,7 +7406,7 @@ export class FleetManager {
|
|
|
7393
7406
|
backgroundWorkEndedNames,
|
|
7394
7407
|
...(cleanupOutcome && "render" in cleanupOutcome
|
|
7395
7408
|
? { warningText: cleanupOutcome.render.warning, warningCommand: cleanupOutcome.render.cleanupCommand }
|
|
7396
|
-
: {}),
|
|
7409
|
+
: notLanded ? { warningText: notLanded } : {}),
|
|
7397
7410
|
};
|
|
7398
7411
|
const progressCompleted = await startupProgress.finish(completionSummary);
|
|
7399
7412
|
// Armed only after the completion posted: an append racing ahead of it would be overwritten by it.
|
|
@@ -13469,6 +13482,7 @@ export class FleetManager {
|
|
|
13469
13482
|
interactionSummary: p.interaction_summary ?? null,
|
|
13470
13483
|
pauseReason, pausedAt,
|
|
13471
13484
|
crashedAt: crashed ? (this.needsCrashedAt.get(name) ?? null) : null,
|
|
13485
|
+
signIn: pauseReason === "auth" ? this.signInFor(name) : null,
|
|
13472
13486
|
});
|
|
13473
13487
|
}
|
|
13474
13488
|
return out;
|
|
@@ -14179,7 +14193,7 @@ export class FleetManager {
|
|
|
14179
14193
|
const current = this.resolveInstanceEffort(instance).effort;
|
|
14180
14194
|
return { current, options: levels.map(l => ({ id: l, label: this.effortChoiceLabel(l, current) })) };
|
|
14181
14195
|
},
|
|
14182
|
-
backendStep: async (instance, args) => {
|
|
14196
|
+
backendStep: async (instance, args, stepOpts) => {
|
|
14183
14197
|
const refusal = this.backendCommandRefusal(instance);
|
|
14184
14198
|
if (refusal)
|
|
14185
14199
|
return { error: refusal };
|
|
@@ -14189,7 +14203,13 @@ export class FleetManager {
|
|
|
14189
14203
|
return step.noop ? { text: step.text } : { error: step.text };
|
|
14190
14204
|
if (step.kind === "choose") {
|
|
14191
14205
|
const id = (token) => joinBackendArgs([...step.args, token]);
|
|
14192
|
-
return { choices: { prompt: step.text, current: step.current === null ? null : id(step.current), options: step.choices.map(c =>
|
|
14206
|
+
return { choices: { prompt: step.text, current: step.current === null ? null : id(step.current), options: step.choices.map(c => {
|
|
14207
|
+
// #2233: the web offers Sign in beside it, so its reason is no longer "use /login".
|
|
14208
|
+
// Not over the public link: Sign in is refused there, so the choice keeps its "(use /login)" (#2262 review).
|
|
14209
|
+
const signIn = c.signIn && !stepOpts?.publicLink && dashboardSignInSupported(c.signIn) ? c.signIn : null;
|
|
14210
|
+
const disabled = signIn ? t("backend.reason_not_signed_in_web") : c.disabled;
|
|
14211
|
+
return { id: id(c.token), label: signIn ? `${c.token} — ${disabled}` : c.label, ...(disabled ? { disabled } : {}), ...(signIn ? { signIn } : {}) };
|
|
14212
|
+
}) } };
|
|
14193
14213
|
}
|
|
14194
14214
|
const now = performance.now();
|
|
14195
14215
|
for (const [k, v] of this.webBackendTokens)
|
|
@@ -15353,6 +15373,86 @@ export class FleetManager {
|
|
|
15353
15373
|
}
|
|
15354
15374
|
return this.loginController;
|
|
15355
15375
|
}
|
|
15376
|
+
/** #2233: sign-ins started from the web dashboard (local admin sessions), on the same controller as chat's. */
|
|
15377
|
+
webBackendLoginsInstance = null;
|
|
15378
|
+
get webBackendLogins() {
|
|
15379
|
+
this.webBackendLoginsInstance ??= new WebBackendLogins({
|
|
15380
|
+
isLocalAdmin: handle => this.isLocalAdminSession(handle),
|
|
15381
|
+
start: (backend, chat, opts) => this.startWebDashboardLogin(backend, chat, opts),
|
|
15382
|
+
accessToken: sink => this.loginController?.webAccessToken(sink) ?? null,
|
|
15383
|
+
isActiveFor: sink => this.loginController?.isActiveFor(sink) ?? false,
|
|
15384
|
+
cancelFor: sink => this.loginController?.cancelFor(sink) ?? Promise.resolve(false),
|
|
15385
|
+
cancel: () => this.cancelLoginSession(),
|
|
15386
|
+
notice: ({ shown, label, handle }) => this.notifyFleetError(t("login.web_dashboard_notice", shown, label, handle.slice(0, 8))),
|
|
15387
|
+
// No details in the event: each page reads its own view (GET /ui/backend-login), as its session may see it.
|
|
15388
|
+
changed: () => broadcastSseEvent(this.sseClients, "backend_login", {}, err => this.logger.debug({ err }, "backend_login event failed")),
|
|
15389
|
+
});
|
|
15390
|
+
return this.webBackendLoginsInstance;
|
|
15391
|
+
}
|
|
15392
|
+
/** #2233: the login a paused-for-sign-in instance needs, when the dashboard can sign it in. */
|
|
15393
|
+
signInFor(name) {
|
|
15394
|
+
const backend = this.backendNameForInstance(name);
|
|
15395
|
+
const profile = this.credentialProfileOf(name, backend);
|
|
15396
|
+
return dashboardSignInSupported(backend, profile) ? { backend, ...(profile ? { profile } : {}) } : null;
|
|
15397
|
+
}
|
|
15398
|
+
/**
|
|
15399
|
+
* #2233: Settings → Agents' sign-in list — every backend's default login as the availability snapshot has it, then
|
|
15400
|
+
* each credential profile an agent uses (its own login state, read offline).
|
|
15401
|
+
*/
|
|
15402
|
+
backendSignInTargets() {
|
|
15403
|
+
const out = [];
|
|
15404
|
+
for (const row of this.backendAvailabilityRows()) {
|
|
15405
|
+
const flow = LOGIN_FLOWS[row.backend];
|
|
15406
|
+
const install = BACKEND_INSTALLATION_INFO[row.backend]?.install;
|
|
15407
|
+
out.push({
|
|
15408
|
+
// Not installed or too old: signing in would not help — the row says how to install (or update) it instead.
|
|
15409
|
+
backend: row.backend, state: row.state, signIn: row.state !== "not_installed" && row.state !== "too_old" && dashboardSignInSupported(row.backend),
|
|
15410
|
+
...(flow?.remoteLogin === "unsupported" ? { hostCommand: flow.command } : {}),
|
|
15411
|
+
...(row.state === "not_installed" && install ? { install } : {}),
|
|
15412
|
+
...(row.state === "too_old" && install ? { update: install } : {}),
|
|
15413
|
+
});
|
|
15414
|
+
}
|
|
15415
|
+
const seen = new Set();
|
|
15416
|
+
for (const name of Object.keys(this.fleetConfig?.instances ?? {}).sort()) {
|
|
15417
|
+
const backend = this.backendNameForInstance(name);
|
|
15418
|
+
const profile = this.credentialProfileOf(name, backend);
|
|
15419
|
+
if (!profile || seen.has(`${backend}\0${profile}`))
|
|
15420
|
+
continue;
|
|
15421
|
+
seen.add(`${backend}\0${profile}`);
|
|
15422
|
+
let login = "unknown";
|
|
15423
|
+
try {
|
|
15424
|
+
login = credentialProfileLogin(this.dataDir, backend, profile).state;
|
|
15425
|
+
}
|
|
15426
|
+
catch { /* unknown */ }
|
|
15427
|
+
const signIn = dashboardSignInSupported(backend, profile);
|
|
15428
|
+
const hostCommand = signIn ? null : credentialProfileLoginCommand(this.dataDir, backend, profile);
|
|
15429
|
+
out.push({ backend, profile, state: login === "logged-in" ? "usable" : login === "signed-out" ? "not_signed_in" : "unknown", signIn,
|
|
15430
|
+
...(hostCommand ? { hostCommand } : {}) });
|
|
15431
|
+
}
|
|
15432
|
+
return out;
|
|
15433
|
+
}
|
|
15434
|
+
/** #2233: the session with this handle is live, admin, local and of the current dashboard token. */
|
|
15435
|
+
isLocalAdminSession(handle) {
|
|
15436
|
+
const sessions = this.webSessions, token = this.webToken;
|
|
15437
|
+
const record = sessions?.findByHandle(handle);
|
|
15438
|
+
return !!record && !!token && record.tier === "admin" && record.surface === "local" && sessions.isCurrent(record, tokenEpoch(token));
|
|
15439
|
+
}
|
|
15440
|
+
/**
|
|
15441
|
+
* #2233: `/login` for a dashboard requester. The same controller and checks; a CLI that is not installed is refused
|
|
15442
|
+
* with its install command (chat's install-first runs a terminal of its own, which the dashboard does not offer).
|
|
15443
|
+
*/
|
|
15444
|
+
startWebDashboardLogin(backendArg, chat, opts) {
|
|
15445
|
+
const wanted = LOGIN_BACKEND_ALIASES[backendArg.toLowerCase()] ?? backendArg.toLowerCase();
|
|
15446
|
+
if (isRemovedBackend(wanted))
|
|
15447
|
+
return Promise.resolve(removedBackendMessage(wanted));
|
|
15448
|
+
const info = BACKEND_INSTALLATION_INFO[wanted];
|
|
15449
|
+
if (info && LOGIN_FLOWS[wanted]?.remoteLogin !== "unsupported" && !this.isCliInstalled(wanted)) {
|
|
15450
|
+
return Promise.resolve(t("login.web_dashboard_not_installed", wanted, info.install));
|
|
15451
|
+
}
|
|
15452
|
+
if (!opts.skipAuthCheck)
|
|
15453
|
+
this.recordLoginFlow(wanted, "login", chat.userId);
|
|
15454
|
+
return this.webLogin.start(backendArg, chat, opts);
|
|
15455
|
+
}
|
|
15356
15456
|
/**
|
|
15357
15457
|
* Post the backend chooser for a bare `/login`. Caller enforces admin.
|
|
15358
15458
|
* Returns why the chooser could not be posted, for the caller to tell the
|
|
@@ -16089,6 +16189,7 @@ export class FleetManager {
|
|
|
16089
16189
|
links: m.links,
|
|
16090
16190
|
channel: m.channel,
|
|
16091
16191
|
from: m.from,
|
|
16192
|
+
replyTo: m.replyTo,
|
|
16092
16193
|
});
|
|
16093
16194
|
broadcastSseEvent(this.sseClients, event, recorded, onError, this.webChatHistory.cursorOf(recorded));
|
|
16094
16195
|
// #1629: live-only receipt after the recorded agent reply. Never persist/replay it or give it an SSE cursor.
|
|
@@ -16435,16 +16536,16 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
16435
16536
|
.filter(name => existsSync(join(srcSkills, name, "SKILL.md")))
|
|
16436
16537
|
.sort();
|
|
16437
16538
|
// Pre-manifest Kiro General copied bundled skills directly into
|
|
16438
|
-
// .kiro/skills. If every existing skill is still
|
|
16439
|
-
// the
|
|
16440
|
-
// the ownership manifest. Any extra skill name keeps the directory fully
|
|
16539
|
+
// .kiro/skills. If every existing skill is still bundled AND belongs to
|
|
16540
|
+
// the closed pre-manifest cohort, adopt it once, update it below, and
|
|
16541
|
+
// write the ownership manifest. Any extra skill name keeps the directory fully
|
|
16441
16542
|
// on the user-owned/collision path.
|
|
16442
16543
|
if (!hadManifest && adoptLegacyUnmanaged) {
|
|
16443
16544
|
const existing = readdirSync(destSkills, { withFileTypes: true })
|
|
16444
16545
|
.filter(entry => entry.isDirectory() && existsSync(join(destSkills, entry.name, "SKILL.md")))
|
|
16445
16546
|
.map(entry => entry.name)
|
|
16446
16547
|
.sort();
|
|
16447
|
-
if (existing.length > 0 && existing.every(name => bundled.includes(name))) {
|
|
16548
|
+
if (existing.length > 0 && existing.every(name => bundled.includes(name) && PRE_MANIFEST_KIRO_SKILLS.has(name))) {
|
|
16448
16549
|
previouslyManaged = existing;
|
|
16449
16550
|
this.logger.info({ skills: existing, destSkills }, "Adopted legacy AgEnD skills into managed ownership");
|
|
16450
16551
|
}
|