rehydra 0.13.0 → 0.15.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 +41 -3
- package/dist/browser.d.ts +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/cli/commands/anonymize.d.ts.map +1 -1
- package/dist/cli/commands/anonymize.js.map +1 -1
- package/dist/cli/utils/color.d.ts.map +1 -1
- package/dist/cli/utils/color.js +1 -0
- package/dist/cli/utils/color.js.map +1 -1
- package/dist/core/anonymizer.d.ts.map +1 -1
- package/dist/core/anonymizer.js +4 -1
- package/dist/core/anonymizer.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/opencode-plugin/git-identity.d.ts +3 -0
- package/dist/opencode-plugin/git-identity.d.ts.map +1 -0
- package/dist/opencode-plugin/git-identity.js +37 -0
- package/dist/opencode-plugin/git-identity.js.map +1 -0
- package/dist/opencode-plugin/github-username.d.ts +3 -0
- package/dist/opencode-plugin/github-username.d.ts.map +1 -0
- package/dist/opencode-plugin/github-username.js +41 -0
- package/dist/opencode-plugin/github-username.js.map +1 -0
- package/dist/opencode-plugin/identity-recognizer.d.ts +5 -0
- package/dist/opencode-plugin/identity-recognizer.d.ts.map +1 -0
- package/dist/opencode-plugin/identity-recognizer.js +21 -0
- package/dist/opencode-plugin/identity-recognizer.js.map +1 -0
- package/dist/opencode-plugin/index.d.ts +10 -1
- package/dist/opencode-plugin/index.d.ts.map +1 -1
- package/dist/opencode-plugin/index.js +32 -1
- package/dist/opencode-plugin/index.js.map +1 -1
- package/dist/opencode-plugin/plugin-v2.d.ts +92 -0
- package/dist/opencode-plugin/plugin-v2.d.ts.map +1 -0
- package/dist/opencode-plugin/plugin-v2.js +385 -0
- package/dist/opencode-plugin/plugin-v2.js.map +1 -0
- package/dist/opencode-plugin/plugin.d.ts +12 -3
- package/dist/opencode-plugin/plugin.d.ts.map +1 -1
- package/dist/opencode-plugin/plugin.js +102 -9
- package/dist/opencode-plugin/plugin.js.map +1 -1
- package/dist/opencode-plugin/types.d.ts +4 -1
- package/dist/opencode-plugin/types.d.ts.map +1 -1
- package/dist/opencode-plugin/vcs-command.d.ts +3 -0
- package/dist/opencode-plugin/vcs-command.d.ts.map +1 -0
- package/dist/opencode-plugin/vcs-command.js +34 -0
- package/dist/opencode-plugin/vcs-command.js.map +1 -0
- package/dist/pipeline/tagger.d.ts +6 -6
- package/dist/pipeline/tagger.d.ts.map +1 -1
- package/dist/pipeline/tagger.js +32 -11
- package/dist/pipeline/tagger.js.map +1 -1
- package/dist/pipeline/validator.d.ts.map +1 -1
- package/dist/pipeline/validator.js +8 -1
- package/dist/pipeline/validator.js.map +1 -1
- package/dist/proxy/providers/anthropic.d.ts +1 -0
- package/dist/proxy/providers/anthropic.d.ts.map +1 -1
- package/dist/proxy/providers/anthropic.js +2 -4
- package/dist/proxy/providers/anthropic.js.map +1 -1
- package/dist/proxy/providers/openai.d.ts +1 -0
- package/dist/proxy/providers/openai.d.ts.map +1 -1
- package/dist/proxy/providers/openai.js +3 -4
- package/dist/proxy/providers/openai.js.map +1 -1
- package/dist/proxy/providers/streaming-tool-loop.d.ts +12 -0
- package/dist/proxy/providers/streaming-tool-loop.d.ts.map +1 -0
- package/dist/proxy/providers/streaming-tool-loop.js +223 -0
- package/dist/proxy/providers/streaming-tool-loop.js.map +1 -0
- package/dist/proxy/providers/types.d.ts +3 -0
- package/dist/proxy/providers/types.d.ts.map +1 -1
- package/dist/proxy/providers/types.js +0 -4
- package/dist/proxy/providers/types.js.map +1 -1
- package/dist/proxy/rehydra-fetch.d.ts.map +1 -1
- package/dist/proxy/rehydra-fetch.js +68 -6
- package/dist/proxy/rehydra-fetch.js.map +1 -1
- package/dist/proxy/tool-loop-stream.d.ts +7 -0
- package/dist/proxy/tool-loop-stream.d.ts.map +1 -0
- package/dist/proxy/tool-loop-stream.js +65 -0
- package/dist/proxy/tool-loop-stream.js.map +1 -0
- package/dist/proxy/types.d.ts +6 -2
- package/dist/proxy/types.d.ts.map +1 -1
- package/dist/recognizers/address.d.ts +2 -0
- package/dist/recognizers/address.d.ts.map +1 -0
- package/dist/recognizers/address.js +23 -0
- package/dist/recognizers/address.js.map +1 -0
- package/dist/recognizers/custom-id.d.ts.map +1 -1
- package/dist/recognizers/custom-id.js +4 -2
- package/dist/recognizers/custom-id.js.map +1 -1
- package/dist/recognizers/index.d.ts +2 -0
- package/dist/recognizers/index.d.ts.map +1 -1
- package/dist/recognizers/index.js +6 -0
- package/dist/recognizers/index.js.map +1 -1
- package/dist/recognizers/postal-code.d.ts +16 -0
- package/dist/recognizers/postal-code.d.ts.map +1 -0
- package/dist/recognizers/postal-code.js +42 -0
- package/dist/recognizers/postal-code.js.map +1 -0
- package/dist/types/index.d.ts +15 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/pii-types.d.ts +2 -0
- package/dist/types/pii-types.d.ts.map +1 -1
- package/dist/types/pii-types.js +7 -0
- package/dist/types/pii-types.js.map +1 -1
- package/dist/utils/storage-node.d.ts +1 -0
- package/dist/utils/storage-node.d.ts.map +1 -1
- package/dist/utils/storage-node.js +22 -0
- package/dist/utils/storage-node.js.map +1 -1
- package/dist/utils/storage.d.ts +3 -0
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/storage.js.map +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rehydra OpenCode Plugin — OpenCode 2 (V2 plugin API) implementation.
|
|
3
|
+
*
|
|
4
|
+
* OpenCode 2 replaces the V1 hooks-object entrypoint with a plugin definition
|
|
5
|
+
* that exposes a stable `id` and registers hooks through a plugin context.
|
|
6
|
+
* Mapping from the V1 hooks:
|
|
7
|
+
*
|
|
8
|
+
* V1 hook V2 registration
|
|
9
|
+
* -------------------------------------- -----------------------------------------------------
|
|
10
|
+
* experimental.chat.messages.transform ctx.session.hook("context" | "compaction" | "generate" | "title")
|
|
11
|
+
* experimental.chat.system.transform same hooks — event.system.push({ type: "text", text })
|
|
12
|
+
* tool.execute.before ctx.tool.hook("execute.before") — mutate event.input in place
|
|
13
|
+
* tool.execute.after ctx.tool.hook("execute.after") — event.result / event.status
|
|
14
|
+
* experimental.text.complete no V2 equivalent (documented gap — see README)
|
|
15
|
+
* client.app.log console.* (captured by OpenCode's log service)
|
|
16
|
+
*
|
|
17
|
+
* The V2 session-request event shape (@opencode/ai SessionRequest) differs from
|
|
18
|
+
* V1: { sessionID, system, messages: Message[] } where each Message has a role
|
|
19
|
+
* and content parts. Text/reasoning parts carry `text`; tool-call parts carry
|
|
20
|
+
* `input`; tool-result parts carry `result`. Tool calls and results share the
|
|
21
|
+
* same `id` across messages, which is used to pair VCS commands with outputs.
|
|
22
|
+
*
|
|
23
|
+
* Registering the scrubber on all four session-request kinds also protects the
|
|
24
|
+
* session-title request, closing the V1 title leak (OpenCode issue #46115)
|
|
25
|
+
* without disabling the title agent.
|
|
26
|
+
*
|
|
27
|
+
* Structural types only: the plugin declares its own minimal shapes for the
|
|
28
|
+
* OpenCode plugin context, so there is no runtime (or build) dependency on
|
|
29
|
+
* OpenCode packages.
|
|
30
|
+
*/
|
|
31
|
+
import type { RehydraPluginOptions } from "./types.js";
|
|
32
|
+
/**
|
|
33
|
+
* The part of the OpenCode 2 plugin context this plugin uses. The real context
|
|
34
|
+
* (@opencode/plugin Context) satisfies this structurally.
|
|
35
|
+
*/
|
|
36
|
+
export interface RehydraV2PluginContext {
|
|
37
|
+
readonly app: {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly version: string;
|
|
40
|
+
};
|
|
41
|
+
readonly location: {
|
|
42
|
+
readonly directory: string;
|
|
43
|
+
readonly project?: unknown;
|
|
44
|
+
};
|
|
45
|
+
readonly options: Record<string, unknown>;
|
|
46
|
+
readonly session: {
|
|
47
|
+
hook(name: string, callback: (event: unknown) => void | Promise<void>): Promise<unknown>;
|
|
48
|
+
};
|
|
49
|
+
readonly tool: {
|
|
50
|
+
hook(name: string, callback: (event: unknown) => void | Promise<void>): Promise<unknown>;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export type RehydraCleanup = () => void | Promise<void>;
|
|
54
|
+
/** Default-exported plugin definition consumed by OpenCode 2. */
|
|
55
|
+
export interface RehydraV2Plugin {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly setup: (context: RehydraV2PluginContext) => Promise<RehydraCleanup | void>;
|
|
58
|
+
}
|
|
59
|
+
export declare function isVcsEnabled(options: RehydraPluginOptions | undefined): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Creates a Rehydra plugin definition for OpenCode 2.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```json
|
|
65
|
+
* // opencode.json — published npm package with default options
|
|
66
|
+
* { "plugins": ["@rehydra/opencode"] }
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```json
|
|
71
|
+
* // opencode.json — npm package with custom options
|
|
72
|
+
* {
|
|
73
|
+
* "plugins": [{
|
|
74
|
+
* "package": "@rehydra/opencode",
|
|
75
|
+
* "options": { "envFiles": [".env", ".env.local"] }
|
|
76
|
+
* }]
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* // .opencode/plugins/rehydra.ts — local plugin with custom options
|
|
83
|
+
* import { createRehydraPluginV2 } from "@rehydra/opencode";
|
|
84
|
+
* export default createRehydraPluginV2({
|
|
85
|
+
* envFiles: [".env", ".env.local"],
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function createRehydraPluginV2(options?: RehydraPluginOptions): RehydraV2Plugin;
|
|
90
|
+
declare const _default: RehydraV2Plugin;
|
|
91
|
+
export default _default;
|
|
92
|
+
//# sourceMappingURL=plugin-v2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-v2.d.ts","sourceRoot":"","sources":["../../src/opencode-plugin/plugin-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAeH,OAAO,KAAK,EAAe,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAwDpE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,GAAG,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE;QAChB,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACjD,OAAO,CAAC,OAAO,CAAC,CAAC;KACrB,CAAC;IACF,QAAQ,CAAC,IAAI,EAAE;QACb,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACjD,OAAO,CAAC,OAAO,CAAC,CAAC;KACrB,CAAC;CACH;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAExD,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,CACd,OAAO,EAAE,sBAAsB,KAC5B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACrC;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,oBAAoB,GAAG,SAAS,GACxC,OAAO,CAET;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,eAAe,CAyWjB;;AAED,wBAAuC"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rehydra OpenCode Plugin — OpenCode 2 (V2 plugin API) implementation.
|
|
3
|
+
*
|
|
4
|
+
* OpenCode 2 replaces the V1 hooks-object entrypoint with a plugin definition
|
|
5
|
+
* that exposes a stable `id` and registers hooks through a plugin context.
|
|
6
|
+
* Mapping from the V1 hooks:
|
|
7
|
+
*
|
|
8
|
+
* V1 hook V2 registration
|
|
9
|
+
* -------------------------------------- -----------------------------------------------------
|
|
10
|
+
* experimental.chat.messages.transform ctx.session.hook("context" | "compaction" | "generate" | "title")
|
|
11
|
+
* experimental.chat.system.transform same hooks — event.system.push({ type: "text", text })
|
|
12
|
+
* tool.execute.before ctx.tool.hook("execute.before") — mutate event.input in place
|
|
13
|
+
* tool.execute.after ctx.tool.hook("execute.after") — event.result / event.status
|
|
14
|
+
* experimental.text.complete no V2 equivalent (documented gap — see README)
|
|
15
|
+
* client.app.log console.* (captured by OpenCode's log service)
|
|
16
|
+
*
|
|
17
|
+
* The V2 session-request event shape (@opencode/ai SessionRequest) differs from
|
|
18
|
+
* V1: { sessionID, system, messages: Message[] } where each Message has a role
|
|
19
|
+
* and content parts. Text/reasoning parts carry `text`; tool-call parts carry
|
|
20
|
+
* `input`; tool-result parts carry `result`. Tool calls and results share the
|
|
21
|
+
* same `id` across messages, which is used to pair VCS commands with outputs.
|
|
22
|
+
*
|
|
23
|
+
* Registering the scrubber on all four session-request kinds also protects the
|
|
24
|
+
* session-title request, closing the V1 title leak (OpenCode issue #46115)
|
|
25
|
+
* without disabling the title agent.
|
|
26
|
+
*
|
|
27
|
+
* Structural types only: the plugin declares its own minimal shapes for the
|
|
28
|
+
* OpenCode plugin context, so there is no runtime (or build) dependency on
|
|
29
|
+
* OpenCode packages.
|
|
30
|
+
*/
|
|
31
|
+
/* eslint-disable no-console */
|
|
32
|
+
import { createAnonymizer } from "../core/anonymizer.js";
|
|
33
|
+
import { AnonymizerSessionImpl } from "../storage/session-base.js";
|
|
34
|
+
import { InMemoryPIIStorageProvider } from "../storage/in-memory.js";
|
|
35
|
+
import { InMemoryKeyProvider } from "../crypto/index.js";
|
|
36
|
+
import { PIIType, createDefaultPolicy, SECRET_PII_TYPES, DEFAULT_TAG_FORMAT, } from "../types/index.js";
|
|
37
|
+
import { buildPIISystemInstruction } from "../proxy/system-instruction.js";
|
|
38
|
+
import { buildTagPrefix } from "../utils/regex.js";
|
|
39
|
+
import { githubUsernameRecognizer } from "./github-username.js";
|
|
40
|
+
import { protectIdentityTags } from "./identity-recognizer.js";
|
|
41
|
+
import { vcsCommandTypes } from "./vcs-command.js";
|
|
42
|
+
import { gitIdentityRecognizer } from "./git-identity.js";
|
|
43
|
+
import { deepRehydrate } from "./plugin.js";
|
|
44
|
+
/** Session request kinds that can be hooked in OpenCode 2. */
|
|
45
|
+
const REQUEST_KINDS = [
|
|
46
|
+
"context",
|
|
47
|
+
"compaction",
|
|
48
|
+
"generate",
|
|
49
|
+
"title",
|
|
50
|
+
];
|
|
51
|
+
export function isVcsEnabled(options) {
|
|
52
|
+
return options?.vcsIdentities === true;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates a Rehydra plugin definition for OpenCode 2.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```json
|
|
59
|
+
* // opencode.json — published npm package with default options
|
|
60
|
+
* { "plugins": ["@rehydra/opencode"] }
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```json
|
|
65
|
+
* // opencode.json — npm package with custom options
|
|
66
|
+
* {
|
|
67
|
+
* "plugins": [{
|
|
68
|
+
* "package": "@rehydra/opencode",
|
|
69
|
+
* "options": { "envFiles": [".env", ".env.local"] }
|
|
70
|
+
* }]
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* // .opencode/plugins/rehydra.ts — local plugin with custom options
|
|
77
|
+
* import { createRehydraPluginV2 } from "@rehydra/opencode";
|
|
78
|
+
* export default createRehydraPluginV2({
|
|
79
|
+
* envFiles: [".env", ".env.local"],
|
|
80
|
+
* });
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export function createRehydraPluginV2(options) {
|
|
84
|
+
return {
|
|
85
|
+
id: "rehydra",
|
|
86
|
+
async setup(ctx) {
|
|
87
|
+
const SERVICE = "rehydra";
|
|
88
|
+
// OpenCode 2 removes client.app.log from the plugin context. Plain console
|
|
89
|
+
// output is captured by OpenCode's log service, so the structured
|
|
90
|
+
// "service=rehydra …" entries survive in the log directory.
|
|
91
|
+
function log(level, message, extra) {
|
|
92
|
+
const payload = {
|
|
93
|
+
service: SERVICE,
|
|
94
|
+
level,
|
|
95
|
+
message,
|
|
96
|
+
};
|
|
97
|
+
if (extra !== undefined) {
|
|
98
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
99
|
+
payload[key] = value;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (level === "error") {
|
|
103
|
+
console.error(payload);
|
|
104
|
+
}
|
|
105
|
+
else if (level === "warn") {
|
|
106
|
+
console.warn(payload);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
console.log(payload);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const keyProvider = new InMemoryKeyProvider();
|
|
113
|
+
const piiStorage = new InMemoryPIIStorageProvider();
|
|
114
|
+
// Factory options take precedence over options from opencode.json
|
|
115
|
+
// (ctx.options). Both feed the same RehydraPluginOptions shape.
|
|
116
|
+
const runtimeOptions = ctx.options;
|
|
117
|
+
const opts = {
|
|
118
|
+
...(runtimeOptions ?? {}),
|
|
119
|
+
...(options ?? {}),
|
|
120
|
+
};
|
|
121
|
+
// Build anonymizer config from options, sharing key and storage providers
|
|
122
|
+
const baseConfig = opts.anonymizer ?? {
|
|
123
|
+
secrets: {
|
|
124
|
+
enabled: true,
|
|
125
|
+
envFiles: opts.envFiles ?? ["**/.env*"],
|
|
126
|
+
redactValues: opts.redactValues,
|
|
127
|
+
minValueLength: opts.minValueLength,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
const anonymizerConfig = {
|
|
131
|
+
...baseConfig,
|
|
132
|
+
secrets: baseConfig.secrets === undefined
|
|
133
|
+
? undefined
|
|
134
|
+
: {
|
|
135
|
+
...baseConfig.secrets,
|
|
136
|
+
envBaseDirectory: baseConfig.secrets.envBaseDirectory ?? ctx.location.directory,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
const tagFormat = anonymizerConfig.tagFormat ?? opts.tagFormat ?? DEFAULT_TAG_FORMAT;
|
|
140
|
+
const tagPrefix = buildTagPrefix(tagFormat);
|
|
141
|
+
const rehydraInstruction = `<rehydra>\n${buildPIISystemInstruction(tagFormat)}\n</rehydra>`;
|
|
142
|
+
const anonymizer = createAnonymizer({
|
|
143
|
+
...anonymizerConfig,
|
|
144
|
+
tagFormat,
|
|
145
|
+
keyProvider,
|
|
146
|
+
piiStorageProvider: piiStorage,
|
|
147
|
+
});
|
|
148
|
+
if (opts.vcsIdentities === true) {
|
|
149
|
+
anonymizer
|
|
150
|
+
.getRegistry()
|
|
151
|
+
.register(protectIdentityTags(githubUsernameRecognizer, tagFormat));
|
|
152
|
+
anonymizer
|
|
153
|
+
.getRegistry()
|
|
154
|
+
.register(protectIdentityTags(gitIdentityRecognizer, tagFormat));
|
|
155
|
+
}
|
|
156
|
+
await anonymizer.initialize();
|
|
157
|
+
// Build policy with disabled types (URL and IP_ADDRESS disabled by default)
|
|
158
|
+
const disableTypes = opts.disableTypes ?? [
|
|
159
|
+
"URL",
|
|
160
|
+
"IP_ADDRESS",
|
|
161
|
+
];
|
|
162
|
+
let policy = opts.policy;
|
|
163
|
+
if (disableTypes.length > 0) {
|
|
164
|
+
const base = createDefaultPolicy();
|
|
165
|
+
const disableSet = new Set(disableTypes);
|
|
166
|
+
const regexEnabledTypes = new Set(base.regexEnabledTypes);
|
|
167
|
+
const nerEnabledTypes = new Set(base.nerEnabledTypes);
|
|
168
|
+
// createDefaultPolicy() excludes secret types (they're opt-in via
|
|
169
|
+
// AnonymizerConfig.secrets). Add them back so that passing this
|
|
170
|
+
// partial policy to mergePolicyWithBase doesn't accidentally drop
|
|
171
|
+
// the secret types the anonymizer added to its internal default.
|
|
172
|
+
for (const secretType of SECRET_PII_TYPES) {
|
|
173
|
+
regexEnabledTypes.add(secretType);
|
|
174
|
+
}
|
|
175
|
+
for (const t of disableSet) {
|
|
176
|
+
const piiType = t;
|
|
177
|
+
regexEnabledTypes.delete(piiType);
|
|
178
|
+
nerEnabledTypes.delete(piiType);
|
|
179
|
+
}
|
|
180
|
+
policy = {
|
|
181
|
+
...policy,
|
|
182
|
+
regexEnabledTypes,
|
|
183
|
+
nerEnabledTypes,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
log("info", "plugin initialized", {
|
|
187
|
+
envFiles: anonymizerConfig.secrets?.envFiles,
|
|
188
|
+
redactValueCount: opts.redactValues?.length ?? 0,
|
|
189
|
+
disableTypes,
|
|
190
|
+
opencode: `${ctx.app.name} ${ctx.app.version}`,
|
|
191
|
+
});
|
|
192
|
+
const locale = opts.locale;
|
|
193
|
+
const identityPolicy = (types) => {
|
|
194
|
+
const defaults = createDefaultPolicy();
|
|
195
|
+
const configPolicy = anonymizerConfig.defaultPolicy;
|
|
196
|
+
const enabledTypes = new Set(policy?.enabledTypes ??
|
|
197
|
+
configPolicy?.enabledTypes ??
|
|
198
|
+
defaults.enabledTypes);
|
|
199
|
+
const regexEnabledTypes = new Set(policy?.regexEnabledTypes ??
|
|
200
|
+
configPolicy?.regexEnabledTypes ??
|
|
201
|
+
defaults.regexEnabledTypes);
|
|
202
|
+
if (anonymizerConfig.secrets?.enabled === true) {
|
|
203
|
+
for (const type of SECRET_PII_TYPES) {
|
|
204
|
+
if (!disableTypes.includes(type)) {
|
|
205
|
+
enabledTypes.add(type);
|
|
206
|
+
regexEnabledTypes.add(type);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
for (const type of types) {
|
|
211
|
+
if (!disableTypes.includes(type)) {
|
|
212
|
+
enabledTypes.add(type);
|
|
213
|
+
regexEnabledTypes.add(type);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
...policy,
|
|
218
|
+
enabledTypes,
|
|
219
|
+
regexEnabledTypes,
|
|
220
|
+
reuseIdsForRepeatedPII: true,
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
// One session per OpenCode session, keyed by sessionID
|
|
224
|
+
const sessions = new Map();
|
|
225
|
+
function getSession(sessionID) {
|
|
226
|
+
let session = sessions.get(sessionID);
|
|
227
|
+
if (session === undefined) {
|
|
228
|
+
session = new AnonymizerSessionImpl(anonymizer, sessionID, piiStorage, keyProvider);
|
|
229
|
+
sessions.set(sessionID, session);
|
|
230
|
+
}
|
|
231
|
+
return session;
|
|
232
|
+
}
|
|
233
|
+
// Track whether any anonymization occurred (to conditionally inject instruction)
|
|
234
|
+
let hasAnonymized = false;
|
|
235
|
+
/**
|
|
236
|
+
* Scrubs one outgoing model request. OpenCode 2 delivers the same request
|
|
237
|
+
* shape to the `context` (agent loop), `compaction`, `generate`, and
|
|
238
|
+
* `title` session hooks, so one implementation covers every kind.
|
|
239
|
+
*/
|
|
240
|
+
async function scrubRequest(event) {
|
|
241
|
+
let totalScrubbed = 0;
|
|
242
|
+
const scrubbedByType = {};
|
|
243
|
+
const session = getSession(event.sessionID);
|
|
244
|
+
// VCS commands by tool-call id, captured before scrubbing so detection
|
|
245
|
+
// tokens survive anonymization. Tool results pair with their call by id.
|
|
246
|
+
const commandsByCallId = new Map();
|
|
247
|
+
// OpenCode retains the rehydrated arguments after tool execution and
|
|
248
|
+
// serializes them into later model requests. Copy and scrub values so
|
|
249
|
+
// the execution arguments and JSON property names stay intact.
|
|
250
|
+
const scrubValue = async (value, activePolicy) => {
|
|
251
|
+
if (typeof value === "string") {
|
|
252
|
+
const result = await session.anonymize(value, locale, activePolicy ?? policy);
|
|
253
|
+
if (result.stats.totalEntities > 0) {
|
|
254
|
+
hasAnonymized = true;
|
|
255
|
+
totalScrubbed += result.stats.totalEntities;
|
|
256
|
+
for (const [type, count] of Object.entries(result.stats.countsByType)) {
|
|
257
|
+
scrubbedByType[type] = (scrubbedByType[type] ?? 0) + count;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return result.anonymizedText;
|
|
261
|
+
}
|
|
262
|
+
if (Array.isArray(value)) {
|
|
263
|
+
const result = [];
|
|
264
|
+
for (const item of value)
|
|
265
|
+
result.push(await scrubValue(item, activePolicy));
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
if (value !== null && typeof value === "object") {
|
|
269
|
+
const entries = [];
|
|
270
|
+
for (const [key, item] of Object.entries(value)) {
|
|
271
|
+
entries.push([key, await scrubValue(item, activePolicy)]);
|
|
272
|
+
}
|
|
273
|
+
return Object.fromEntries(entries);
|
|
274
|
+
}
|
|
275
|
+
return value;
|
|
276
|
+
};
|
|
277
|
+
for (const msg of event.messages) {
|
|
278
|
+
const content = msg.content;
|
|
279
|
+
if (!Array.isArray(content))
|
|
280
|
+
continue;
|
|
281
|
+
for (const part of content) {
|
|
282
|
+
if (part.type === "tool-call") {
|
|
283
|
+
const rawInput = part.input;
|
|
284
|
+
if (isVcsEnabled(opts) &&
|
|
285
|
+
rawInput !== null &&
|
|
286
|
+
typeof rawInput === "object" &&
|
|
287
|
+
typeof rawInput.command ===
|
|
288
|
+
"string" &&
|
|
289
|
+
typeof part.id === "string") {
|
|
290
|
+
commandsByCallId.set(part.id, rawInput.command);
|
|
291
|
+
}
|
|
292
|
+
part.input = await scrubValue(part.input);
|
|
293
|
+
}
|
|
294
|
+
else if (part.type === "text" || part.type === "reasoning") {
|
|
295
|
+
if (typeof part.text === "string") {
|
|
296
|
+
part.text = (await scrubValue(part.text));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else if (part.type === "tool-result" &&
|
|
300
|
+
part.result !== undefined &&
|
|
301
|
+
part.result !== null) {
|
|
302
|
+
let outputPolicy;
|
|
303
|
+
if (isVcsEnabled(opts) &&
|
|
304
|
+
typeof part.id === "string" &&
|
|
305
|
+
commandsByCallId.has(part.id)) {
|
|
306
|
+
const command = commandsByCallId.get(part.id) ?? "";
|
|
307
|
+
const commands = vcsCommandTypes(command);
|
|
308
|
+
const types = [];
|
|
309
|
+
if (commands.has("github"))
|
|
310
|
+
types.push(PIIType.GITHUB_USERNAME);
|
|
311
|
+
if (commands.has("git"))
|
|
312
|
+
types.push(PIIType.PERSON);
|
|
313
|
+
if (types.length > 0)
|
|
314
|
+
outputPolicy = identityPolicy(types);
|
|
315
|
+
}
|
|
316
|
+
part.result = await scrubValue(part.result, outputPolicy);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (totalScrubbed > 0) {
|
|
321
|
+
// Only include types that actually had hits
|
|
322
|
+
const nonZero = {};
|
|
323
|
+
for (const [type, count] of Object.entries(scrubbedByType)) {
|
|
324
|
+
if (count > 0)
|
|
325
|
+
nonZero[type] = count;
|
|
326
|
+
}
|
|
327
|
+
log("info", `scrubbed ${totalScrubbed} secret(s) from messages`, {
|
|
328
|
+
scrubbed: nonZero,
|
|
329
|
+
messageCount: event.messages.length,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
log("debug", "no secrets found in messages", {
|
|
334
|
+
messageCount: event.messages.length,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
if (hasAnonymized) {
|
|
338
|
+
log("debug", "injected rehydra instruction into system prompt");
|
|
339
|
+
event.system.push({ type: "text", text: rehydraInstruction });
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Register the scrubber on every model-request kind OpenCode 2 can issue:
|
|
343
|
+
// agent loop, checkpoint compaction, transient generates, session titles.
|
|
344
|
+
for (const kind of REQUEST_KINDS) {
|
|
345
|
+
await ctx.session.hook(kind, (event) => scrubRequest(event));
|
|
346
|
+
}
|
|
347
|
+
await ctx.tool.hook("execute.before", async (event) => {
|
|
348
|
+
const toolEvent = event;
|
|
349
|
+
const session = getSession(toolEvent.sessionID);
|
|
350
|
+
const before = JSON.stringify(toolEvent.input);
|
|
351
|
+
toolEvent.input = await deepRehydrate(toolEvent.input, session, tagPrefix);
|
|
352
|
+
if (before !== JSON.stringify(toolEvent.input)) {
|
|
353
|
+
log("info", "rehydrated PII tags in tool args", {
|
|
354
|
+
tool: toolEvent.tool,
|
|
355
|
+
callID: toolEvent.id,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
// Result shape varies by tool type: native tools return their result
|
|
360
|
+
// object while MCP tools return the raw CallToolResult
|
|
361
|
+
// ({ content: [{type,text}], … }). deepRehydrate handles any shape.
|
|
362
|
+
await ctx.tool.hook("execute.after", async (event) => {
|
|
363
|
+
if (event.status === "error")
|
|
364
|
+
return;
|
|
365
|
+
const toolEvent = event;
|
|
366
|
+
const session = getSession(toolEvent.sessionID);
|
|
367
|
+
const before = JSON.stringify(toolEvent.result);
|
|
368
|
+
toolEvent.result = await deepRehydrate(toolEvent.result, session, tagPrefix);
|
|
369
|
+
if (JSON.stringify(toolEvent.result) !== before) {
|
|
370
|
+
log("info", "rehydrated PII tags in tool result", {
|
|
371
|
+
tool: toolEvent.tool,
|
|
372
|
+
callID: toolEvent.id,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
// Drop the PII maps when the plugin unloads.
|
|
377
|
+
return () => {
|
|
378
|
+
sessions.clear();
|
|
379
|
+
piiStorage.clear();
|
|
380
|
+
};
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
export default createRehydraPluginV2();
|
|
385
|
+
//# sourceMappingURL=plugin-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-v2.js","sourceRoot":"","sources":["../../src/opencode-plugin/plugin-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,+BAA+B;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,8DAA8D;AAC9D,MAAM,aAAa,GAA4D;IAC7E,SAAS;IACT,YAAY;IACZ,UAAU;IACV,OAAO;CACC,CAAC;AAyEX,MAAM,UAAU,YAAY,CAC1B,OAAyC;IAEzC,OAAO,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAA8B;IAE9B,OAAO;QACL,EAAE,EAAE,SAAS;QACb,KAAK,CAAC,KAAK,CAAC,GAAG;YACb,MAAM,OAAO,GAAG,SAAS,CAAC;YAE1B,2EAA2E;YAC3E,kEAAkE;YAClE,4DAA4D;YAC5D,SAAS,GAAG,CACV,KAA0C,EAC1C,OAAe,EACf,KAA+B;gBAE/B,MAAM,OAAO,GAA4B;oBACvC,OAAO,EAAE,OAAO;oBAChB,KAAK;oBACL,OAAO;iBACR,CAAC;gBACF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;wBACjD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;oBACvB,CAAC;gBACH,CAAC;gBACD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;oBACtB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzB,CAAC;qBAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;oBAC5B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,mBAAmB,EAAE,CAAC;YAC9C,MAAM,UAAU,GAAG,IAAI,0BAA0B,EAAE,CAAC;YAEpD,kEAAkE;YAClE,gEAAgE;YAChE,MAAM,cAAc,GAAG,GAAG,CAAC,OAA2C,CAAC;YACvE,MAAM,IAAI,GAAyB;gBACjC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;gBACzB,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;aACnB,CAAC;YAEF,0EAA0E;YAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI;gBACpC,OAAO,EAAE;oBACP,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC;oBACvC,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,cAAc,EAAE,IAAI,CAAC,cAAc;iBACpC;aACF,CAAC;YAEF,MAAM,gBAAgB,GAAG;gBACvB,GAAG,UAAU;gBACb,OAAO,EACL,UAAU,CAAC,OAAO,KAAK,SAAS;oBAC9B,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC;wBACE,GAAG,UAAU,CAAC,OAAO;wBACrB,gBAAgB,EACd,UAAU,CAAC,OAAO,CAAC,gBAAgB,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS;qBAChE;aACR,CAAC;YAEF,MAAM,SAAS,GACb,gBAAgB,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;YACrE,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;YAC5C,MAAM,kBAAkB,GAAG,cAAc,yBAAyB,CAAC,SAAS,CAAC,cAAc,CAAC;YAE5F,MAAM,UAAU,GAAG,gBAAgB,CAAC;gBAClC,GAAG,gBAAgB;gBACnB,SAAS;gBACT,WAAW;gBACX,kBAAkB,EAAE,UAAU;aAC/B,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;gBAChC,UAAU;qBACP,WAAW,EAAE;qBACb,QAAQ,CAAC,mBAAmB,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC,CAAC;gBACtE,UAAU;qBACP,WAAW,EAAE;qBACb,QAAQ,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC,CAAC;YACrE,CAAC;YACD,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC;YAE9B,4EAA4E;YAC5E,MAAM,YAAY,GAAkB,IAAI,CAAC,YAAY,IAAI;gBACvD,KAAK;gBACL,YAAY;aACb,CAAC;YACF,IAAI,MAAM,GAA6C,IAAI,CAAC,MAAM,CAAC;YACnE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;gBACnC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,YAAY,CAAC,CAAC;gBACjD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBAC1D,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBACtD,kEAAkE;gBAClE,iEAAiE;gBACjE,kEAAkE;gBAClE,iEAAiE;gBACjE,KAAK,MAAM,UAAU,IAAI,gBAAgB,EAAE,CAAC;oBAC1C,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACpC,CAAC;gBACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;oBAC3B,MAAM,OAAO,GAAG,CAAY,CAAC;oBAC7B,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBAClC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAClC,CAAC;gBACD,MAAM,GAAG;oBACP,GAAG,MAAM;oBACT,iBAAiB;oBACjB,eAAe;iBAChB,CAAC;YACJ,CAAC;YAED,GAAG,CAAC,MAAM,EAAE,oBAAoB,EAAE;gBAChC,QAAQ,EAAE,gBAAgB,CAAC,OAAO,EAAE,QAAQ;gBAC5C,gBAAgB,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC;gBAChD,YAAY;gBACZ,QAAQ,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE;aAC/C,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,MAAM,cAAc,GAAG,CACrB,KAAgB,EACc,EAAE;gBAChC,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;gBACvC,MAAM,YAAY,GAAG,gBAAgB,CAAC,aAAa,CAAC;gBACpD,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,MAAM,EAAE,YAAY;oBAClB,YAAY,EAAE,YAAY;oBAC1B,QAAQ,CAAC,YAAY,CACxB,CAAC;gBACF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAC/B,MAAM,EAAE,iBAAiB;oBACvB,YAAY,EAAE,iBAAiB;oBAC/B,QAAQ,CAAC,iBAAiB,CAC7B,CAAC;gBACF,IAAI,gBAAgB,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;oBAC/C,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;wBACpC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;4BACjC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;4BACvB,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;wBAC9B,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;wBACjC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;wBACvB,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC9B,CAAC;gBACH,CAAC;gBACD,OAAO;oBACL,GAAG,MAAM;oBACT,YAAY;oBACZ,iBAAiB;oBACjB,sBAAsB,EAAE,IAAI;iBAC7B,CAAC;YACJ,CAAC,CAAC;YAEF,uDAAuD;YACvD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiC,CAAC;YAE1D,SAAS,UAAU,CAAC,SAAiB;gBACnC,IAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,OAAO,GAAG,IAAI,qBAAqB,CACjC,UAAU,EACV,SAAS,EACT,UAAU,EACV,WAAW,CACZ,CAAC;oBACF,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC;YAED,iFAAiF;YACjF,IAAI,aAAa,GAAG,KAAK,CAAC;YAE1B;;;;eAIG;YACH,KAAK,UAAU,YAAY,CACzB,KAA8B;gBAE9B,IAAI,aAAa,GAAG,CAAC,CAAC;gBACtB,MAAM,cAAc,GAA2B,EAAE,CAAC;gBAClD,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBAE5C,uEAAuE;gBACvE,yEAAyE;gBACzE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;gBAEnD,qEAAqE;gBACrE,sEAAsE;gBACtE,+DAA+D;gBAC/D,MAAM,UAAU,GAAG,KAAK,EACtB,KAAc,EACd,YAA2C,EACzB,EAAE;oBACpB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;wBAC9B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CACpC,KAAK,EACL,MAAM,EACN,YAAY,IAAI,MAAM,CACvB,CAAC;wBACF,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;4BACnC,aAAa,GAAG,IAAI,CAAC;4BACrB,aAAa,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;4BAC5C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CACxC,MAAM,CAAC,KAAK,CAAC,YAAY,CAC1B,EAAE,CAAC;gCACF,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;4BAC7D,CAAC;wBACH,CAAC;wBACD,OAAO,MAAM,CAAC,cAAc,CAAC;oBAC/B,CAAC;oBACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;wBACzB,MAAM,MAAM,GAAc,EAAE,CAAC;wBAC7B,KAAK,MAAM,IAAI,IAAI,KAAK;4BACtB,MAAM,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;wBACpD,OAAO,MAAM,CAAC;oBAChB,CAAC;oBACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;wBAChD,MAAM,OAAO,GAA6B,EAAE,CAAC;wBAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;4BAChD,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;wBAC5D,CAAC;wBACD,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;oBACrC,CAAC;oBACD,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC;gBAEF,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACjC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;oBAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;wBAAE,SAAS;oBAEtC,KAAK,MAAM,IAAI,IAAI,OAA4B,EAAE,CAAC;wBAChD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;4BAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;4BAC5B,IACE,YAAY,CAAC,IAAI,CAAC;gCAClB,QAAQ,KAAK,IAAI;gCACjB,OAAO,QAAQ,KAAK,QAAQ;gCAC5B,OAAQ,QAAkC,CAAC,OAAO;oCAChD,QAAQ;gCACV,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAC3B,CAAC;gCACD,gBAAgB,CAAC,GAAG,CAClB,IAAI,CAAC,EAAE,EACN,QAAgC,CAAC,OAAO,CAC1C,CAAC;4BACJ,CAAC;4BACD,IAAI,CAAC,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wBAC5C,CAAC;6BAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;4BAC7D,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gCAClC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAW,CAAC;4BACtD,CAAC;wBACH,CAAC;6BAAM,IACL,IAAI,CAAC,IAAI,KAAK,aAAa;4BAC3B,IAAI,CAAC,MAAM,KAAK,SAAS;4BACzB,IAAI,CAAC,MAAM,KAAK,IAAI,EACpB,CAAC;4BACD,IAAI,YAAsD,CAAC;4BAC3D,IACE,YAAY,CAAC,IAAI,CAAC;gCAClB,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;gCAC3B,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAC7B,CAAC;gCACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;gCACpD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;gCAC1C,MAAM,KAAK,GAAc,EAAE,CAAC;gCAC5B,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;oCAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;gCAChE,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;oCAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gCACpD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;oCAAE,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;4BAC7D,CAAC;4BACD,IAAI,CAAC,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;wBAC5D,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;oBACtB,4CAA4C;oBAC5C,MAAM,OAAO,GAA2B,EAAE,CAAC;oBAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;wBAC3D,IAAI,KAAK,GAAG,CAAC;4BAAE,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;oBACvC,CAAC;oBACD,GAAG,CAAC,MAAM,EAAE,YAAY,aAAa,0BAA0B,EAAE;wBAC/D,QAAQ,EAAE,OAAO;wBACjB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;qBACpC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,OAAO,EAAE,8BAA8B,EAAE;wBAC3C,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;qBACpC,CAAC,CAAC;gBACL,CAAC;gBAED,IAAI,aAAa,EAAE,CAAC;oBAClB,GAAG,CAAC,OAAO,EAAE,iDAAiD,CAAC,CAAC;oBAChE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;YAED,0EAA0E;YAC1E,0EAA0E;YAC1E,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBACjC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CACrC,YAAY,CAAC,KAAgC,CAAC,CAC/C,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACpD,MAAM,SAAS,GAAG,KAAmC,CAAC;gBACtD,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC/C,SAAS,CAAC,KAAK,GAAG,MAAM,aAAa,CACnC,SAAS,CAAC,KAAK,EACf,OAAO,EACP,SAAS,CACV,CAAC;gBACF,IAAI,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/C,GAAG,CAAC,MAAM,EAAE,kCAAkC,EAAE;wBAC9C,IAAI,EAAE,SAAS,CAAC,IAAI;wBACpB,MAAM,EAAE,SAAS,CAAC,EAAE;qBACrB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,qEAAqE;YACrE,uDAAuD;YACvD,oEAAoE;YACpE,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACnD,IAAK,KAAmC,CAAC,MAAM,KAAK,OAAO;oBAAE,OAAO;gBACpE,MAAM,SAAS,GAAG,KAAkC,CAAC;gBACrD,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAChD,SAAS,CAAC,MAAM,GAAG,MAAM,aAAa,CACpC,SAAS,CAAC,MAAM,EAChB,OAAO,EACP,SAAS,CACV,CAAC;gBACF,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,MAAM,EAAE,CAAC;oBAChD,GAAG,CAAC,MAAM,EAAE,oCAAoC,EAAE;wBAChD,IAAI,EAAE,SAAS,CAAC,IAAI;wBACpB,MAAM,EAAE,SAAS,CAAC,EAAE;qBACrB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,6CAA6C;YAC7C,OAAO,GAAG,EAAE;gBACV,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACjB,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,eAAe,qBAAqB,EAAE,CAAC"}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* - tool.execute.before — rehydrate PII tags in tool args
|
|
11
11
|
* - experimental.text.complete — rehydrate PII tags in LLM response
|
|
12
12
|
*/
|
|
13
|
+
import { AnonymizerSessionImpl } from "../storage/session-base.js";
|
|
13
14
|
import type { RehydraPluginOptions } from "./types.js";
|
|
14
15
|
/**
|
|
15
16
|
* OpenCode Plugin types — matches signatures from @opencode-ai/plugin.
|
|
@@ -34,10 +35,18 @@ interface OpencodeClient {
|
|
|
34
35
|
};
|
|
35
36
|
[key: string]: unknown;
|
|
36
37
|
}
|
|
37
|
-
type Plugin = (input: PluginInput) => Promise<Hooks>;
|
|
38
|
+
type Plugin = (input: PluginInput, options?: Record<string, unknown>) => Promise<Hooks>;
|
|
38
39
|
interface Hooks {
|
|
39
40
|
[key: string]: unknown;
|
|
40
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Recursively rehydrate all string values containing PII tags.
|
|
44
|
+
* Returns a new value (for strings/arrays) or the same object mutated in-place
|
|
45
|
+
* (for plain objects). The in-place mutation is required because OpenCode's
|
|
46
|
+
* tool.execute.before hook uses the original args reference for execution —
|
|
47
|
+
* replacing the object wholesale has no effect.
|
|
48
|
+
*/
|
|
49
|
+
export declare function deepRehydrate(value: unknown, session: AnonymizerSessionImpl, tagPrefix: string): Promise<unknown>;
|
|
41
50
|
/**
|
|
42
51
|
* Creates a Rehydra plugin for OpenCode.
|
|
43
52
|
*
|
|
@@ -53,10 +62,10 @@ interface Hooks {
|
|
|
53
62
|
* @example
|
|
54
63
|
* ```json
|
|
55
64
|
* // opencode.json — when published as npm package
|
|
56
|
-
* { "plugin": ["@rehydra/opencode
|
|
65
|
+
* { "plugin": [["@rehydra/opencode", { "disableTypes": ["DATE"] }]] }
|
|
57
66
|
* ```
|
|
58
67
|
*/
|
|
59
|
-
export declare function createRehydraPlugin(
|
|
68
|
+
export declare function createRehydraPlugin(factoryOptions?: RehydraPluginOptions): Plugin;
|
|
60
69
|
declare const _default: Plugin;
|
|
61
70
|
export default _default;
|
|
62
71
|
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/opencode-plugin/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/opencode-plugin/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,OAAO,KAAK,EAAe,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQpE;;;GAGG;AACH,UAAU,WAAW;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,cAAc;IACtB,GAAG,EAAE;QACH,GAAG,CAAC,KAAK,EAAE;YACT,IAAI,EAAE;gBACJ,OAAO,EAAE,MAAM,CAAC;gBAChB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;gBAC3C,OAAO,EAAE,MAAM,CAAC;gBAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aACjC,CAAC;SACH,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACtB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;AAExF,UAAU,KAAK;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,qBAAqB,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAoUjF;;AAED,wBAAqC"}
|