@caupulican/pi-adaptative 0.85.8 → 0.86.2
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/CHANGELOG.md +42 -0
- package/dist/core/agent-paths.d.ts +6 -3
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +10 -3
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/agent-session.d.ts +5 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +19 -8
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +11 -5
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +34 -8
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/subagent-prompt.d.ts +3 -3
- package/dist/core/autonomy/subagent-prompt.js +9 -9
- package/dist/core/autonomy/subagent-prompt.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +10 -8
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +23 -13
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/bash-execution-controller.d.ts +4 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -1
- package/dist/core/bash-execution-controller.js +11 -4
- package/dist/core/bash-execution-controller.js.map +1 -1
- package/dist/core/bash-executor.d.ts +2 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +2 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/capability-contract.d.ts +1 -1
- package/dist/core/capability-contract.d.ts.map +1 -1
- package/dist/core/capability-contract.js +0 -1
- package/dist/core/capability-contract.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts +1 -0
- package/dist/core/default-tool-surface.d.ts.map +1 -1
- package/dist/core/default-tool-surface.js +3 -2
- package/dist/core/default-tool-surface.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +27 -8
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +191 -33
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-agent-control.d.ts +45 -6
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control.js +110 -13
- package/dist/core/delegation/worker-agent-control.js.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +177 -158
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts +23 -0
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -0
- package/dist/core/delegation/worker-authority-resolver.js +128 -0
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -0
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
- package/dist/core/delegation/worker-conversation-store.js +1 -1
- package/dist/core/delegation/worker-conversation-store.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +7 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +260 -87
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +25 -4
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js +90 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts +2 -0
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +22 -12
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +1 -0
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +4 -2
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts +0 -2
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +8 -35
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.js +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-runner.d.ts +6 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +20 -6
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +47 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.js +210 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -0
- package/dist/core/memory/providers/file-store.d.ts +2 -0
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +22 -20
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/models/runtime-process.d.ts.map +1 -1
- package/dist/core/models/runtime-process.js +5 -18
- package/dist/core/models/runtime-process.js.map +1 -1
- package/dist/core/orchestration/bounded-string-array.d.ts +11 -0
- package/dist/core/orchestration/bounded-string-array.d.ts.map +1 -0
- package/dist/core/orchestration/bounded-string-array.js +17 -0
- package/dist/core/orchestration/bounded-string-array.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +16 -0
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +38 -0
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +11 -3
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +0 -1
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +1 -0
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +3 -0
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +12 -10
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +94 -104
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts +2 -2
- package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.js +4 -1
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
- package/dist/core/orchestration/policy-compiler.d.ts.map +1 -1
- package/dist/core/orchestration/policy-compiler.js +8 -9
- package/dist/core/orchestration/policy-compiler.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +4 -10
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/task-runtime.d.ts +1 -0
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +58 -3
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +10 -17
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/risk-classifier.js +3 -3
- package/dist/core/risk-classifier.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +4 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +34 -15
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/secrets/bitwarden-credential-storage.d.ts +51 -0
- package/dist/core/secrets/bitwarden-credential-storage.d.ts.map +1 -0
- package/dist/core/secrets/bitwarden-credential-storage.js +345 -0
- package/dist/core/secrets/bitwarden-credential-storage.js.map +1 -0
- package/dist/core/secrets/credential-exposure-guard.d.ts +8 -4
- package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.js +30 -31
- package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
- package/dist/core/secrets/credential-manager.d.ts +109 -0
- package/dist/core/secrets/credential-manager.d.ts.map +1 -0
- package/dist/core/secrets/credential-manager.js +384 -0
- package/dist/core/secrets/credential-manager.js.map +1 -0
- package/dist/core/secrets/credential-project.d.ts +4 -0
- package/dist/core/secrets/credential-project.d.ts.map +1 -0
- package/dist/core/secrets/credential-project.js +145 -0
- package/dist/core/secrets/credential-project.js.map +1 -0
- package/dist/core/secrets/secret-dotenv.d.ts +1 -1
- package/dist/core/secrets/secret-dotenv.js +1 -1
- package/dist/core/secrets/secret-dotenv.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +9 -5
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tool-capability-policy.js +2 -2
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +29 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +179 -28
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/git-filter.d.ts +1 -0
- package/dist/core/tools/git-filter.d.ts.map +1 -1
- package/dist/core/tools/git-filter.js +1 -1
- package/dist/core/tools/git-filter.js.map +1 -1
- package/dist/core/tools/profile-writer.js +3 -3
- package/dist/core/tools/profile-writer.js.map +1 -1
- package/dist/core/tools/python.d.ts +2 -0
- package/dist/core/tools/python.d.ts.map +1 -1
- package/dist/core/tools/python.js +17 -12
- package/dist/core/tools/python.js.map +1 -1
- package/dist/core/tools/run-process.d.ts +2 -0
- package/dist/core/tools/run-process.d.ts.map +1 -1
- package/dist/core/tools/run-process.js +7 -3
- package/dist/core/tools/run-process.js.map +1 -1
- package/dist/core/tools/secret-store.d.ts +8 -18
- package/dist/core/tools/secret-store.d.ts.map +1 -1
- package/dist/core/tools/secret-store.js +83 -348
- package/dist/core/tools/secret-store.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +38 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +35 -14
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +26 -3
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/secret-menu-controller.d.ts +21 -0
- package/dist/modes/interactive/secret-menu-controller.d.ts.map +1 -0
- package/dist/modes/interactive/secret-menu-controller.js +276 -0
- package/dist/modes/interactive/secret-menu-controller.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +2 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +43 -48
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/zip-extractor.d.ts +8 -0
- package/dist/utils/zip-extractor.d.ts.map +1 -0
- package/dist/utils/zip-extractor.js +275 -0
- package/dist/utils/zip-extractor.js.map +1 -0
- package/docs/harness-architecture.md +34 -22
- package/docs/index.md +1 -1
- package/docs/resources.md +1 -1
- package/docs/settings.md +39 -103
- package/docs/usage.md +7 -5
- package/docs/worker-profiles.md +9 -7
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/dist/core/secrets/secret-vault-format.d.ts +0 -112
- package/dist/core/secrets/secret-vault-format.d.ts.map +0 -1
- package/dist/core/secrets/secret-vault-format.js +0 -396
- package/dist/core/secrets/secret-vault-format.js.map +0 -1
- package/dist/core/secrets/secret-vault.d.ts +0 -72
- package/dist/core/secrets/secret-vault.d.ts.map +0 -1
- package/dist/core/secrets/secret-vault.js +0 -663
- package/dist/core/secrets/secret-vault.js.map +0 -1
|
@@ -1,355 +1,90 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
|
-
import { ExtensionEditorComponent } from "../../modes/interactive/components/extension-editor.js";
|
|
3
2
|
import { defineTool } from "../extensions/types.js";
|
|
4
|
-
import {
|
|
5
|
-
import { MAX_VARIABLES_PER_PROFILE, SECRET_DESCRIPTION_MAX_CHARS, SECRET_PRINTABLE_METADATA_PATTERN, SECRET_PROFILE_ID_MAX_CHARS, SECRET_PROFILE_ID_PATTERN, SECRET_VARIABLE_NAME_MAX_CHARS, SECRET_VARIABLE_NAME_PATTERN, SecretVault, SecretVaultError, } from "../secrets/secret-vault.js";
|
|
3
|
+
import { CredentialManagerError, CredentialStorageError, } from "../secrets/credential-manager.js";
|
|
6
4
|
import { emptyOrchestrationCall, OrchestrationPanelComponent, } from "./orchestration-panel.js";
|
|
7
5
|
const secretStoreSchema = Type.Object({
|
|
8
|
-
action: Type.Union([
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Type.Literal("materialize"),
|
|
12
|
-
Type.Literal("remove"),
|
|
13
|
-
Type.Literal("lock"),
|
|
14
|
-
], { description: "Credential-management action." }),
|
|
6
|
+
action: Type.Union([Type.Literal("status"), Type.Literal("list"), Type.Literal("activate")], {
|
|
7
|
+
description: "Credential-use action. Credential mutation is owner-only through /secrets.",
|
|
8
|
+
}),
|
|
15
9
|
profile: Type.Optional(Type.String({
|
|
16
10
|
minLength: 1,
|
|
17
|
-
maxLength:
|
|
18
|
-
pattern:
|
|
19
|
-
description: "
|
|
20
|
-
})),
|
|
21
|
-
description: Type.Optional(Type.String({
|
|
22
|
-
minLength: 1,
|
|
23
|
-
maxLength: SECRET_DESCRIPTION_MAX_CHARS,
|
|
24
|
-
pattern: SECRET_PRINTABLE_METADATA_PATTERN,
|
|
25
|
-
description: "Non-secret profile description.",
|
|
26
|
-
})),
|
|
27
|
-
envFile: Type.Optional(Type.String({
|
|
28
|
-
minLength: 1,
|
|
29
|
-
maxLength: 512,
|
|
30
|
-
description: "Relative dotenv location inside the current workspace, such as .env, .env.local, or config/dev.env. Valid only for set.",
|
|
31
|
-
})),
|
|
32
|
-
variableNames: Type.Optional(Type.Array(Type.String({
|
|
33
|
-
minLength: 1,
|
|
34
|
-
maxLength: SECRET_VARIABLE_NAME_MAX_CHARS,
|
|
35
|
-
pattern: SECRET_VARIABLE_NAME_PATTERN,
|
|
36
|
-
}), {
|
|
37
|
-
minItems: 1,
|
|
38
|
-
maxItems: MAX_VARIABLES_PER_PROFILE,
|
|
39
|
-
description: "Specific variable names to remove. Omit to remove the whole profile.",
|
|
40
|
-
})),
|
|
41
|
-
scope: Type.Optional(Type.Union([Type.Literal("managed"), Type.Literal("workspace")], {
|
|
42
|
-
description: "Materialization target. workspace resolves the durable current-project binding; managed writes private Pi state.",
|
|
11
|
+
maxLength: 96,
|
|
12
|
+
pattern: "^[A-Za-z0-9][A-Za-z0-9._-]*$",
|
|
13
|
+
description: "Bound profile to activate. Omit when the project has exactly one bound profile.",
|
|
43
14
|
})),
|
|
44
15
|
}, { additionalProperties: false });
|
|
45
16
|
function result(details, text) {
|
|
46
17
|
return { content: [{ type: "text", text }], details };
|
|
47
18
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
19
|
+
function invalid(input) {
|
|
20
|
+
if (input.action !== "activate" && input.profile !== undefined) {
|
|
21
|
+
return result({
|
|
22
|
+
action: input.action,
|
|
23
|
+
status: "error",
|
|
24
|
+
code: "unexpected_profile",
|
|
25
|
+
message: `Action ${input.action} does not accept a profile.`,
|
|
26
|
+
}, `Secret store request is invalid: action ${input.action} does not accept a profile.`);
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
55
29
|
}
|
|
56
|
-
function
|
|
57
|
-
|
|
30
|
+
function failed(input, error) {
|
|
31
|
+
const known = error instanceof CredentialManagerError || error instanceof CredentialStorageError;
|
|
32
|
+
const code = known ? error.code : "safe_failure";
|
|
33
|
+
const message = known ? error.message : "Credential activation failed safely without exposing values.";
|
|
34
|
+
const status = ["owner_setup_required", "not_connected", "provider_unavailable"].includes(code)
|
|
35
|
+
? "unavailable"
|
|
36
|
+
: "error";
|
|
37
|
+
return result({
|
|
38
|
+
action: input.action,
|
|
39
|
+
status,
|
|
40
|
+
...(input.profile ? { profile: input.profile } : {}),
|
|
41
|
+
code,
|
|
42
|
+
message,
|
|
43
|
+
}, `Credential action failed: ${message}`);
|
|
58
44
|
}
|
|
59
45
|
function panelModel(details, expanded) {
|
|
60
46
|
if (!details)
|
|
61
|
-
return { label: "secrets", status: "error", emptyText: "No
|
|
62
|
-
const success = ["
|
|
63
|
-
const rows = expanded
|
|
64
|
-
? (details.profiles ?? []).map((profile) => ({
|
|
65
|
-
status: "info",
|
|
66
|
-
label: profile.profile,
|
|
67
|
-
meta: [
|
|
68
|
-
`${profile.variableNames.length} variable${profile.variableNames.length === 1 ? "" : "s"}`,
|
|
69
|
-
`${profile.bindings.length} binding${profile.bindings.length === 1 ? "" : "s"}`,
|
|
70
|
-
],
|
|
71
|
-
details: [
|
|
72
|
-
...(profile.description ? [profile.description] : []),
|
|
73
|
-
...profile.bindings.map((binding) => `${binding.envFile} · ${binding.workspace}`),
|
|
74
|
-
],
|
|
75
|
-
}))
|
|
76
|
-
: undefined;
|
|
47
|
+
return { label: "secrets", status: "error", emptyText: "No credential result was retained." };
|
|
48
|
+
const success = ["activated", "available", "listed"].includes(details.status);
|
|
77
49
|
return {
|
|
78
50
|
label: "secrets",
|
|
79
51
|
action: details.status,
|
|
80
52
|
status: success ? "success" : details.status === "cancelled" ? "warning" : "error",
|
|
81
53
|
summary: [
|
|
82
54
|
details.profile,
|
|
83
|
-
details.
|
|
84
|
-
details.scope,
|
|
55
|
+
details.project,
|
|
85
56
|
details.variableNames
|
|
86
57
|
? `${details.variableNames.length} variable${details.variableNames.length === 1 ? "" : "s"}`
|
|
87
58
|
: undefined,
|
|
88
59
|
details.profiles ? `${details.profiles.length} profile${details.profiles.length === 1 ? "" : "s"}` : undefined,
|
|
89
60
|
].filter((value) => value !== undefined),
|
|
90
|
-
rows
|
|
61
|
+
rows: expanded
|
|
62
|
+
? details.profiles?.map((profile) => ({
|
|
63
|
+
status: profile.boundToCurrentProject ? "succeeded" : "info",
|
|
64
|
+
label: profile.profile,
|
|
65
|
+
meta: [
|
|
66
|
+
`${profile.variableNames.length} variable${profile.variableNames.length === 1 ? "" : "s"}`,
|
|
67
|
+
profile.boundToCurrentProject ? "bound here" : "not bound here",
|
|
68
|
+
],
|
|
69
|
+
details: profile.description ? [profile.description] : undefined,
|
|
70
|
+
}))
|
|
71
|
+
: undefined,
|
|
91
72
|
notices: expanded && details.message ? [{ status: success ? "info" : "error", text: details.message }] : undefined,
|
|
92
73
|
};
|
|
93
74
|
}
|
|
94
|
-
async function ensureUnlocked(vault, action, ctx, signal, profile) {
|
|
95
|
-
if (vault.isUnlocked)
|
|
96
|
-
return undefined;
|
|
97
|
-
if (await vault.exists()) {
|
|
98
|
-
while (!signal?.aborted) {
|
|
99
|
-
let passphrase = await ctx.ui.input("Unlock secret vault", "Master passphrase", {
|
|
100
|
-
signal,
|
|
101
|
-
sensitive: true,
|
|
102
|
-
});
|
|
103
|
-
if (passphrase === undefined || signal?.aborted)
|
|
104
|
-
return cancelled(action, profile);
|
|
105
|
-
try {
|
|
106
|
-
await vault.unlock(passphrase);
|
|
107
|
-
return undefined;
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
if (error instanceof SecretVaultError && ["invalid_passphrase", "unlock_failed"].includes(error.code)) {
|
|
111
|
-
ctx.ui.notify(error.message, "error");
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
return failed(action, error, profile);
|
|
115
|
-
}
|
|
116
|
-
finally {
|
|
117
|
-
passphrase = "";
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return cancelled(action, profile);
|
|
121
|
-
}
|
|
122
|
-
while (!signal?.aborted) {
|
|
123
|
-
let passphrase = await ctx.ui.input("Create secret vault", "New master passphrase", { signal, sensitive: true });
|
|
124
|
-
if (passphrase === undefined || signal?.aborted)
|
|
125
|
-
return cancelled(action, profile);
|
|
126
|
-
let confirmation = await ctx.ui.input("Confirm secret vault", "Repeat master passphrase", {
|
|
127
|
-
signal,
|
|
128
|
-
sensitive: true,
|
|
129
|
-
});
|
|
130
|
-
if (confirmation === undefined || signal?.aborted) {
|
|
131
|
-
passphrase = "";
|
|
132
|
-
return cancelled(action, profile);
|
|
133
|
-
}
|
|
134
|
-
try {
|
|
135
|
-
if (passphrase !== confirmation) {
|
|
136
|
-
ctx.ui.notify("The two master passphrases do not match.", "error");
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
await vault.initialize(passphrase);
|
|
140
|
-
return undefined;
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
if (error instanceof SecretVaultError && error.code === "invalid_passphrase") {
|
|
144
|
-
ctx.ui.notify(error.message, "error");
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
return failed(action, error, profile);
|
|
148
|
-
}
|
|
149
|
-
finally {
|
|
150
|
-
passphrase = "";
|
|
151
|
-
confirmation = "";
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return cancelled(action, profile);
|
|
155
|
-
}
|
|
156
|
-
function validateInput(input) {
|
|
157
|
-
if (input.action === "lock" || input.action === "list") {
|
|
158
|
-
if (input.profile !== undefined ||
|
|
159
|
-
input.description !== undefined ||
|
|
160
|
-
input.envFile !== undefined ||
|
|
161
|
-
input.variableNames !== undefined ||
|
|
162
|
-
input.scope !== undefined) {
|
|
163
|
-
return invalid(input.action, "unexpected_fields", `Action ${input.action} does not accept profile fields.`);
|
|
164
|
-
}
|
|
165
|
-
return undefined;
|
|
166
|
-
}
|
|
167
|
-
if (input.action === "set" && !input.profile) {
|
|
168
|
-
return invalid(input.action, "profile_required", "Action set requires a profile.");
|
|
169
|
-
}
|
|
170
|
-
if (input.action === "remove" && !input.profile) {
|
|
171
|
-
return invalid(input.action, "profile_required", "Action remove requires a profile.");
|
|
172
|
-
}
|
|
173
|
-
if (input.action !== "set" && (input.description !== undefined || input.envFile !== undefined)) {
|
|
174
|
-
return invalid(input.action, "unexpected_profile_fields", "description and envFile are valid only for set.", input.profile);
|
|
175
|
-
}
|
|
176
|
-
if (input.action !== "remove" && input.variableNames !== undefined) {
|
|
177
|
-
return invalid(input.action, "unexpected_variable_names", "variableNames is valid only for remove.", input.profile);
|
|
178
|
-
}
|
|
179
|
-
if (input.action !== "materialize" && input.scope !== undefined) {
|
|
180
|
-
return invalid(input.action, "unexpected_scope", "scope is valid only for materialize.", input.profile);
|
|
181
|
-
}
|
|
182
|
-
if (input.variableNames && new Set(input.variableNames).size !== input.variableNames.length) {
|
|
183
|
-
return invalid(input.action, "duplicate_variables", "Variable names must be unique.", input.profile);
|
|
184
|
-
}
|
|
185
|
-
return undefined;
|
|
186
|
-
}
|
|
187
|
-
async function openPrivateDotenvEditor(ctx, title, prefill, signal) {
|
|
188
|
-
if (signal?.aborted)
|
|
189
|
-
return undefined;
|
|
190
|
-
try {
|
|
191
|
-
return await ctx.ui.custom((tui, _theme, keybindings, done) => new ExtensionEditorComponent(tui, keybindings, title, prefill, (value) => done(value), () => done(undefined), {
|
|
192
|
-
privateContent: true,
|
|
193
|
-
allowExternalEditor: false,
|
|
194
|
-
signal,
|
|
195
|
-
notice: "Private plaintext editor · content stays local and never enters model context",
|
|
196
|
-
}));
|
|
197
|
-
}
|
|
198
|
-
catch (error) {
|
|
199
|
-
if (signal?.aborted)
|
|
200
|
-
return undefined;
|
|
201
|
-
throw error;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
async function captureValidDotenv(ctx, title, prefill, signal) {
|
|
205
|
-
let draft = prefill;
|
|
206
|
-
while (!signal?.aborted) {
|
|
207
|
-
const edited = await openPrivateDotenvEditor(ctx, title, draft, signal);
|
|
208
|
-
if (edited === undefined || signal?.aborted)
|
|
209
|
-
return undefined;
|
|
210
|
-
try {
|
|
211
|
-
const parsed = parseDotenvDocument(edited);
|
|
212
|
-
const variableNames = parsed.variables.map((variable) => variable.name);
|
|
213
|
-
for (const variable of parsed.variables)
|
|
214
|
-
variable.value = "";
|
|
215
|
-
draft = "";
|
|
216
|
-
return { document: parsed.document, variableNames };
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
ctx.ui.notify(error instanceof SecretDotenvError ? error.message : "The dotenv document is invalid.", "error");
|
|
220
|
-
draft = edited;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return undefined;
|
|
224
|
-
}
|
|
225
|
-
async function executeSet(vault, input, ctx, signal) {
|
|
226
|
-
let document = "";
|
|
227
|
-
let originalUnmanagedContent;
|
|
228
|
-
try {
|
|
229
|
-
const target = vault.resolveBindingTarget(ctx.cwd, input.envFile ?? ".env");
|
|
230
|
-
const destinationState = await vault.inspectEnvDestination(target.destination, input.profile);
|
|
231
|
-
if (destinationState === "managed-other") {
|
|
232
|
-
return invalid(input.action, "destination_conflict", "The selected dotenv location is already managed by another profile.", input.profile);
|
|
233
|
-
}
|
|
234
|
-
const storedDocument = await vault.getProfileDocument(input.profile);
|
|
235
|
-
let prefill = storedDocument ?? "";
|
|
236
|
-
if (destinationState === "unmanaged") {
|
|
237
|
-
originalUnmanagedContent = await vault.readOwnerDotenv(target.destination);
|
|
238
|
-
prefill = originalUnmanagedContent;
|
|
239
|
-
}
|
|
240
|
-
if (destinationState === "managed-profile" && storedDocument === undefined) {
|
|
241
|
-
return invalid(input.action, "profile_missing", "The dotenv target claims this profile, but the encrypted profile is missing.", input.profile);
|
|
242
|
-
}
|
|
243
|
-
const captured = await captureValidDotenv(ctx, `Secrets · ${input.profile} → ${target.destination}`, prefill, signal);
|
|
244
|
-
prefill = "";
|
|
245
|
-
if (!captured)
|
|
246
|
-
return cancelled(input.action, input.profile);
|
|
247
|
-
document = captured.document;
|
|
248
|
-
await vault.replaceProfileDocument(input.profile, input.description, document, {
|
|
249
|
-
workspace: target.workspace,
|
|
250
|
-
envFile: target.envFile,
|
|
251
|
-
});
|
|
252
|
-
try {
|
|
253
|
-
await vault.materializeEnv(input.profile, target.destination, {
|
|
254
|
-
allowReplaceUnmanaged: destinationState === "unmanaged",
|
|
255
|
-
expectedUnmanagedContent: originalUnmanagedContent,
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
catch (error) {
|
|
259
|
-
const message = error instanceof SecretVaultError ? error.message : "Dotenv materialization failed safely.";
|
|
260
|
-
ctx.ui.notify(`Profile stored, but ${target.destination} was not refreshed: ${message}`, "warning");
|
|
261
|
-
return result({
|
|
262
|
-
action: input.action,
|
|
263
|
-
status: "stored",
|
|
264
|
-
profile: input.profile,
|
|
265
|
-
envFile: target.envFile,
|
|
266
|
-
variableNames: captured.variableNames,
|
|
267
|
-
materialized: false,
|
|
268
|
-
code: "materialization_failed",
|
|
269
|
-
message,
|
|
270
|
-
}, `Stored profile ${input.profile}, but its bound dotenv could not be refreshed. Retry secret_store materialize; no values were exposed.`);
|
|
271
|
-
}
|
|
272
|
-
ctx.ui.notify(`Credential profile ${input.profile} stored and activated at ${target.destination}`, "info");
|
|
273
|
-
return result({
|
|
274
|
-
action: input.action,
|
|
275
|
-
status: "stored",
|
|
276
|
-
profile: input.profile,
|
|
277
|
-
envFile: target.envFile,
|
|
278
|
-
variableNames: captured.variableNames,
|
|
279
|
-
materialized: true,
|
|
280
|
-
}, `Stored and activated ${captured.variableNames.length} variables for profile ${input.profile} at its bound workspace dotenv location. Values never entered model context.`);
|
|
281
|
-
}
|
|
282
|
-
catch (error) {
|
|
283
|
-
return failed(input.action, error, input.profile);
|
|
284
|
-
}
|
|
285
|
-
finally {
|
|
286
|
-
document = "";
|
|
287
|
-
originalUnmanagedContent = undefined;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
async function executeMaterialize(vault, input, ctx) {
|
|
291
|
-
try {
|
|
292
|
-
const scope = input.scope ?? "workspace";
|
|
293
|
-
const binding = await vault.resolveBindingForWorkspace(ctx.cwd, input.profile);
|
|
294
|
-
const destination = scope === "managed" ? vault.getManagedEnvPath(binding.profile) : binding.destination;
|
|
295
|
-
const destinationState = await vault.inspectEnvDestination(destination, binding.profile);
|
|
296
|
-
if (destinationState === "unmanaged" || destinationState === "managed-other") {
|
|
297
|
-
return invalid(input.action, "destination_conflict", "The bound dotenv location is no longer safely managed. Use set to review it in the private editor.", binding.profile);
|
|
298
|
-
}
|
|
299
|
-
const materialized = await vault.materializeEnv(binding.profile, destination, {
|
|
300
|
-
activationWorkspace: ctx.cwd,
|
|
301
|
-
managed: scope === "managed",
|
|
302
|
-
});
|
|
303
|
-
ctx.ui.notify(`Credential profile ${binding.profile} activated at ${destination}`, "info");
|
|
304
|
-
return result({
|
|
305
|
-
action: input.action,
|
|
306
|
-
status: "materialized",
|
|
307
|
-
profile: binding.profile,
|
|
308
|
-
variableNames: materialized.variableNames,
|
|
309
|
-
scope,
|
|
310
|
-
envFile: scope === "workspace" ? binding.envFile : undefined,
|
|
311
|
-
materialized: true,
|
|
312
|
-
}, `Activated profile ${binding.profile} for the current workspace. Its dotenv and process environment are available without exposing values to the model.`);
|
|
313
|
-
}
|
|
314
|
-
catch (error) {
|
|
315
|
-
return failed(input.action, error, input.profile);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
async function executeRemove(vault, input, ctx, signal) {
|
|
319
|
-
const target = input.variableNames?.length
|
|
320
|
-
? `${input.variableNames.join(", ")} from profile ${input.profile}`
|
|
321
|
-
: `the entire profile ${input.profile}`;
|
|
322
|
-
const approved = await ctx.ui.confirm("Remove stored secrets", `Remove ${target}? Pi-managed workspace and private dotenv copies are invalidated.`, { signal });
|
|
323
|
-
if (!approved || signal?.aborted)
|
|
324
|
-
return cancelled(input.action, input.profile);
|
|
325
|
-
try {
|
|
326
|
-
const removal = await vault.removeProfile(input.profile, input.variableNames);
|
|
327
|
-
return result({
|
|
328
|
-
action: input.action,
|
|
329
|
-
status: "removed",
|
|
330
|
-
profile: input.profile,
|
|
331
|
-
variableNames: removal.removedVariableNames,
|
|
332
|
-
}, `Removed ${removal.removedVariableNames.length} secret variable${removal.removedVariableNames.length === 1 ? "" : "s"} from profile ${input.profile}.`);
|
|
333
|
-
}
|
|
334
|
-
catch (error) {
|
|
335
|
-
return failed(input.action, error, input.profile);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
75
|
export function createSecretStoreToolDefinition(options) {
|
|
339
|
-
const
|
|
340
|
-
if (!vault)
|
|
341
|
-
throw new Error("secret_store requires an agentDir or SecretVault");
|
|
76
|
+
const { manager } = options;
|
|
342
77
|
return defineTool({
|
|
343
78
|
name: "secret_store",
|
|
344
79
|
label: "Secret Store",
|
|
345
|
-
description: "
|
|
346
|
-
promptSnippet: "
|
|
80
|
+
description: "Discover and activate owner-authorized Bitwarden credential profiles for the current project without exposing values.",
|
|
81
|
+
promptSnippet: "Activate project credentials with secret_store before credential-dependent commands. Credential setup and mutation are owner-only through /secrets.",
|
|
347
82
|
promptGuidelines: [
|
|
348
|
-
"Use secret_store
|
|
349
|
-
"
|
|
350
|
-
"
|
|
351
|
-
"After activation, run the consuming
|
|
352
|
-
"
|
|
83
|
+
"Use secret_store activate before credential-dependent work. It works in TUI, print, and RPC modes and returns metadata only.",
|
|
84
|
+
"Omit profile when the project has one binding. Use list to select among multiple authorized profiles.",
|
|
85
|
+
"Never ask the owner to paste a credential into chat or pass a value through tool arguments.",
|
|
86
|
+
"After activation, run the consuming command normally. Never print, inspect, grep, or echo credential environment values.",
|
|
87
|
+
"If owner_setup_required is returned, tell the owner to run /secrets in a TUI session. Do not repeatedly retry.",
|
|
353
88
|
],
|
|
354
89
|
parameters: secretStoreSchema,
|
|
355
90
|
executionMode: "sequential",
|
|
@@ -361,50 +96,50 @@ export function createSecretStoreToolDefinition(options) {
|
|
|
361
96
|
if (isPartial) {
|
|
362
97
|
return new OrchestrationPanelComponent(theme, {
|
|
363
98
|
label: "secrets",
|
|
364
|
-
action: "
|
|
99
|
+
action: "activating",
|
|
365
100
|
status: "running",
|
|
366
101
|
});
|
|
367
102
|
}
|
|
368
103
|
return new OrchestrationPanelComponent(theme, panelModel(toolResult.details, expanded), expanded);
|
|
369
104
|
},
|
|
370
105
|
async execute(_toolCallId, input, signal, _onUpdate, ctx) {
|
|
371
|
-
if (
|
|
372
|
-
return result({
|
|
373
|
-
action: input.action,
|
|
374
|
-
status: "unavailable",
|
|
375
|
-
...(input.profile ? { profile: input.profile } : {}),
|
|
376
|
-
code: "user_tui_required",
|
|
377
|
-
message: "Secret values can be captured only in a user-visible TUI session.",
|
|
378
|
-
}, "secret_store requires a user-visible TUI session.");
|
|
106
|
+
if (signal?.aborted) {
|
|
107
|
+
return result({ action: input.action, status: "cancelled", code: "cancelled" }, "Credential action cancelled.");
|
|
379
108
|
}
|
|
380
|
-
|
|
381
|
-
return cancelled(input.action, input.profile);
|
|
382
|
-
const validation = validateInput(input);
|
|
109
|
+
const validation = invalid(input);
|
|
383
110
|
if (validation)
|
|
384
111
|
return validation;
|
|
385
|
-
if (input.action === "lock") {
|
|
386
|
-
vault.lock();
|
|
387
|
-
return result({ action: input.action, status: "locked" }, "Secret vault locked; cached key, credential environment, and exact-value redaction cache were cleared.");
|
|
388
|
-
}
|
|
389
112
|
try {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
113
|
+
if (input.action === "status") {
|
|
114
|
+
const status = manager.status;
|
|
115
|
+
if (!status.sessionAvailable) {
|
|
116
|
+
return result({
|
|
117
|
+
action: input.action,
|
|
118
|
+
status: "unavailable",
|
|
119
|
+
connected: false,
|
|
120
|
+
code: "owner_setup_required",
|
|
121
|
+
message: "The owner must connect Bitwarden with /secrets.",
|
|
122
|
+
}, "Bitwarden owner setup is required. Run /secrets in a TUI session.");
|
|
123
|
+
}
|
|
124
|
+
return result({ action: input.action, status: "available", connected: status.connected }, status.connected
|
|
125
|
+
? "Bitwarden is connected for this Pi session."
|
|
126
|
+
: "A Bitwarden session key is available and will be validated on activation.");
|
|
396
127
|
}
|
|
397
|
-
if (input.action === "
|
|
398
|
-
|
|
128
|
+
if (input.action === "list") {
|
|
129
|
+
const profiles = await manager.listForProject(ctx.cwd, signal);
|
|
130
|
+
return result({ action: input.action, status: "listed", profiles }, `Found ${profiles.length} credential profile${profiles.length === 1 ? "" : "s"}; only metadata was returned.`);
|
|
399
131
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
132
|
+
const activated = await manager.activateForProject(ctx.cwd, input.profile, signal);
|
|
133
|
+
return result({
|
|
134
|
+
action: input.action,
|
|
135
|
+
status: "activated",
|
|
136
|
+
profile: activated.profile,
|
|
137
|
+
variableNames: activated.variableNames,
|
|
138
|
+
project: activated.project,
|
|
139
|
+
}, `Activated ${activated.profile} for ${activated.project}. Credential values remain hidden.`);
|
|
405
140
|
}
|
|
406
141
|
catch (error) {
|
|
407
|
-
return failed(input
|
|
142
|
+
return failed(input, error);
|
|
408
143
|
}
|
|
409
144
|
},
|
|
410
145
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-store.js","sourceRoot":"","sources":["../../../src/core/tools/secret-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport { ExtensionEditorComponent } from \"../../modes/interactive/components/extension-editor.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { defineTool, type ExtensionContext } from \"../extensions/types.ts\";\nimport { parseDotenvDocument, SecretDotenvError } from \"../secrets/secret-dotenv.ts\";\nimport {\n\tMAX_VARIABLES_PER_PROFILE,\n\tSECRET_DESCRIPTION_MAX_CHARS,\n\tSECRET_PRINTABLE_METADATA_PATTERN,\n\tSECRET_PROFILE_ID_MAX_CHARS,\n\tSECRET_PROFILE_ID_PATTERN,\n\tSECRET_VARIABLE_NAME_MAX_CHARS,\n\tSECRET_VARIABLE_NAME_PATTERN,\n\ttype SecretProfileSummary,\n\tSecretVault,\n\tSecretVaultError,\n} from \"../secrets/secret-vault.ts\";\nimport {\n\temptyOrchestrationCall,\n\tOrchestrationPanelComponent,\n\ttype OrchestrationPanelModel,\n} from \"./orchestration-panel.ts\";\n\nconst secretStoreSchema = Type.Object(\n\t{\n\t\taction: Type.Union(\n\t\t\t[\n\t\t\t\tType.Literal(\"set\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"materialize\"),\n\t\t\t\tType.Literal(\"remove\"),\n\t\t\t\tType.Literal(\"lock\"),\n\t\t\t],\n\t\t\t{ description: \"Credential-management action.\" },\n\t\t),\n\t\tprofile: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tminLength: 1,\n\t\t\t\tmaxLength: SECRET_PROFILE_ID_MAX_CHARS,\n\t\t\t\tpattern: SECRET_PROFILE_ID_PATTERN,\n\t\t\t\tdescription: \"Portable profile identifier, such as project-dev or aws-work.\",\n\t\t\t}),\n\t\t),\n\t\tdescription: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tminLength: 1,\n\t\t\t\tmaxLength: SECRET_DESCRIPTION_MAX_CHARS,\n\t\t\t\tpattern: SECRET_PRINTABLE_METADATA_PATTERN,\n\t\t\t\tdescription: \"Non-secret profile description.\",\n\t\t\t}),\n\t\t),\n\t\tenvFile: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tminLength: 1,\n\t\t\t\tmaxLength: 512,\n\t\t\t\tdescription:\n\t\t\t\t\t\"Relative dotenv location inside the current workspace, such as .env, .env.local, or config/dev.env. Valid only for set.\",\n\t\t\t}),\n\t\t),\n\t\tvariableNames: Type.Optional(\n\t\t\tType.Array(\n\t\t\t\tType.String({\n\t\t\t\t\tminLength: 1,\n\t\t\t\t\tmaxLength: SECRET_VARIABLE_NAME_MAX_CHARS,\n\t\t\t\t\tpattern: SECRET_VARIABLE_NAME_PATTERN,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\tminItems: 1,\n\t\t\t\t\tmaxItems: MAX_VARIABLES_PER_PROFILE,\n\t\t\t\t\tdescription: \"Specific variable names to remove. Omit to remove the whole profile.\",\n\t\t\t\t},\n\t\t\t),\n\t\t),\n\t\tscope: Type.Optional(\n\t\t\tType.Union([Type.Literal(\"managed\"), Type.Literal(\"workspace\")], {\n\t\t\t\tdescription:\n\t\t\t\t\t\"Materialization target. workspace resolves the durable current-project binding; managed writes private Pi state.\",\n\t\t\t}),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type SecretStoreToolInput = Static<typeof secretStoreSchema>;\n\nexport type SecretStoreStatus =\n\t| \"cancelled\"\n\t| \"error\"\n\t| \"listed\"\n\t| \"locked\"\n\t| \"materialized\"\n\t| \"removed\"\n\t| \"stored\"\n\t| \"unavailable\";\n\nexport interface SecretStoreToolDetails {\n\taction: SecretStoreToolInput[\"action\"];\n\tstatus: SecretStoreStatus;\n\tprofile?: string;\n\tvariableNames?: string[];\n\tprofiles?: SecretProfileSummary[];\n\tscope?: \"managed\" | \"workspace\";\n\tenvFile?: string;\n\tmaterialized?: boolean;\n\tcode?: string;\n\tmessage?: string;\n}\n\nexport interface SecretStoreToolOptions {\n\tagentDir?: string;\n\tvault?: SecretVault;\n}\n\ntype SecretStoreResult = {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: SecretStoreToolDetails;\n};\n\nfunction result(details: SecretStoreToolDetails, text: string): SecretStoreResult {\n\treturn { content: [{ type: \"text\", text }], details };\n}\n\nfunction cancelled(action: SecretStoreToolInput[\"action\"], profile?: string): SecretStoreResult {\n\treturn result(\n\t\t{ action, status: \"cancelled\", ...(profile ? { profile } : {}), code: \"owner_cancelled\" },\n\t\t\"Secret store action was cancelled by the owner.\",\n\t);\n}\n\nfunction failed(action: SecretStoreToolInput[\"action\"], error: unknown, profile?: string): SecretStoreResult {\n\tconst code = error instanceof SecretVaultError ? error.code : \"safe_failure\";\n\tconst message =\n\t\terror instanceof SecretVaultError ? error.message : \"Secret store failed safely without exposing values.\";\n\treturn result(\n\t\t{ action, status: \"error\", ...(profile ? { profile } : {}), code, message },\n\t\t`Secret store failed: ${message}`,\n\t);\n}\n\nfunction invalid(\n\taction: SecretStoreToolInput[\"action\"],\n\tcode: string,\n\tmessage: string,\n\tprofile?: string,\n): SecretStoreResult {\n\treturn result(\n\t\t{ action, status: \"error\", ...(profile ? { profile } : {}), code, message },\n\t\t`Secret store request is invalid: ${message}`,\n\t);\n}\n\nfunction panelModel(details: SecretStoreToolDetails | undefined, expanded: boolean): OrchestrationPanelModel {\n\tif (!details) return { label: \"secrets\", status: \"error\", emptyText: \"No secret-store result was retained.\" };\n\tconst success = [\"listed\", \"locked\", \"materialized\", \"removed\", \"stored\"].includes(details.status);\n\tconst rows = expanded\n\t\t? (details.profiles ?? []).map((profile) => ({\n\t\t\t\tstatus: \"info\" as const,\n\t\t\t\tlabel: profile.profile,\n\t\t\t\tmeta: [\n\t\t\t\t\t`${profile.variableNames.length} variable${profile.variableNames.length === 1 ? \"\" : \"s\"}`,\n\t\t\t\t\t`${profile.bindings.length} binding${profile.bindings.length === 1 ? \"\" : \"s\"}`,\n\t\t\t\t],\n\t\t\t\tdetails: [\n\t\t\t\t\t...(profile.description ? [profile.description] : []),\n\t\t\t\t\t...profile.bindings.map((binding) => `${binding.envFile} · ${binding.workspace}`),\n\t\t\t\t],\n\t\t\t}))\n\t\t: undefined;\n\treturn {\n\t\tlabel: \"secrets\",\n\t\taction: details.status,\n\t\tstatus: success ? \"success\" : details.status === \"cancelled\" ? \"warning\" : \"error\",\n\t\tsummary: [\n\t\t\tdetails.profile,\n\t\t\tdetails.envFile,\n\t\t\tdetails.scope,\n\t\t\tdetails.variableNames\n\t\t\t\t? `${details.variableNames.length} variable${details.variableNames.length === 1 ? \"\" : \"s\"}`\n\t\t\t\t: undefined,\n\t\t\tdetails.profiles ? `${details.profiles.length} profile${details.profiles.length === 1 ? \"\" : \"s\"}` : undefined,\n\t\t].filter((value): value is string => value !== undefined),\n\t\trows,\n\t\tnotices:\n\t\t\texpanded && details.message ? [{ status: success ? \"info\" : \"error\", text: details.message }] : undefined,\n\t};\n}\n\nasync function ensureUnlocked(\n\tvault: SecretVault,\n\taction: SecretStoreToolInput[\"action\"],\n\tctx: ExtensionContext,\n\tsignal: AbortSignal | undefined,\n\tprofile?: string,\n): Promise<SecretStoreResult | undefined> {\n\tif (vault.isUnlocked) return undefined;\n\tif (await vault.exists()) {\n\t\twhile (!signal?.aborted) {\n\t\t\tlet passphrase = await ctx.ui.input(\"Unlock secret vault\", \"Master passphrase\", {\n\t\t\t\tsignal,\n\t\t\t\tsensitive: true,\n\t\t\t});\n\t\t\tif (passphrase === undefined || signal?.aborted) return cancelled(action, profile);\n\t\t\ttry {\n\t\t\t\tawait vault.unlock(passphrase);\n\t\t\t\treturn undefined;\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof SecretVaultError && [\"invalid_passphrase\", \"unlock_failed\"].includes(error.code)) {\n\t\t\t\t\tctx.ui.notify(error.message, \"error\");\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\treturn failed(action, error, profile);\n\t\t\t} finally {\n\t\t\t\tpassphrase = \"\";\n\t\t\t}\n\t\t}\n\t\treturn cancelled(action, profile);\n\t}\n\n\twhile (!signal?.aborted) {\n\t\tlet passphrase = await ctx.ui.input(\"Create secret vault\", \"New master passphrase\", { signal, sensitive: true });\n\t\tif (passphrase === undefined || signal?.aborted) return cancelled(action, profile);\n\t\tlet confirmation = await ctx.ui.input(\"Confirm secret vault\", \"Repeat master passphrase\", {\n\t\t\tsignal,\n\t\t\tsensitive: true,\n\t\t});\n\t\tif (confirmation === undefined || signal?.aborted) {\n\t\t\tpassphrase = \"\";\n\t\t\treturn cancelled(action, profile);\n\t\t}\n\t\ttry {\n\t\t\tif (passphrase !== confirmation) {\n\t\t\t\tctx.ui.notify(\"The two master passphrases do not match.\", \"error\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait vault.initialize(passphrase);\n\t\t\treturn undefined;\n\t\t} catch (error) {\n\t\t\tif (error instanceof SecretVaultError && error.code === \"invalid_passphrase\") {\n\t\t\t\tctx.ui.notify(error.message, \"error\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn failed(action, error, profile);\n\t\t} finally {\n\t\t\tpassphrase = \"\";\n\t\t\tconfirmation = \"\";\n\t\t}\n\t}\n\treturn cancelled(action, profile);\n}\n\nfunction validateInput(input: SecretStoreToolInput): SecretStoreResult | undefined {\n\tif (input.action === \"lock\" || input.action === \"list\") {\n\t\tif (\n\t\t\tinput.profile !== undefined ||\n\t\t\tinput.description !== undefined ||\n\t\t\tinput.envFile !== undefined ||\n\t\t\tinput.variableNames !== undefined ||\n\t\t\tinput.scope !== undefined\n\t\t) {\n\t\t\treturn invalid(input.action, \"unexpected_fields\", `Action ${input.action} does not accept profile fields.`);\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (input.action === \"set\" && !input.profile) {\n\t\treturn invalid(input.action, \"profile_required\", \"Action set requires a profile.\");\n\t}\n\tif (input.action === \"remove\" && !input.profile) {\n\t\treturn invalid(input.action, \"profile_required\", \"Action remove requires a profile.\");\n\t}\n\tif (input.action !== \"set\" && (input.description !== undefined || input.envFile !== undefined)) {\n\t\treturn invalid(\n\t\t\tinput.action,\n\t\t\t\"unexpected_profile_fields\",\n\t\t\t\"description and envFile are valid only for set.\",\n\t\t\tinput.profile,\n\t\t);\n\t}\n\tif (input.action !== \"remove\" && input.variableNames !== undefined) {\n\t\treturn invalid(\n\t\t\tinput.action,\n\t\t\t\"unexpected_variable_names\",\n\t\t\t\"variableNames is valid only for remove.\",\n\t\t\tinput.profile,\n\t\t);\n\t}\n\tif (input.action !== \"materialize\" && input.scope !== undefined) {\n\t\treturn invalid(input.action, \"unexpected_scope\", \"scope is valid only for materialize.\", input.profile);\n\t}\n\tif (input.variableNames && new Set(input.variableNames).size !== input.variableNames.length) {\n\t\treturn invalid(input.action, \"duplicate_variables\", \"Variable names must be unique.\", input.profile);\n\t}\n\treturn undefined;\n}\n\nasync function openPrivateDotenvEditor(\n\tctx: ExtensionContext,\n\ttitle: string,\n\tprefill: string,\n\tsignal: AbortSignal | undefined,\n): Promise<string | undefined> {\n\tif (signal?.aborted) return undefined;\n\ttry {\n\t\treturn await ctx.ui.custom<string | undefined>(\n\t\t\t(tui, _theme, keybindings, done) =>\n\t\t\t\tnew ExtensionEditorComponent(\n\t\t\t\t\ttui,\n\t\t\t\t\tkeybindings,\n\t\t\t\t\ttitle,\n\t\t\t\t\tprefill,\n\t\t\t\t\t(value) => done(value),\n\t\t\t\t\t() => done(undefined),\n\t\t\t\t\t{\n\t\t\t\t\t\tprivateContent: true,\n\t\t\t\t\t\tallowExternalEditor: false,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tnotice: \"Private plaintext editor · content stays local and never enters model context\",\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t);\n\t} catch (error) {\n\t\tif (signal?.aborted) return undefined;\n\t\tthrow error;\n\t}\n}\n\nasync function captureValidDotenv(\n\tctx: ExtensionContext,\n\ttitle: string,\n\tprefill: string,\n\tsignal: AbortSignal | undefined,\n): Promise<{ document: string; variableNames: string[] } | undefined> {\n\tlet draft = prefill;\n\twhile (!signal?.aborted) {\n\t\tconst edited = await openPrivateDotenvEditor(ctx, title, draft, signal);\n\t\tif (edited === undefined || signal?.aborted) return undefined;\n\t\ttry {\n\t\t\tconst parsed = parseDotenvDocument(edited);\n\t\t\tconst variableNames = parsed.variables.map((variable) => variable.name);\n\t\t\tfor (const variable of parsed.variables) variable.value = \"\";\n\t\t\tdraft = \"\";\n\t\t\treturn { document: parsed.document, variableNames };\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(error instanceof SecretDotenvError ? error.message : \"The dotenv document is invalid.\", \"error\");\n\t\t\tdraft = edited;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nasync function executeSet(\n\tvault: SecretVault,\n\tinput: SecretStoreToolInput & { profile: string },\n\tctx: ExtensionContext,\n\tsignal: AbortSignal | undefined,\n): Promise<SecretStoreResult> {\n\tlet document = \"\";\n\tlet originalUnmanagedContent: string | undefined;\n\ttry {\n\t\tconst target = vault.resolveBindingTarget(ctx.cwd, input.envFile ?? \".env\");\n\t\tconst destinationState = await vault.inspectEnvDestination(target.destination, input.profile);\n\t\tif (destinationState === \"managed-other\") {\n\t\t\treturn invalid(\n\t\t\t\tinput.action,\n\t\t\t\t\"destination_conflict\",\n\t\t\t\t\"The selected dotenv location is already managed by another profile.\",\n\t\t\t\tinput.profile,\n\t\t\t);\n\t\t}\n\t\tconst storedDocument = await vault.getProfileDocument(input.profile);\n\t\tlet prefill = storedDocument ?? \"\";\n\t\tif (destinationState === \"unmanaged\") {\n\t\t\toriginalUnmanagedContent = await vault.readOwnerDotenv(target.destination);\n\t\t\tprefill = originalUnmanagedContent;\n\t\t}\n\t\tif (destinationState === \"managed-profile\" && storedDocument === undefined) {\n\t\t\treturn invalid(\n\t\t\t\tinput.action,\n\t\t\t\t\"profile_missing\",\n\t\t\t\t\"The dotenv target claims this profile, but the encrypted profile is missing.\",\n\t\t\t\tinput.profile,\n\t\t\t);\n\t\t}\n\n\t\tconst captured = await captureValidDotenv(\n\t\t\tctx,\n\t\t\t`Secrets · ${input.profile} → ${target.destination}`,\n\t\t\tprefill,\n\t\t\tsignal,\n\t\t);\n\t\tprefill = \"\";\n\t\tif (!captured) return cancelled(input.action, input.profile);\n\t\tdocument = captured.document;\n\t\tawait vault.replaceProfileDocument(input.profile, input.description, document, {\n\t\t\tworkspace: target.workspace,\n\t\t\tenvFile: target.envFile,\n\t\t});\n\t\ttry {\n\t\t\tawait vault.materializeEnv(input.profile, target.destination, {\n\t\t\t\tallowReplaceUnmanaged: destinationState === \"unmanaged\",\n\t\t\t\texpectedUnmanagedContent: originalUnmanagedContent,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof SecretVaultError ? error.message : \"Dotenv materialization failed safely.\";\n\t\t\tctx.ui.notify(`Profile stored, but ${target.destination} was not refreshed: ${message}`, \"warning\");\n\t\t\treturn result(\n\t\t\t\t{\n\t\t\t\t\taction: input.action,\n\t\t\t\t\tstatus: \"stored\",\n\t\t\t\t\tprofile: input.profile,\n\t\t\t\t\tenvFile: target.envFile,\n\t\t\t\t\tvariableNames: captured.variableNames,\n\t\t\t\t\tmaterialized: false,\n\t\t\t\t\tcode: \"materialization_failed\",\n\t\t\t\t\tmessage,\n\t\t\t\t},\n\t\t\t\t`Stored profile ${input.profile}, but its bound dotenv could not be refreshed. Retry secret_store materialize; no values were exposed.`,\n\t\t\t);\n\t\t}\n\t\tctx.ui.notify(`Credential profile ${input.profile} stored and activated at ${target.destination}`, \"info\");\n\t\treturn result(\n\t\t\t{\n\t\t\t\taction: input.action,\n\t\t\t\tstatus: \"stored\",\n\t\t\t\tprofile: input.profile,\n\t\t\t\tenvFile: target.envFile,\n\t\t\t\tvariableNames: captured.variableNames,\n\t\t\t\tmaterialized: true,\n\t\t\t},\n\t\t\t`Stored and activated ${captured.variableNames.length} variables for profile ${input.profile} at its bound workspace dotenv location. Values never entered model context.`,\n\t\t);\n\t} catch (error) {\n\t\treturn failed(input.action, error, input.profile);\n\t} finally {\n\t\tdocument = \"\";\n\t\toriginalUnmanagedContent = undefined;\n\t}\n}\n\nasync function executeMaterialize(\n\tvault: SecretVault,\n\tinput: SecretStoreToolInput,\n\tctx: ExtensionContext,\n): Promise<SecretStoreResult> {\n\ttry {\n\t\tconst scope = input.scope ?? \"workspace\";\n\t\tconst binding = await vault.resolveBindingForWorkspace(ctx.cwd, input.profile);\n\t\tconst destination = scope === \"managed\" ? vault.getManagedEnvPath(binding.profile) : binding.destination;\n\t\tconst destinationState = await vault.inspectEnvDestination(destination, binding.profile);\n\t\tif (destinationState === \"unmanaged\" || destinationState === \"managed-other\") {\n\t\t\treturn invalid(\n\t\t\t\tinput.action,\n\t\t\t\t\"destination_conflict\",\n\t\t\t\t\"The bound dotenv location is no longer safely managed. Use set to review it in the private editor.\",\n\t\t\t\tbinding.profile,\n\t\t\t);\n\t\t}\n\t\tconst materialized = await vault.materializeEnv(binding.profile, destination, {\n\t\t\tactivationWorkspace: ctx.cwd,\n\t\t\tmanaged: scope === \"managed\",\n\t\t});\n\t\tctx.ui.notify(`Credential profile ${binding.profile} activated at ${destination}`, \"info\");\n\t\treturn result(\n\t\t\t{\n\t\t\t\taction: input.action,\n\t\t\t\tstatus: \"materialized\",\n\t\t\t\tprofile: binding.profile,\n\t\t\t\tvariableNames: materialized.variableNames,\n\t\t\t\tscope,\n\t\t\t\tenvFile: scope === \"workspace\" ? binding.envFile : undefined,\n\t\t\t\tmaterialized: true,\n\t\t\t},\n\t\t\t`Activated profile ${binding.profile} for the current workspace. Its dotenv and process environment are available without exposing values to the model.`,\n\t\t);\n\t} catch (error) {\n\t\treturn failed(input.action, error, input.profile);\n\t}\n}\n\nasync function executeRemove(\n\tvault: SecretVault,\n\tinput: SecretStoreToolInput & { profile: string },\n\tctx: ExtensionContext,\n\tsignal: AbortSignal | undefined,\n): Promise<SecretStoreResult> {\n\tconst target = input.variableNames?.length\n\t\t? `${input.variableNames.join(\", \")} from profile ${input.profile}`\n\t\t: `the entire profile ${input.profile}`;\n\tconst approved = await ctx.ui.confirm(\n\t\t\"Remove stored secrets\",\n\t\t`Remove ${target}? Pi-managed workspace and private dotenv copies are invalidated.`,\n\t\t{ signal },\n\t);\n\tif (!approved || signal?.aborted) return cancelled(input.action, input.profile);\n\ttry {\n\t\tconst removal = await vault.removeProfile(input.profile, input.variableNames);\n\t\treturn result(\n\t\t\t{\n\t\t\t\taction: input.action,\n\t\t\t\tstatus: \"removed\",\n\t\t\t\tprofile: input.profile,\n\t\t\t\tvariableNames: removal.removedVariableNames,\n\t\t\t},\n\t\t\t`Removed ${removal.removedVariableNames.length} secret variable${removal.removedVariableNames.length === 1 ? \"\" : \"s\"} from profile ${input.profile}.`,\n\t\t);\n\t} catch (error) {\n\t\treturn failed(input.action, error, input.profile);\n\t}\n}\n\nexport function createSecretStoreToolDefinition(options: SecretStoreToolOptions) {\n\tconst vault = options.vault ?? (options.agentDir ? SecretVault.forAgentDir(options.agentDir) : undefined);\n\tif (!vault) throw new Error(\"secret_store requires an agentDir or SecretVault\");\n\treturn defineTool<typeof secretStoreSchema, SecretStoreToolDetails>({\n\t\tname: \"secret_store\",\n\t\tlabel: \"Secret Store\",\n\t\tdescription:\n\t\t\t\"Open a model-blind native dotenv editor, encrypt owner credentials, bind profiles to workspace dotenv locations, and activate them for normal process use without returning values to the model.\",\n\t\tpromptSnippet:\n\t\t\t\"Manage credentials through the model-blind secret vault. Before credential-dependent work, materialize the current workspace binding; use set to open the owner's private dotenv editor.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use secret_store whenever credentials are needed. Never ask the owner to paste a secret into chat or place a value in tool arguments.\",\n\t\t\t\"Use set with a profile and relative envFile. The harness opens a private plaintext editor, persists the workspace binding, writes the dotenv, and activates the environment.\",\n\t\t\t\"Before credential-dependent commands in a later session, call materialize without a profile to resolve the current workspace binding. Use list only when selection or discovery is needed.\",\n\t\t\t\"After activation, run the consuming application normally. Never read, grep, print, echo, source, or otherwise inspect credential files or environment values.\",\n\t\t\t\"Treat cancellation as owner intent. Do not immediately repeat the same credential request.\",\n\t\t],\n\t\tparameters: secretStoreSchema,\n\t\texecutionMode: \"sequential\",\n\t\trenderShell: \"self\",\n\t\trenderCall() {\n\t\t\treturn emptyOrchestrationCall();\n\t\t},\n\t\trenderResult(toolResult, { expanded, isPartial }, theme: Theme) {\n\t\t\tif (isPartial) {\n\t\t\t\treturn new OrchestrationPanelComponent(theme, {\n\t\t\t\t\tlabel: \"secrets\",\n\t\t\t\t\taction: \"waiting for you\",\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn new OrchestrationPanelComponent(theme, panelModel(toolResult.details, expanded), expanded);\n\t\t},\n\t\tasync execute(_toolCallId, input, signal, _onUpdate, ctx) {\n\t\t\tif (!ctx.hasUI || ctx.mode !== \"tui\") {\n\t\t\t\treturn result(\n\t\t\t\t\t{\n\t\t\t\t\t\taction: input.action,\n\t\t\t\t\t\tstatus: \"unavailable\",\n\t\t\t\t\t\t...(input.profile ? { profile: input.profile } : {}),\n\t\t\t\t\t\tcode: \"user_tui_required\",\n\t\t\t\t\t\tmessage: \"Secret values can be captured only in a user-visible TUI session.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"secret_store requires a user-visible TUI session.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (signal?.aborted) return cancelled(input.action, input.profile);\n\t\t\tconst validation = validateInput(input);\n\t\t\tif (validation) return validation;\n\t\t\tif (input.action === \"lock\") {\n\t\t\t\tvault.lock();\n\t\t\t\treturn result(\n\t\t\t\t\t{ action: input.action, status: \"locked\" },\n\t\t\t\t\t\"Secret vault locked; cached key, credential environment, and exact-value redaction cache were cleared.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst unlockResult = await ensureUnlocked(vault, input.action, ctx, signal, input.profile);\n\t\t\t\tif (unlockResult) return unlockResult;\n\t\t\t\tif (input.action === \"list\") {\n\t\t\t\t\tconst profiles = await vault.listProfiles();\n\t\t\t\t\treturn result(\n\t\t\t\t\t\t{ action: input.action, status: \"listed\", profiles },\n\t\t\t\t\t\t`Secret vault contains ${profiles.length} profile${profiles.length === 1 ? \"\" : \"s\"}. Only names, variable names, and workspace bindings were returned.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (input.action === \"set\" && input.profile) {\n\t\t\t\t\treturn executeSet(vault, { ...input, profile: input.profile }, ctx, signal);\n\t\t\t\t}\n\t\t\t\tif (input.action === \"materialize\") return executeMaterialize(vault, input, ctx);\n\t\t\t\tif (!input.profile) return invalid(input.action, \"profile_required\", \"A profile is required.\");\n\t\t\t\treturn executeRemove(vault, { ...input, profile: input.profile }, ctx, signal);\n\t\t\t} catch (error) {\n\t\t\t\treturn failed(input.action, error, input.profile);\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"secret-store.js","sourceRoot":"","sources":["../../../src/core/tools/secret-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { defineTool } from \"../extensions/types.ts\";\nimport {\n\ttype CredentialManager,\n\tCredentialManagerError,\n\ttype CredentialProfileSummary,\n\tCredentialStorageError,\n} from \"../secrets/credential-manager.ts\";\nimport {\n\temptyOrchestrationCall,\n\tOrchestrationPanelComponent,\n\ttype OrchestrationPanelModel,\n} from \"./orchestration-panel.ts\";\n\nconst secretStoreSchema = Type.Object(\n\t{\n\t\taction: Type.Union([Type.Literal(\"status\"), Type.Literal(\"list\"), Type.Literal(\"activate\")], {\n\t\t\tdescription: \"Credential-use action. Credential mutation is owner-only through /secrets.\",\n\t\t}),\n\t\tprofile: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tminLength: 1,\n\t\t\t\tmaxLength: 96,\n\t\t\t\tpattern: \"^[A-Za-z0-9][A-Za-z0-9._-]*$\",\n\t\t\t\tdescription: \"Bound profile to activate. Omit when the project has exactly one bound profile.\",\n\t\t\t}),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type SecretStoreToolInput = Static<typeof secretStoreSchema>;\n\nexport type SecretStoreStatus = \"activated\" | \"available\" | \"cancelled\" | \"error\" | \"listed\" | \"unavailable\";\n\nexport interface SecretStoreToolDetails {\n\taction: SecretStoreToolInput[\"action\"];\n\tstatus: SecretStoreStatus;\n\tprofile?: string;\n\tvariableNames?: string[];\n\tprofiles?: CredentialProfileSummary[];\n\tproject?: string;\n\tconnected?: boolean;\n\tcode?: string;\n\tmessage?: string;\n}\n\nexport interface SecretStoreToolOptions {\n\tmanager: CredentialManager;\n}\n\ntype SecretStoreResult = {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: SecretStoreToolDetails;\n};\n\nfunction result(details: SecretStoreToolDetails, text: string): SecretStoreResult {\n\treturn { content: [{ type: \"text\", text }], details };\n}\n\nfunction invalid(input: SecretStoreToolInput): SecretStoreResult | undefined {\n\tif (input.action !== \"activate\" && input.profile !== undefined) {\n\t\treturn result(\n\t\t\t{\n\t\t\t\taction: input.action,\n\t\t\t\tstatus: \"error\",\n\t\t\t\tcode: \"unexpected_profile\",\n\t\t\t\tmessage: `Action ${input.action} does not accept a profile.`,\n\t\t\t},\n\t\t\t`Secret store request is invalid: action ${input.action} does not accept a profile.`,\n\t\t);\n\t}\n\treturn undefined;\n}\n\nfunction failed(input: SecretStoreToolInput, error: unknown): SecretStoreResult {\n\tconst known = error instanceof CredentialManagerError || error instanceof CredentialStorageError;\n\tconst code = known ? error.code : \"safe_failure\";\n\tconst message = known ? error.message : \"Credential activation failed safely without exposing values.\";\n\tconst status: SecretStoreStatus = [\"owner_setup_required\", \"not_connected\", \"provider_unavailable\"].includes(code)\n\t\t? \"unavailable\"\n\t\t: \"error\";\n\treturn result(\n\t\t{\n\t\t\taction: input.action,\n\t\t\tstatus,\n\t\t\t...(input.profile ? { profile: input.profile } : {}),\n\t\t\tcode,\n\t\t\tmessage,\n\t\t},\n\t\t`Credential action failed: ${message}`,\n\t);\n}\n\nfunction panelModel(details: SecretStoreToolDetails | undefined, expanded: boolean): OrchestrationPanelModel {\n\tif (!details) return { label: \"secrets\", status: \"error\", emptyText: \"No credential result was retained.\" };\n\tconst success = [\"activated\", \"available\", \"listed\"].includes(details.status);\n\treturn {\n\t\tlabel: \"secrets\",\n\t\taction: details.status,\n\t\tstatus: success ? \"success\" : details.status === \"cancelled\" ? \"warning\" : \"error\",\n\t\tsummary: [\n\t\t\tdetails.profile,\n\t\t\tdetails.project,\n\t\t\tdetails.variableNames\n\t\t\t\t? `${details.variableNames.length} variable${details.variableNames.length === 1 ? \"\" : \"s\"}`\n\t\t\t\t: undefined,\n\t\t\tdetails.profiles ? `${details.profiles.length} profile${details.profiles.length === 1 ? \"\" : \"s\"}` : undefined,\n\t\t].filter((value): value is string => value !== undefined),\n\t\trows: expanded\n\t\t\t? details.profiles?.map((profile) => ({\n\t\t\t\t\tstatus: profile.boundToCurrentProject ? (\"succeeded\" as const) : (\"info\" as const),\n\t\t\t\t\tlabel: profile.profile,\n\t\t\t\t\tmeta: [\n\t\t\t\t\t\t`${profile.variableNames.length} variable${profile.variableNames.length === 1 ? \"\" : \"s\"}`,\n\t\t\t\t\t\tprofile.boundToCurrentProject ? \"bound here\" : \"not bound here\",\n\t\t\t\t\t],\n\t\t\t\t\tdetails: profile.description ? [profile.description] : undefined,\n\t\t\t\t}))\n\t\t\t: undefined,\n\t\tnotices:\n\t\t\texpanded && details.message ? [{ status: success ? \"info\" : \"error\", text: details.message }] : undefined,\n\t};\n}\n\nexport function createSecretStoreToolDefinition(options: SecretStoreToolOptions) {\n\tconst { manager } = options;\n\treturn defineTool<typeof secretStoreSchema, SecretStoreToolDetails>({\n\t\tname: \"secret_store\",\n\t\tlabel: \"Secret Store\",\n\t\tdescription:\n\t\t\t\"Discover and activate owner-authorized Bitwarden credential profiles for the current project without exposing values.\",\n\t\tpromptSnippet:\n\t\t\t\"Activate project credentials with secret_store before credential-dependent commands. Credential setup and mutation are owner-only through /secrets.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use secret_store activate before credential-dependent work. It works in TUI, print, and RPC modes and returns metadata only.\",\n\t\t\t\"Omit profile when the project has one binding. Use list to select among multiple authorized profiles.\",\n\t\t\t\"Never ask the owner to paste a credential into chat or pass a value through tool arguments.\",\n\t\t\t\"After activation, run the consuming command normally. Never print, inspect, grep, or echo credential environment values.\",\n\t\t\t\"If owner_setup_required is returned, tell the owner to run /secrets in a TUI session. Do not repeatedly retry.\",\n\t\t],\n\t\tparameters: secretStoreSchema,\n\t\texecutionMode: \"sequential\",\n\t\trenderShell: \"self\",\n\t\trenderCall() {\n\t\t\treturn emptyOrchestrationCall();\n\t\t},\n\t\trenderResult(toolResult, { expanded, isPartial }, theme: Theme) {\n\t\t\tif (isPartial) {\n\t\t\t\treturn new OrchestrationPanelComponent(theme, {\n\t\t\t\t\tlabel: \"secrets\",\n\t\t\t\t\taction: \"activating\",\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn new OrchestrationPanelComponent(theme, panelModel(toolResult.details, expanded), expanded);\n\t\t},\n\t\tasync execute(_toolCallId, input, signal, _onUpdate, ctx) {\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn result(\n\t\t\t\t\t{ action: input.action, status: \"cancelled\", code: \"cancelled\" },\n\t\t\t\t\t\"Credential action cancelled.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst validation = invalid(input);\n\t\t\tif (validation) return validation;\n\t\t\ttry {\n\t\t\t\tif (input.action === \"status\") {\n\t\t\t\t\tconst status = manager.status;\n\t\t\t\t\tif (!status.sessionAvailable) {\n\t\t\t\t\t\treturn result(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\taction: input.action,\n\t\t\t\t\t\t\t\tstatus: \"unavailable\",\n\t\t\t\t\t\t\t\tconnected: false,\n\t\t\t\t\t\t\t\tcode: \"owner_setup_required\",\n\t\t\t\t\t\t\t\tmessage: \"The owner must connect Bitwarden with /secrets.\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"Bitwarden owner setup is required. Run /secrets in a TUI session.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn result(\n\t\t\t\t\t\t{ action: input.action, status: \"available\", connected: status.connected },\n\t\t\t\t\t\tstatus.connected\n\t\t\t\t\t\t\t? \"Bitwarden is connected for this Pi session.\"\n\t\t\t\t\t\t\t: \"A Bitwarden session key is available and will be validated on activation.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (input.action === \"list\") {\n\t\t\t\t\tconst profiles = await manager.listForProject(ctx.cwd, signal);\n\t\t\t\t\treturn result(\n\t\t\t\t\t\t{ action: input.action, status: \"listed\", profiles },\n\t\t\t\t\t\t`Found ${profiles.length} credential profile${profiles.length === 1 ? \"\" : \"s\"}; only metadata was returned.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst activated = await manager.activateForProject(ctx.cwd, input.profile, signal);\n\t\t\t\treturn result(\n\t\t\t\t\t{\n\t\t\t\t\t\taction: input.action,\n\t\t\t\t\t\tstatus: \"activated\",\n\t\t\t\t\t\tprofile: activated.profile,\n\t\t\t\t\t\tvariableNames: activated.variableNames,\n\t\t\t\t\t\tproject: activated.project,\n\t\t\t\t\t},\n\t\t\t\t\t`Activated ${activated.profile} for ${activated.project}. Credential values remain hidden.`,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn failed(input, error);\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|