@gmickel/gno 2.5.1 → 2.7.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/README.md +60 -5
- package/assets/skill/README.md +5 -1
- package/assets/skill/SKILL.md +80 -4
- package/assets/skill/cli-reference.md +132 -2
- package/assets/skill/examples.md +30 -0
- package/assets/skill/mcp-reference.md +54 -1
- package/assets/skill/recipes/capture-and-file.md +6 -0
- package/assets/skill/recipes/memory-file-decision.md +6 -0
- package/assets/skill/recipes/memory-supersede-fact.md +5 -0
- package/assets/skill/recipes/session-evidence-lookup.md +98 -0
- package/assets/spa-production.json.gz +0 -0
- package/browser-extension/artifacts/{gno-browser-clipper-v2.5.1.zip → gno-browser-clipper-v2.7.0.zip} +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.7.0.zip.sha256 +1 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/package.json +2 -1
- package/spec/cli.md +449 -35
- package/spec/mcp.md +234 -4
- package/spec/output-schemas/ask.schema.json +1 -1
- package/spec/output-schemas/capture-receipt.schema.json +4 -1
- package/spec/output-schemas/doctor.schema.json +88 -0
- package/spec/output-schemas/error.schema.json +11 -2
- package/spec/output-schemas/get.schema.json +1 -1
- package/spec/output-schemas/mcp-capture-result.schema.json +4 -2
- package/spec/output-schemas/memory-remember.schema.json +10 -4
- package/spec/output-schemas/multi-get.schema.json +4 -1
- package/spec/output-schemas/peek.schema.json +2 -9
- package/spec/output-schemas/request-status.schema.json +113 -0
- package/spec/output-schemas/resident-status.schema.json +22 -0
- package/spec/output-schemas/search-result.schema.json +1 -1
- package/spec/output-schemas/search-results.schema.json +1 -1
- package/spec/output-schemas/sessions-automation-run.schema.json +46 -0
- package/spec/output-schemas/sessions-discovery.schema.json +38 -0
- package/spec/output-schemas/sessions-import-receipt.schema.json +156 -0
- package/spec/output-schemas/sessions-status.schema.json +432 -0
- package/spec/output-schemas/status.schema.json +98 -0
- package/src/cli/commands/ask.ts +14 -2
- package/src/cli/commands/capture.ts +55 -96
- package/src/cli/commands/daemon.ts +41 -0
- package/src/cli/commands/doctor.ts +54 -20
- package/src/cli/commands/embed.ts +41 -3
- package/src/cli/commands/ls.ts +3 -0
- package/src/cli/commands/memory.ts +12 -3
- package/src/cli/commands/query.ts +5 -0
- package/src/cli/commands/request-status.ts +59 -0
- package/src/cli/commands/reset.ts +39 -5
- package/src/cli/commands/sessions.ts +713 -0
- package/src/cli/commands/shared.ts +14 -1
- package/src/cli/commands/status.ts +63 -5
- package/src/cli/commands/vec.ts +54 -0
- package/src/cli/detach.ts +29 -1
- package/src/cli/errors.ts +13 -9
- package/src/cli/program.ts +441 -2
- package/src/cli/session-binding.ts +49 -0
- package/src/config/types.ts +8 -0
- package/src/core/capture-publish.ts +239 -0
- package/src/core/capture-sync.ts +12 -2
- package/src/core/host-paths.ts +31 -0
- package/src/core/memory-remember.ts +234 -122
- package/src/core/memory-types.ts +11 -0
- package/src/core/network-boundary-inventory.ts +8 -0
- package/src/core/request-receipts.ts +671 -0
- package/src/core/shutdown-budget.ts +6 -0
- package/src/core/vector-partition-status.ts +52 -0
- package/src/embed/backlog.ts +124 -18
- package/src/embed/fingerprint.ts +6 -3
- package/src/embed/retry.ts +66 -27
- package/src/embed/variant-backlog.ts +15 -10
- package/src/embed/variant-retry.ts +31 -22
- package/src/index.ts +30 -2
- package/src/llm/native-worker/dispatcher.ts +2 -0
- package/src/llm/native-worker/embedding-identity.ts +42 -0
- package/src/llm/native-worker/protocol.ts +1 -0
- package/src/llm/types.ts +3 -0
- package/src/mcp/context.ts +17 -0
- package/src/mcp/http-egress.ts +4 -0
- package/src/mcp/http-transport.ts +2 -0
- package/src/mcp/resources/index.ts +6 -5
- package/src/mcp/tool-descriptions-core.ts +1 -1
- package/src/mcp/tools/capture.ts +87 -85
- package/src/mcp/tools/index.ts +77 -4
- package/src/mcp/tools/memory-remember.ts +8 -1
- package/src/mcp/tools/memory-shared.ts +7 -1
- package/src/mcp/tools/request-status.ts +73 -0
- package/src/mcp/tools/sessions.ts +208 -0
- package/src/mcp/tools/status.ts +4 -0
- package/src/pipeline/hybrid.ts +37 -7
- package/src/pipeline/vsearch.ts +14 -2
- package/src/sdk/client.ts +180 -84
- package/src/sdk/index.ts +6 -0
- package/src/sdk/types.ts +54 -2
- package/src/serve/capture-service.ts +98 -32
- package/src/serve/config-sync.ts +3 -2
- package/src/serve/embed-scheduler.ts +133 -19
- package/src/serve/host-path-redaction.ts +79 -0
- package/src/serve/public/app.tsx +4 -1
- package/src/serve/public/components/CaptureModal.tsx +26 -8
- package/src/serve/public/components/sessions/AutomationPanel.tsx +800 -0
- package/src/serve/public/components/sessions/ImportReceipt.tsx +238 -0
- package/src/serve/public/components/sessions/SessionSearch.tsx +286 -0
- package/src/serve/public/components/sessions/SourcesPanel.tsx +541 -0
- package/src/serve/public/components/sessions/api.ts +40 -0
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/hooks/use-api.ts +26 -3
- package/src/serve/public/lib/request-intent.ts +77 -0
- package/src/serve/public/lib/snippet.tsx +52 -0
- package/src/serve/public/lib/workspace-actions.ts +12 -1
- package/src/serve/public/lib/workspace-tabs.ts +2 -0
- package/src/serve/public/pages/Dashboard.tsx +22 -9
- package/src/serve/public/pages/DocView.tsx +25 -6
- package/src/serve/public/pages/DocumentEditor.tsx +224 -104
- package/src/serve/public/pages/Search.tsx +1 -41
- package/src/serve/public/pages/Sessions.tsx +350 -0
- package/src/serve/resident-runtime.ts +69 -4
- package/src/serve/resident-status.ts +13 -1
- package/src/serve/routes/api.ts +476 -147
- package/src/serve/routes/sessions.ts +766 -0
- package/src/serve/security.ts +9 -0
- package/src/serve/server.ts +215 -10
- package/src/serve/session-automation.ts +146 -0
- package/src/serve/status-model.ts +16 -0
- package/src/serve/status.ts +2 -0
- package/src/serve/watch-reconciliation-shared.ts +3 -0
- package/src/serve/watch-service-events.ts +3 -2
- package/src/serve/watch-service-run-flush.ts +35 -2
- package/src/serve/watch-service.ts +5 -0
- package/src/sessions/archive.ts +348 -0
- package/src/sessions/automation-state.ts +444 -0
- package/src/sessions/automation-status.ts +239 -0
- package/src/sessions/automation.ts +1169 -0
- package/src/sessions/binding.ts +105 -0
- package/src/sessions/claude-hook.ts +240 -0
- package/src/sessions/config.ts +176 -0
- package/src/sessions/format.ts +191 -0
- package/src/sessions/import-child-env.ts +8 -0
- package/src/sessions/import-child.ts +152 -0
- package/src/sessions/parsers/claude-code.ts +259 -0
- package/src/sessions/parsers/codex.ts +303 -0
- package/src/sessions/parsers/hermes.ts +248 -0
- package/src/sessions/parsers/openclaw.ts +496 -0
- package/src/sessions/parsers/shared.ts +184 -0
- package/src/sessions/sanitize.ts +222 -0
- package/src/sessions/service.ts +1533 -0
- package/src/sessions/setup.ts +477 -0
- package/src/sessions/sources.ts +518 -0
- package/src/sessions/state.ts +118 -0
- package/src/sessions/types.ts +457 -0
- package/src/store/migrations/031-runtime-independent-vectors.ts +29 -0
- package/src/store/migrations/032-vector-runtime-callers.ts +17 -0
- package/src/store/migrations/index.ts +4 -0
- package/src/store/sqlite/adapter.ts +76 -16
- package/src/store/sqlite/scoped-index.ts +9 -0
- package/src/store/types.ts +11 -1
- package/src/store/vector/lazy.ts +46 -43
- package/src/store/vector/runtime-compat.ts +651 -0
- package/src/store/vector/sqlite-vec.ts +20 -2
- package/src/store/vector/status.ts +276 -35
- package/src/store/vector/types.ts +2 -0
- package/src/store/vector/variant-search.ts +71 -23
- package/src/store/vector/variants.ts +49 -14
- package/browser-extension/artifacts/gno-browser-clipper-v2.5.1.zip.sha256 +0 -1
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret redaction applied before any session content is persisted.
|
|
3
|
+
*
|
|
4
|
+
* Detection is format-based (well-known credential shapes) plus
|
|
5
|
+
* owner-configured exact literals. Every pattern uses bounded, non-nested
|
|
6
|
+
* quantifiers so scanning stays linear in the input length; inputs are also
|
|
7
|
+
* bounded per turn by the caller. Redaction is best effort: it does not
|
|
8
|
+
* promise to find every secret or personal datum.
|
|
9
|
+
*
|
|
10
|
+
* A value detected anywhere in a thread is propagated: later exact
|
|
11
|
+
* occurrences of the same value in that thread are redacted too, even where
|
|
12
|
+
* the surrounding shape no longer matches.
|
|
13
|
+
*
|
|
14
|
+
* @module src/sessions/sanitize
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Bumped whenever a rule changes; stale archives are rescanned on import. */
|
|
18
|
+
export const SESSION_REDACTION_VERSION = 1;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Identity of the effective redaction policy: the rule version plus the
|
|
22
|
+
* owner's configured literals. Any change re-renders or rescans archives.
|
|
23
|
+
*/
|
|
24
|
+
export function redactionStamp(policy: RedactionPolicy = {}): string {
|
|
25
|
+
const literals = [...new Set(policy.literals ?? [])].sort();
|
|
26
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
27
|
+
hasher.update(JSON.stringify(literals));
|
|
28
|
+
return `${SESSION_REDACTION_VERSION}:${hasher.digest("hex").slice(0, 16)}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const MAX_PROPAGATED_VALUES = 256;
|
|
32
|
+
const MIN_PROPAGATED_LENGTH = 8;
|
|
33
|
+
const PRIVATE_KEY_WINDOW = 16 * 1024;
|
|
34
|
+
const PRIVATE_KEY_BEGIN = /-----BEGIN [A-Z0-9 ]{0,40}PRIVATE KEY-----/g;
|
|
35
|
+
const PRIVATE_KEY_END = /-----END [A-Z0-9 ]{0,40}PRIVATE KEY-----/;
|
|
36
|
+
|
|
37
|
+
interface Rule {
|
|
38
|
+
kind: string;
|
|
39
|
+
pattern: RegExp;
|
|
40
|
+
/** Capture group holding the secret; 0 means the whole match. */
|
|
41
|
+
group: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Every quantifier is bounded; no quantified group contains another quantifier.
|
|
45
|
+
const RULES: readonly Rule[] = [
|
|
46
|
+
{ kind: "aws-key", pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g, group: 0 },
|
|
47
|
+
{
|
|
48
|
+
kind: "github-token",
|
|
49
|
+
pattern:
|
|
50
|
+
/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{22,255})/g,
|
|
51
|
+
group: 0,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
kind: "api-key",
|
|
55
|
+
pattern: /\bsk-(?:ant-|proj-|live-|test-)?[A-Za-z0-9_-]{20,512}/g,
|
|
56
|
+
group: 0,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
kind: "stripe-key",
|
|
60
|
+
pattern: /\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{16,256}/g,
|
|
61
|
+
group: 0,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
kind: "slack-token",
|
|
65
|
+
pattern: /\bxox[abposr]-[A-Za-z0-9-]{10,256}/g,
|
|
66
|
+
group: 0,
|
|
67
|
+
},
|
|
68
|
+
{ kind: "google-key", pattern: /\bAIza[0-9A-Za-z_-]{35}/g, group: 0 },
|
|
69
|
+
{
|
|
70
|
+
kind: "jwt",
|
|
71
|
+
pattern:
|
|
72
|
+
/\beyJ[A-Za-z0-9_-]{8,4096}\.eyJ[A-Za-z0-9_-]{8,8192}\.[A-Za-z0-9_-]{8,4096}/g,
|
|
73
|
+
group: 0,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
kind: "bearer",
|
|
77
|
+
pattern: /\b(?:Bearer|Token)[ \t]{1,8}([A-Za-z0-9._~+/=-]{16,4096})/g,
|
|
78
|
+
group: 1,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
kind: "url-credentials",
|
|
82
|
+
pattern: /\b[a-z][a-z0-9+.-]{1,16}:\/\/[^\s:@/]{1,256}:([^\s@/]{1,256})@/gi,
|
|
83
|
+
group: 1,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
kind: "assignment",
|
|
87
|
+
pattern:
|
|
88
|
+
/\b(?:password|passwd|pwd|secret|api[_-]?key|apikey|access[_-]?token|auth[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key|token)["']?[ \t]{0,4}[:=][ \t]{0,4}["']?([^\s"'`,;]{6,512})/gi,
|
|
89
|
+
group: 1,
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const CONTROL_CHARS = new RegExp(
|
|
94
|
+
`[${String.fromCharCode(0)}-${String.fromCharCode(8)}${String.fromCharCode(11)}${String.fromCharCode(12)}${String.fromCharCode(14)}-${String.fromCharCode(31)}${String.fromCharCode(127)}]`,
|
|
95
|
+
"g"
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const PLACEHOLDER_VALUES = new Set([
|
|
99
|
+
"redacted",
|
|
100
|
+
"changeme",
|
|
101
|
+
"password",
|
|
102
|
+
"example",
|
|
103
|
+
"xxxxxx",
|
|
104
|
+
"********",
|
|
105
|
+
"<redacted>",
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
const marker = (kind: string): string => `[REDACTED:${kind}]`;
|
|
109
|
+
|
|
110
|
+
export interface RedactionPolicy {
|
|
111
|
+
/** Owner-configured exact literals (e.g. a known internal hostname or key). */
|
|
112
|
+
literals?: readonly string[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Per-thread sanitizer. Holds the values detected so far so later turns of
|
|
117
|
+
* the same thread redact them even out of their original shape.
|
|
118
|
+
*/
|
|
119
|
+
export class ThreadSanitizer {
|
|
120
|
+
private readonly literals: string[];
|
|
121
|
+
private readonly detected = new Set<string>();
|
|
122
|
+
redactions = 0;
|
|
123
|
+
|
|
124
|
+
constructor(policy: RedactionPolicy = {}) {
|
|
125
|
+
this.literals = [...new Set(policy.literals ?? [])]
|
|
126
|
+
.filter((value) => value.length >= 4)
|
|
127
|
+
.sort((left, right) => right.length - left.length);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Values detected so far (bounded); used for the propagation pass. */
|
|
131
|
+
get detectedValues(): readonly string[] {
|
|
132
|
+
return [...this.detected];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private remember(value: string): void {
|
|
136
|
+
if (
|
|
137
|
+
value.length >= MIN_PROPAGATED_LENGTH &&
|
|
138
|
+
this.detected.size < MAX_PROPAGATED_VALUES &&
|
|
139
|
+
!PLACEHOLDER_VALUES.has(value.toLowerCase())
|
|
140
|
+
) {
|
|
141
|
+
this.detected.add(value);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private replaceLiteral(text: string, literal: string, kind: string): string {
|
|
146
|
+
if (!text.includes(literal)) return text;
|
|
147
|
+
const parts = text.split(literal);
|
|
148
|
+
this.redactions += parts.length - 1;
|
|
149
|
+
return parts.join(marker(kind));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private redactPrivateKeys(text: string): string {
|
|
153
|
+
if (!text.includes("PRIVATE KEY-----")) return text;
|
|
154
|
+
let output = "";
|
|
155
|
+
let cursor = 0;
|
|
156
|
+
PRIVATE_KEY_BEGIN.lastIndex = 0;
|
|
157
|
+
for (;;) {
|
|
158
|
+
const begin = PRIVATE_KEY_BEGIN.exec(text);
|
|
159
|
+
if (!begin) break;
|
|
160
|
+
const window = text.slice(begin.index, begin.index + PRIVATE_KEY_WINDOW);
|
|
161
|
+
const end = PRIVATE_KEY_END.exec(window);
|
|
162
|
+
// An unterminated block is redacted to the end of its window.
|
|
163
|
+
const stop = end
|
|
164
|
+
? begin.index + end.index + end[0].length
|
|
165
|
+
: Math.min(text.length, begin.index + PRIVATE_KEY_WINDOW);
|
|
166
|
+
output += `${text.slice(cursor, begin.index)}${marker("private-key")}`;
|
|
167
|
+
this.redactions += 1;
|
|
168
|
+
cursor = stop;
|
|
169
|
+
PRIVATE_KEY_BEGIN.lastIndex = stop;
|
|
170
|
+
}
|
|
171
|
+
return output + text.slice(cursor);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Sanitize one field. Safe for titles, labels and metadata as well as bodies. */
|
|
175
|
+
sanitize(input: string): string {
|
|
176
|
+
let text = input.replace(CONTROL_CHARS, "");
|
|
177
|
+
text = this.redactPrivateKeys(text);
|
|
178
|
+
for (const rule of RULES) {
|
|
179
|
+
rule.pattern.lastIndex = 0;
|
|
180
|
+
text = text.replace(
|
|
181
|
+
rule.pattern,
|
|
182
|
+
(match: string, ...groups: unknown[]) => {
|
|
183
|
+
const secret =
|
|
184
|
+
rule.group === 0 ? match : (groups[rule.group - 1] as string);
|
|
185
|
+
if (!secret || PLACEHOLDER_VALUES.has(secret.toLowerCase())) {
|
|
186
|
+
return match;
|
|
187
|
+
}
|
|
188
|
+
if (secret.startsWith("[REDACTED:")) return match;
|
|
189
|
+
this.remember(secret);
|
|
190
|
+
this.redactions += 1;
|
|
191
|
+
return rule.group === 0
|
|
192
|
+
? marker(rule.kind)
|
|
193
|
+
: match.replace(secret, marker(rule.kind));
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
for (const literal of this.literals) {
|
|
198
|
+
text = this.replaceLiteral(text, literal, "configured");
|
|
199
|
+
}
|
|
200
|
+
return this.propagate(text);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Redact exact occurrences of every value detected so far. Run over the
|
|
205
|
+
* whole thread after the first pass so earlier turns are covered too.
|
|
206
|
+
*/
|
|
207
|
+
propagate(text: string): string {
|
|
208
|
+
let output = text;
|
|
209
|
+
for (const value of this.detected) {
|
|
210
|
+
output = this.replaceLiteral(output, value, "propagated");
|
|
211
|
+
}
|
|
212
|
+
return output;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Sanitize a single standalone value with a fresh per-call sanitizer. */
|
|
217
|
+
export function sanitizeValue(
|
|
218
|
+
value: string,
|
|
219
|
+
policy: RedactionPolicy = {}
|
|
220
|
+
): string {
|
|
221
|
+
return new ThreadSanitizer(policy).sanitize(value);
|
|
222
|
+
}
|