@psnext/slingcli 2.5.20260607-2 → 2.5.20260615-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/node_modules/@aws-sdk/core/dist-cjs/index.js +47 -2297
- package/node_modules/@aws-sdk/core/dist-es/index.js +3 -3
- package/node_modules/@aws-sdk/core/dist-types/index.d.ts +5 -5
- package/node_modules/@aws-sdk/core/dist-types/ts3.4/index.d.ts +5 -5
- package/node_modules/@aws-sdk/core/package.json +8 -8
- package/node_modules/@aws-sdk/credential-provider-env/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/package.json +7 -7
- package/node_modules/@aws-sdk/credential-provider-http/package.json +6 -5
- package/node_modules/@aws-sdk/credential-provider-ini/package.json +11 -11
- package/node_modules/@aws-sdk/credential-provider-login/package.json +5 -5
- package/node_modules/@aws-sdk/credential-provider-node/package.json +9 -9
- package/node_modules/@aws-sdk/credential-provider-process/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/index.js +4 -1
- package/node_modules/@aws-sdk/credential-provider-sso/dist-es/resolveSSOCredentials.js +4 -1
- package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/package.json +5 -5
- package/node_modules/@aws-sdk/credential-provider-sso/package.json +9 -7
- package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +5 -5
- package/node_modules/@aws-sdk/eventstream-handler-node/package.json +3 -3
- package/node_modules/@aws-sdk/middleware-eventstream/package.json +3 -3
- package/node_modules/@aws-sdk/middleware-websocket/package.json +5 -5
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/package.json +7 -7
- package/node_modules/@aws-sdk/nested-clients/package.json +6 -6
- package/node_modules/@aws-sdk/signature-v4-multi-region/package.json +7 -6
- package/node_modules/@aws-sdk/types/package.json +2 -2
- package/node_modules/@aws-sdk/util-locate-window/package.json +2 -2
- package/node_modules/@aws-sdk/xml-builder/package.json +2 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +6 -6
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +906 -873
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +25 -8
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +19 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +8 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -2
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +3 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.js +48 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.js +133 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +14 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js +4 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +9 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js +4 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js +34 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +5 -57
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +41 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +31 -17
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js +58 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js +24 -26
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js +0 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +121 -54
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +11 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +26 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js +89 -17
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +65 -76
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js +1 -118
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.js +103 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +7 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +20 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +87 -12
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.js +23 -18
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +104 -30
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js +19 -41
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +72 -18
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +78 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.js +4 -27
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/LICENSE +15 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/bin/semver.js +195 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/comparator.js +143 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/index.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/range.js +557 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/semver.js +333 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/clean.js +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/cmp.js +54 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/coerce.js +62 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-build.js +9 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-loose.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/diff.js +60 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/eq.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gt.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gte.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/inc.js +21 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lt.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lte.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/major.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/minor.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/neq.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/parse.js +18 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/patch.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/prerelease.js +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rcompare.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rsort.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/satisfies.js +12 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/sort.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/truncate.js +48 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/valid.js +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/index.js +93 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/constants.js +37 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/debug.js +11 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/identifiers.js +29 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/lrucache.js +42 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/parse-options.js +17 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/re.js +223 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/package.json +78 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/preload.js +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/range.bnf +17 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/gtr.js +6 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/intersects.js +9 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/ltr.js +6 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/max-satisfying.js +27 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-satisfying.js +26 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-version.js +63 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/outside.js +82 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/simplify.js +49 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/subset.js +249 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/to-comparators.js +10 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/valid.js +13 -0
- package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +25 -12
- package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -8
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +102 -43
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +11 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.js +51 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +38 -77
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +145 -21
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +44 -16
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/node_modules/@nodable/entities/package.json +4 -1
- package/node_modules/@nodable/entities/src/EntityDecoder.js +104 -3
- package/node_modules/@nodable/entities/src/index.d.ts +77 -0
- package/node_modules/@nodable/entities/src/index.js +1 -1
- package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.browser.js +3 -3
- package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.js +3 -3
- package/node_modules/@smithy/core/dist-es/submodules/retry/middleware-retry/retry-pre-sra-deprecated/StandardRetryStrategy.js +2 -2
- package/node_modules/@smithy/core/dist-es/submodules/retry/util-retry/DefaultRateLimiter.js +1 -1
- package/node_modules/@smithy/core/package.json +17 -17
- package/node_modules/@smithy/credential-provider-imds/package.json +6 -6
- package/node_modules/@smithy/fetch-http-handler/package.json +9 -9
- package/node_modules/@smithy/signature-v4/package.json +6 -6
- package/node_modules/@smithy/types/package.json +9 -9
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/http2.d.ts +1 -0
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/anynum/LICENSE +21 -0
- package/node_modules/anynum/README.md +142 -0
- package/node_modules/anynum/anynum.js +135 -0
- package/node_modules/anynum/digitTable.js +116 -0
- package/node_modules/anynum/package.json +42 -0
- package/node_modules/protobufjs/dist/light/protobuf.js +161 -203
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +34 -77
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +181 -223
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/index.d.ts +0 -8
- package/node_modules/protobufjs/package.json +2 -3
- package/node_modules/protobufjs/src/converter.js +5 -4
- package/node_modules/protobufjs/src/decoder.js +1 -1
- package/node_modules/protobufjs/src/service.js +5 -7
- package/node_modules/protobufjs/src/type.js +3 -1
- package/node_modules/protobufjs/src/util/minimal.js +1 -4
- package/node_modules/protobufjs/src/verifier.js +1 -1
- package/node_modules/semver/classes/range.js +11 -2
- package/node_modules/semver/package.json +2 -2
- package/node_modules/strnum/CHANGELOG.md +8 -0
- package/node_modules/strnum/README.md +9 -0
- package/node_modules/strnum/package.json +4 -1
- package/node_modules/strnum/strnum.js +9 -1
- package/package.json +6 -6
- package/slingshot/index.js +260 -258
- package/node_modules/@protobufjs/inquire/CHANGELOG.md +0 -8
- package/node_modules/@protobufjs/inquire/LICENSE +0 -26
- package/node_modules/@protobufjs/inquire/README.md +0 -13
- package/node_modules/@protobufjs/inquire/index.d.ts +0 -10
- package/node_modules/@protobufjs/inquire/index.js +0 -38
- package/node_modules/@protobufjs/inquire/package.json +0 -21
- package/node_modules/@protobufjs/inquire/tests/data/array.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/emptyArray.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/emptyObject.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/object.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/index.js +0 -20
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Container, getKeybindings, Input, Spacer, Text,
|
|
1
|
+
import { Container, getKeybindings, Input, Spacer, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "@earendil-works/pi-tui";
|
|
2
2
|
import { theme } from "../theme/theme.js";
|
|
3
3
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
4
|
-
import {
|
|
4
|
+
import { formatKeyText, keyHint } from "./keybinding-hints.js";
|
|
5
5
|
class TreeList {
|
|
6
6
|
flatNodes = [];
|
|
7
7
|
filteredNodes = [];
|
|
@@ -956,6 +956,90 @@ class SearchLine {
|
|
|
956
956
|
}
|
|
957
957
|
handleInput(_keyData) { }
|
|
958
958
|
}
|
|
959
|
+
/** Component that renders tree help as semantic rows with chunk-aware wrapping */
|
|
960
|
+
class TreeHelp {
|
|
961
|
+
invalidate() { }
|
|
962
|
+
render(width) {
|
|
963
|
+
const items = TREE_HELP_ITEMS.map(({ keys, label, labelFirst }) => {
|
|
964
|
+
const text = formatHelpKeys(keys);
|
|
965
|
+
if (!text)
|
|
966
|
+
return label;
|
|
967
|
+
return labelFirst ? `${label} ${text}` : `${text} ${label}`;
|
|
968
|
+
});
|
|
969
|
+
const availableWidth = Math.max(1, width);
|
|
970
|
+
const indent = " ";
|
|
971
|
+
const separator = " · ";
|
|
972
|
+
const lines = [];
|
|
973
|
+
let currentLine = "";
|
|
974
|
+
for (const item of items) {
|
|
975
|
+
const candidate = currentLine
|
|
976
|
+
? `${currentLine}${separator}${item}`
|
|
977
|
+
: visibleWidth(`${indent}${item}`) <= availableWidth
|
|
978
|
+
? `${indent}${item}`
|
|
979
|
+
: item;
|
|
980
|
+
if (!currentLine || visibleWidth(candidate) <= availableWidth) {
|
|
981
|
+
currentLine = candidate;
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
lines.push(...wrapTextWithAnsi(currentLine.trimEnd(), availableWidth));
|
|
985
|
+
currentLine = visibleWidth(`${indent}${item}`) <= availableWidth ? `${indent}${item}` : item;
|
|
986
|
+
}
|
|
987
|
+
if (currentLine) {
|
|
988
|
+
lines.push(...wrapTextWithAnsi(currentLine.trimEnd(), availableWidth));
|
|
989
|
+
}
|
|
990
|
+
return lines.map((line) => theme.fg("muted", line));
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
const TREE_HELP_ITEMS = [
|
|
994
|
+
{ keys: ["tui.select.up", "tui.select.down"], label: "move" },
|
|
995
|
+
{ keys: ["tui.editor.cursorLeft", "tui.editor.cursorRight"], label: "page" },
|
|
996
|
+
{ keys: ["app.tree.foldOrUp", "app.tree.unfoldOrDown"], label: "branch" },
|
|
997
|
+
{ keys: ["app.tree.editLabel"], label: "label" },
|
|
998
|
+
{ keys: ["app.tree.toggleLabelTimestamp"], label: "label time" },
|
|
999
|
+
{
|
|
1000
|
+
keys: [
|
|
1001
|
+
"app.tree.filter.default",
|
|
1002
|
+
"app.tree.filter.noTools",
|
|
1003
|
+
"app.tree.filter.userOnly",
|
|
1004
|
+
"app.tree.filter.labeledOnly",
|
|
1005
|
+
"app.tree.filter.all",
|
|
1006
|
+
],
|
|
1007
|
+
label: "filters",
|
|
1008
|
+
labelFirst: true,
|
|
1009
|
+
},
|
|
1010
|
+
{ keys: ["app.tree.filter.cycleForward", "app.tree.filter.cycleBackward"], label: "cycle", labelFirst: true },
|
|
1011
|
+
];
|
|
1012
|
+
function formatHelpKeys(keybindings) {
|
|
1013
|
+
const keys = [];
|
|
1014
|
+
for (const keybinding of keybindings) {
|
|
1015
|
+
const key = getKeybindings().getKeys(keybinding)[0];
|
|
1016
|
+
if (key !== undefined)
|
|
1017
|
+
keys.push(key);
|
|
1018
|
+
}
|
|
1019
|
+
if (keys.length === 0)
|
|
1020
|
+
return "";
|
|
1021
|
+
return formatKeyText(compactRawKeys(keys))
|
|
1022
|
+
.replace(/\bpageUp\b/g, "pgup")
|
|
1023
|
+
.replace(/\bpageDown\b/g, "pgdn")
|
|
1024
|
+
.replace(/\bup\b/g, "↑")
|
|
1025
|
+
.replace(/\bdown\b/g, "↓")
|
|
1026
|
+
.replace(/\bleft\b/g, "←")
|
|
1027
|
+
.replace(/\bright\b/g, "→");
|
|
1028
|
+
}
|
|
1029
|
+
function compactRawKeys(keys) {
|
|
1030
|
+
if (keys.length === 1)
|
|
1031
|
+
return keys[0];
|
|
1032
|
+
const parts = keys.map((key) => {
|
|
1033
|
+
const separatorIndex = key.lastIndexOf("+");
|
|
1034
|
+
return separatorIndex === -1
|
|
1035
|
+
? { prefix: "", suffix: key }
|
|
1036
|
+
: { prefix: key.slice(0, separatorIndex + 1), suffix: key.slice(separatorIndex + 1) };
|
|
1037
|
+
});
|
|
1038
|
+
const prefix = parts[0].prefix;
|
|
1039
|
+
return prefix && parts.every((part) => part.prefix === prefix)
|
|
1040
|
+
? `${prefix}${parts.map((part) => part.suffix).join("/")}`
|
|
1041
|
+
: keys.join("/");
|
|
1042
|
+
}
|
|
959
1043
|
/** Label input component shown when editing a label */
|
|
960
1044
|
class LabelInput {
|
|
961
1045
|
input;
|
|
@@ -1037,16 +1121,7 @@ export class TreeSelectorComponent extends Container {
|
|
|
1037
1121
|
this.addChild(new Spacer(1));
|
|
1038
1122
|
this.addChild(new DynamicBorder());
|
|
1039
1123
|
this.addChild(new Text(theme.bold(" Session Tree"), 1, 0));
|
|
1040
|
-
|
|
1041
|
-
keyText("app.tree.filter.default"),
|
|
1042
|
-
keyText("app.tree.filter.noTools"),
|
|
1043
|
-
keyText("app.tree.filter.userOnly"),
|
|
1044
|
-
keyText("app.tree.filter.labeledOnly"),
|
|
1045
|
-
keyText("app.tree.filter.all"),
|
|
1046
|
-
].join("/");
|
|
1047
|
-
const cycleKeys = `${keyText("app.tree.filter.cycleForward")}/${keyText("app.tree.filter.cycleBackward")}`;
|
|
1048
|
-
const branchKeys = `${keyText("app.tree.foldOrUp")}/${keyText("app.tree.unfoldOrDown")}`;
|
|
1049
|
-
this.addChild(new TruncatedText(theme.fg("muted", ` ↑/↓: move. ←/→: page. ${branchKeys}: fold/branch. ${keyText("app.tree.editLabel")}: label. ${filterKeys}: filters (${cycleKeys} cycle). ${keyText("app.tree.toggleLabelTimestamp")}: label time`), 0, 0));
|
|
1124
|
+
this.addChild(new TreeHelp());
|
|
1050
1125
|
this.addChild(new SearchLine(this.treeList));
|
|
1051
1126
|
this.addChild(new DynamicBorder());
|
|
1052
1127
|
this.addChild(new Spacer(1));
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { Container, getKeybindings, Spacer, Text } from "@earendil-works/pi-tui";
|
|
2
|
+
import { getProjectTrustOptions, } from "../../../core/trust-manager.js";
|
|
2
3
|
import { theme } from "../theme/theme.js";
|
|
3
4
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
4
5
|
import { keyHint, rawKeyHint } from "./keybinding-hints.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
];
|
|
9
|
-
function formatDecision(decision) {
|
|
10
|
-
if (decision === true) {
|
|
11
|
-
return "trusted";
|
|
6
|
+
function formatDecision(trustPath, decision) {
|
|
7
|
+
if (decision === null) {
|
|
8
|
+
return "none";
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const label = decision.decision ? "trusted" : "untrusted";
|
|
11
|
+
if (trustPath !== undefined && decision.path !== trustPath) {
|
|
12
|
+
return `${label} (inherited from ${decision.path})`;
|
|
15
13
|
}
|
|
16
|
-
return
|
|
14
|
+
return `${label} (${decision.path})`;
|
|
17
15
|
}
|
|
18
16
|
export class TrustSelectorComponent extends Container {
|
|
19
17
|
selectedIndex;
|
|
20
18
|
listContainer;
|
|
19
|
+
trustOptions;
|
|
21
20
|
savedDecision;
|
|
22
21
|
onSelectCallback;
|
|
23
22
|
onCancelCallback;
|
|
24
23
|
constructor(options) {
|
|
25
24
|
super();
|
|
26
25
|
this.savedDecision = options.savedDecision;
|
|
27
|
-
this.
|
|
26
|
+
this.trustOptions = getProjectTrustOptions(options.cwd);
|
|
27
|
+
this.selectedIndex = Math.max(0, this.trustOptions.findIndex((option) => this.isSavedOption(option)));
|
|
28
28
|
this.onSelectCallback = options.onSelect;
|
|
29
29
|
this.onCancelCallback = options.onCancel;
|
|
30
30
|
this.addChild(new DynamicBorder());
|
|
@@ -32,7 +32,7 @@ export class TrustSelectorComponent extends Container {
|
|
|
32
32
|
this.addChild(new Text(theme.fg("accent", theme.bold("Project trust")), 1, 0));
|
|
33
33
|
this.addChild(new Text(theme.fg("muted", options.cwd), 1, 0));
|
|
34
34
|
this.addChild(new Spacer(1));
|
|
35
|
-
this.addChild(new Text(theme.fg("muted", `Saved decision: ${formatDecision(options.savedDecision)}`), 1, 0));
|
|
35
|
+
this.addChild(new Text(theme.fg("muted", `Saved decision: ${formatDecision(this.trustOptions[0]?.savedPath, options.savedDecision)}`), 1, 0));
|
|
36
36
|
this.addChild(new Text(theme.fg("muted", `Current session: ${options.projectTrusted ? "trusted" : "untrusted"}`), 1, 0));
|
|
37
37
|
this.addChild(new Spacer(1));
|
|
38
38
|
this.listContainer = new Container();
|
|
@@ -47,15 +47,20 @@ export class TrustSelectorComponent extends Container {
|
|
|
47
47
|
this.addChild(new DynamicBorder());
|
|
48
48
|
this.updateList();
|
|
49
49
|
}
|
|
50
|
+
isSavedOption(option) {
|
|
51
|
+
return (option.savedPath !== undefined &&
|
|
52
|
+
this.savedDecision?.decision === option.trusted &&
|
|
53
|
+
this.savedDecision.path === option.savedPath);
|
|
54
|
+
}
|
|
50
55
|
updateList() {
|
|
51
56
|
this.listContainer.clear();
|
|
52
|
-
for (let i = 0; i <
|
|
53
|
-
const option =
|
|
57
|
+
for (let i = 0; i < this.trustOptions.length; i++) {
|
|
58
|
+
const option = this.trustOptions[i];
|
|
54
59
|
if (!option) {
|
|
55
60
|
continue;
|
|
56
61
|
}
|
|
57
62
|
const isSelected = i === this.selectedIndex;
|
|
58
|
-
const isCurrent =
|
|
63
|
+
const isCurrent = this.isSavedOption(option);
|
|
59
64
|
const checkmark = isCurrent ? theme.fg("success", " ✓") : "";
|
|
60
65
|
const prefix = isSelected ? theme.fg("accent", "→ ") : " ";
|
|
61
66
|
const label = isSelected ? theme.fg("accent", option.label) : theme.fg("text", option.label);
|
|
@@ -69,13 +74,13 @@ export class TrustSelectorComponent extends Container {
|
|
|
69
74
|
this.updateList();
|
|
70
75
|
}
|
|
71
76
|
else if (kb.matches(keyData, "tui.select.down") || keyData === "j") {
|
|
72
|
-
this.selectedIndex = Math.min(
|
|
77
|
+
this.selectedIndex = Math.min(this.trustOptions.length - 1, this.selectedIndex + 1);
|
|
73
78
|
this.updateList();
|
|
74
79
|
}
|
|
75
80
|
else if (kb.matches(keyData, "tui.select.confirm") || keyData === "\n") {
|
|
76
|
-
const selected =
|
|
81
|
+
const selected = this.trustOptions[this.selectedIndex];
|
|
77
82
|
if (selected) {
|
|
78
|
-
this.onSelectCallback(selected.trusted);
|
|
83
|
+
this.onSelectCallback({ trusted: selected.trusted, updates: selected.updates });
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
86
|
else if (kb.matches(keyData, "tui.select.cancel")) {
|
package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js
CHANGED
|
@@ -24,8 +24,8 @@ import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../cor
|
|
|
24
24
|
import { SessionManager } from "../../core/session-manager.js";
|
|
25
25
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
26
26
|
import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
|
|
27
|
-
import {
|
|
28
|
-
import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
|
|
27
|
+
import { hasTrustRequiringProjectResources, ProjectTrustStore } from "../../core/trust-manager.js";
|
|
28
|
+
import { getChangelogPath, getNewEntries, normalizeChangelogLinks, parseChangelog } from "../../utils/changelog.js";
|
|
29
29
|
import { copyToClipboard } from "../../utils/clipboard.js";
|
|
30
30
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
31
31
|
import { parseGitUrl } from "../../utils/git.js";
|
|
@@ -63,7 +63,7 @@ import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
|
63
63
|
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
64
64
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
65
65
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
66
|
-
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
66
|
+
import { detectTerminalBackgroundTheme, getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
67
67
|
function isExpandable(obj) {
|
|
68
68
|
return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
|
|
69
69
|
}
|
|
@@ -215,6 +215,7 @@ export class InteractiveMode {
|
|
|
215
215
|
// Custom header from extension (undefined = use built-in header)
|
|
216
216
|
customHeader = undefined;
|
|
217
217
|
options;
|
|
218
|
+
autoTrustOnReloadCwd;
|
|
218
219
|
// Convenience accessors
|
|
219
220
|
get session() {
|
|
220
221
|
return this.runtimeHost.session;
|
|
@@ -231,6 +232,7 @@ export class InteractiveMode {
|
|
|
231
232
|
constructor(runtimeHost, options = {}) {
|
|
232
233
|
this.runtimeHost = runtimeHost;
|
|
233
234
|
this.options = options;
|
|
235
|
+
this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
|
|
234
236
|
this.runtimeHost.setBeforeSessionInvalidate(() => {
|
|
235
237
|
this.resetExtensionUI();
|
|
236
238
|
});
|
|
@@ -266,6 +268,22 @@ export class InteractiveMode {
|
|
|
266
268
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
267
269
|
initTheme(this.settingsManager.getTheme(), true);
|
|
268
270
|
}
|
|
271
|
+
async detectThemeIfUnset() {
|
|
272
|
+
if (this.settingsManager.getTheme()) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const detection = await detectTerminalBackgroundTheme({ ui: this.ui, timeoutMs: 100 });
|
|
276
|
+
const result = setTheme(detection.theme, true);
|
|
277
|
+
if (!result.success) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (detection.confidence === "high") {
|
|
281
|
+
this.settingsManager.setTheme(detection.theme);
|
|
282
|
+
await this.settingsManager.flush();
|
|
283
|
+
}
|
|
284
|
+
this.updateEditorBorderColor();
|
|
285
|
+
this.ui.requestRender();
|
|
286
|
+
}
|
|
269
287
|
getAutocompleteSourceTag(sourceInfo) {
|
|
270
288
|
if (!sourceInfo) {
|
|
271
289
|
return undefined;
|
|
@@ -370,8 +388,13 @@ export class InteractiveMode {
|
|
|
370
388
|
}
|
|
371
389
|
setupAutocompleteProvider() {
|
|
372
390
|
let provider = this.createBaseAutocompleteProvider();
|
|
391
|
+
const triggerCharacters = [];
|
|
373
392
|
for (const wrapProvider of this.autocompleteProviderWrappers) {
|
|
374
393
|
provider = wrapProvider(provider);
|
|
394
|
+
triggerCharacters.push(...(provider.triggerCharacters ?? []));
|
|
395
|
+
}
|
|
396
|
+
if (triggerCharacters.length > 0) {
|
|
397
|
+
provider.triggerCharacters = [...new Set(triggerCharacters)];
|
|
375
398
|
}
|
|
376
399
|
this.autocompleteProvider = provider;
|
|
377
400
|
this.defaultEditor.setAutocompleteProvider(provider);
|
|
@@ -428,8 +451,23 @@ export class InteractiveMode {
|
|
|
428
451
|
: "";
|
|
429
452
|
console.log(theme.fg("dim", `Model scope: ${modelList}${cycleHint}`));
|
|
430
453
|
}
|
|
431
|
-
// Add header container as first child
|
|
454
|
+
// Add header container as first child. Populate it after detectThemeIfUnset.
|
|
432
455
|
this.ui.addChild(this.headerContainer);
|
|
456
|
+
this.ui.addChild(this.chatContainer);
|
|
457
|
+
this.ui.addChild(this.pendingMessagesContainer);
|
|
458
|
+
this.ui.addChild(this.statusContainer);
|
|
459
|
+
this.renderWidgets(); // Initialize with default spacer
|
|
460
|
+
this.ui.addChild(this.widgetContainerAbove);
|
|
461
|
+
this.ui.addChild(this.editorContainer);
|
|
462
|
+
this.ui.addChild(this.widgetContainerBelow);
|
|
463
|
+
this.ui.addChild(this.footer);
|
|
464
|
+
this.ui.setFocus(this.editor);
|
|
465
|
+
this.setupKeyHandlers();
|
|
466
|
+
this.setupEditorSubmitHandler();
|
|
467
|
+
// Start the UI before initializing extensions so session_start handlers can use interactive dialogs
|
|
468
|
+
this.ui.start();
|
|
469
|
+
this.isInitialized = true;
|
|
470
|
+
await this.detectThemeIfUnset();
|
|
433
471
|
// Add header with keybindings from config (unless silenced)
|
|
434
472
|
if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
|
|
435
473
|
const logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
|
|
@@ -476,20 +514,7 @@ export class InteractiveMode {
|
|
|
476
514
|
this.builtInHeader = new Text("", 0, 0);
|
|
477
515
|
this.headerContainer.addChild(this.builtInHeader);
|
|
478
516
|
}
|
|
479
|
-
this.ui.
|
|
480
|
-
this.ui.addChild(this.pendingMessagesContainer);
|
|
481
|
-
this.ui.addChild(this.statusContainer);
|
|
482
|
-
this.renderWidgets(); // Initialize with default spacer
|
|
483
|
-
this.ui.addChild(this.widgetContainerAbove);
|
|
484
|
-
this.ui.addChild(this.editorContainer);
|
|
485
|
-
this.ui.addChild(this.widgetContainerBelow);
|
|
486
|
-
this.ui.addChild(this.footer);
|
|
487
|
-
this.ui.setFocus(this.editor);
|
|
488
|
-
this.setupKeyHandlers();
|
|
489
|
-
this.setupEditorSubmitHandler();
|
|
490
|
-
// Start the UI before initializing extensions so session_start handlers can use interactive dialogs
|
|
491
|
-
this.ui.start();
|
|
492
|
-
this.isInitialized = true;
|
|
517
|
+
this.ui.requestRender();
|
|
493
518
|
// Initialize extensions first so resources are shown before messages
|
|
494
519
|
await this.rebindCurrentSession();
|
|
495
520
|
// Render initial messages AFTER showing loaded resources
|
|
@@ -670,7 +695,7 @@ export class InteractiveMode {
|
|
|
670
695
|
if (newEntries.length > 0) {
|
|
671
696
|
this.settingsManager.setLastChangelogVersion(VERSION);
|
|
672
697
|
this.reportInstallTelemetry(VERSION);
|
|
673
|
-
return newEntries.map((e) => e.content).join("\n\n");
|
|
698
|
+
return newEntries.map((e) => normalizeChangelogLinks(e.content, e)).join("\n\n");
|
|
674
699
|
}
|
|
675
700
|
return undefined;
|
|
676
701
|
}
|
|
@@ -1278,6 +1303,7 @@ export class InteractiveMode {
|
|
|
1278
1303
|
modelRegistry: this.session.modelRegistry,
|
|
1279
1304
|
model: this.session.model,
|
|
1280
1305
|
isIdle: () => !this.session.isStreaming,
|
|
1306
|
+
isProjectTrusted: () => this.settingsManager.isProjectTrusted(),
|
|
1281
1307
|
signal: this.session.agent.signal,
|
|
1282
1308
|
abort: () => {
|
|
1283
1309
|
this.restoreQueuedMessagesToEditor({ abort: true });
|
|
@@ -1557,6 +1583,20 @@ export class InteractiveMode {
|
|
|
1557
1583
|
/**
|
|
1558
1584
|
* Create the ExtensionUIContext for extensions.
|
|
1559
1585
|
*/
|
|
1586
|
+
createProjectTrustContext(cwd) {
|
|
1587
|
+
const ui = this.createExtensionUIContext();
|
|
1588
|
+
return {
|
|
1589
|
+
cwd,
|
|
1590
|
+
mode: "tui",
|
|
1591
|
+
hasUI: true,
|
|
1592
|
+
ui: {
|
|
1593
|
+
select: ui.select,
|
|
1594
|
+
confirm: ui.confirm,
|
|
1595
|
+
input: ui.input,
|
|
1596
|
+
notify: ui.notify,
|
|
1597
|
+
},
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1560
1600
|
createExtensionUIContext() {
|
|
1561
1601
|
return {
|
|
1562
1602
|
select: (title, options, opts) => this.showExtensionSelector(title, options, opts),
|
|
@@ -2645,13 +2685,13 @@ export class InteractiveMode {
|
|
|
2645
2685
|
}
|
|
2646
2686
|
}
|
|
2647
2687
|
renderProjectTrustWarningIfNeeded() {
|
|
2648
|
-
if (this.settingsManager.isProjectTrusted() || !
|
|
2688
|
+
if (this.settingsManager.isProjectTrusted() || !hasTrustRequiringProjectResources(this.sessionManager.getCwd())) {
|
|
2649
2689
|
return;
|
|
2650
2690
|
}
|
|
2651
2691
|
if (this.chatContainer.children.length > 0) {
|
|
2652
2692
|
this.chatContainer.addChild(new Spacer(1));
|
|
2653
2693
|
}
|
|
2654
|
-
this.chatContainer.addChild(new Text(theme.fg("warning", "This project is not trusted. Project
|
|
2694
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", "This project is not trusted. Project .pi resources and packages are ignored. Use /trust to save a trust decision, then restart pi."), 1, 0));
|
|
2655
2695
|
}
|
|
2656
2696
|
async getUserInput() {
|
|
2657
2697
|
const queuedInput = this.pendingUserInputs.shift();
|
|
@@ -2697,7 +2737,9 @@ export class InteractiveMode {
|
|
|
2697
2737
|
if (this.isShuttingDown)
|
|
2698
2738
|
return;
|
|
2699
2739
|
this.isShuttingDown = true;
|
|
2700
|
-
|
|
2740
|
+
// Keep signal handlers registered until terminal cleanup has completed.
|
|
2741
|
+
// `signal-exit` checks the listener list during the same SIGTERM/SIGHUP
|
|
2742
|
+
// dispatch and re-sends the signal if only its own listeners remain.
|
|
2701
2743
|
if (options?.fromSignal) {
|
|
2702
2744
|
// Signal-triggered shutdown (SIGTERM/SIGHUP). Emit extension cleanup
|
|
2703
2745
|
// (session_shutdown) BEFORE touching the terminal. Extension teardown
|
|
@@ -3262,6 +3304,7 @@ export class InteractiveMode {
|
|
|
3262
3304
|
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
3263
3305
|
treeFilterMode: this.settingsManager.getTreeFilterMode(),
|
|
3264
3306
|
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
3307
|
+
defaultProjectTrust: this.settingsManager.getDefaultProjectTrust(),
|
|
3265
3308
|
editorPaddingX: this.settingsManager.getEditorPaddingX(),
|
|
3266
3309
|
autocompleteMaxVisible: this.settingsManager.getAutocompleteMaxVisible(),
|
|
3267
3310
|
quietStartup: this.settingsManager.getQuietStartup(),
|
|
@@ -3354,6 +3397,9 @@ export class InteractiveMode {
|
|
|
3354
3397
|
onQuietStartupChange: (enabled) => {
|
|
3355
3398
|
this.settingsManager.setQuietStartup(enabled);
|
|
3356
3399
|
},
|
|
3400
|
+
onDefaultProjectTrustChange: (defaultProjectTrust) => {
|
|
3401
|
+
this.settingsManager.setDefaultProjectTrust(defaultProjectTrust);
|
|
3402
|
+
},
|
|
3357
3403
|
onDoubleEscapeActionChange: (action) => {
|
|
3358
3404
|
this.settingsManager.setDoubleEscapeAction(action);
|
|
3359
3405
|
},
|
|
@@ -3468,19 +3514,42 @@ export class InteractiveMode {
|
|
|
3468
3514
|
// Ignore auth lookup failures for warning-only checks.
|
|
3469
3515
|
}
|
|
3470
3516
|
}
|
|
3517
|
+
maybeSaveImplicitProjectTrustAfterReload() {
|
|
3518
|
+
const cwd = this.sessionManager.getCwd();
|
|
3519
|
+
if (this.autoTrustOnReloadCwd !== cwd) {
|
|
3520
|
+
return false;
|
|
3521
|
+
}
|
|
3522
|
+
if (!this.settingsManager.isProjectTrusted() || !hasTrustRequiringProjectResources(cwd)) {
|
|
3523
|
+
return false;
|
|
3524
|
+
}
|
|
3525
|
+
const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);
|
|
3526
|
+
try {
|
|
3527
|
+
if (trustStore.get(cwd) !== null) {
|
|
3528
|
+
this.autoTrustOnReloadCwd = undefined;
|
|
3529
|
+
return false;
|
|
3530
|
+
}
|
|
3531
|
+
trustStore.set(cwd, true);
|
|
3532
|
+
this.autoTrustOnReloadCwd = undefined;
|
|
3533
|
+
return true;
|
|
3534
|
+
}
|
|
3535
|
+
catch (error) {
|
|
3536
|
+
this.showWarning(`Could not save project trust after reload: ${error instanceof Error ? error.message : String(error)}`);
|
|
3537
|
+
return false;
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3471
3540
|
showTrustSelector() {
|
|
3472
3541
|
const cwd = this.sessionManager.getCwd();
|
|
3473
3542
|
const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);
|
|
3474
|
-
const savedDecision = trustStore.
|
|
3543
|
+
const savedDecision = trustStore.getEntry(cwd);
|
|
3475
3544
|
this.showSelector((done) => {
|
|
3476
3545
|
const selector = new TrustSelectorComponent({
|
|
3477
3546
|
cwd,
|
|
3478
3547
|
savedDecision,
|
|
3479
3548
|
projectTrusted: this.settingsManager.isProjectTrusted(),
|
|
3480
|
-
onSelect: (
|
|
3481
|
-
trustStore.
|
|
3549
|
+
onSelect: (selection) => {
|
|
3550
|
+
trustStore.setMany(selection.updates);
|
|
3482
3551
|
done();
|
|
3483
|
-
this.showStatus(`Saved trust decision: ${trusted ? "trusted" : "untrusted"}. Restart pi for this to take effect.`);
|
|
3552
|
+
this.showStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart pi for this to take effect.`);
|
|
3484
3553
|
},
|
|
3485
3554
|
onCancel: () => {
|
|
3486
3555
|
done();
|
|
@@ -3768,6 +3837,7 @@ export class InteractiveMode {
|
|
|
3768
3837
|
try {
|
|
3769
3838
|
const result = await this.runtimeHost.switchSession(sessionPath, {
|
|
3770
3839
|
withSession: options?.withSession,
|
|
3840
|
+
projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),
|
|
3771
3841
|
});
|
|
3772
3842
|
if (result.cancelled) {
|
|
3773
3843
|
return result;
|
|
@@ -3786,6 +3856,7 @@ export class InteractiveMode {
|
|
|
3786
3856
|
const result = await this.runtimeHost.switchSession(sessionPath, {
|
|
3787
3857
|
cwdOverride: selectedCwd,
|
|
3788
3858
|
withSession: options?.withSession,
|
|
3859
|
+
projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),
|
|
3789
3860
|
});
|
|
3790
3861
|
if (result.cancelled) {
|
|
3791
3862
|
return result;
|
|
@@ -4184,11 +4255,14 @@ export class InteractiveMode {
|
|
|
4184
4255
|
force: false,
|
|
4185
4256
|
showDiagnosticsWhenQuiet: true,
|
|
4186
4257
|
});
|
|
4258
|
+
const savedImplicitProjectTrust = this.maybeSaveImplicitProjectTrustAfterReload();
|
|
4187
4259
|
const modelsJsonError = this.session.modelRegistry.getError();
|
|
4188
4260
|
if (modelsJsonError) {
|
|
4189
4261
|
this.showError(`models.json error: ${modelsJsonError}`);
|
|
4190
4262
|
}
|
|
4191
|
-
this.showStatus(
|
|
4263
|
+
this.showStatus(savedImplicitProjectTrust
|
|
4264
|
+
? "Reloaded keybindings, extensions, skills, prompts, themes; saved project trust"
|
|
4265
|
+
: "Reloaded keybindings, extensions, skills, prompts, themes");
|
|
4192
4266
|
}
|
|
4193
4267
|
catch (error) {
|
|
4194
4268
|
dismissReloadBox(previousEditor);
|
|
@@ -4443,7 +4517,7 @@ export class InteractiveMode {
|
|
|
4443
4517
|
const changelogMarkdown = allEntries.length > 0
|
|
4444
4518
|
? allEntries
|
|
4445
4519
|
.reverse()
|
|
4446
|
-
.map((e) => e.content)
|
|
4520
|
+
.map((e) => normalizeChangelogLinks(e.content, e))
|
|
4447
4521
|
.join("\n\n")
|
|
4448
4522
|
: "No changelog entries found.";
|
|
4449
4523
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -4510,7 +4584,7 @@ export class InteractiveMode {
|
|
|
4510
4584
|
**Navigation**
|
|
4511
4585
|
| Key | Action |
|
|
4512
4586
|
|-----|--------|
|
|
4513
|
-
| \`${cursorUp}\` / \`${cursorDown}\` / \`${cursorLeft}\` / \`${cursorRight}\` | Move cursor / browse history
|
|
4587
|
+
| \`${cursorUp}\` / \`${cursorDown}\` / \`${cursorLeft}\` / \`${cursorRight}\` | Move cursor / browse history |
|
|
4514
4588
|
| \`${cursorWordLeft}\` / \`${cursorWordRight}\` | Move by word |
|
|
4515
4589
|
| \`${cursorLineStart}\` | Start of line |
|
|
4516
4590
|
| \`${cursorLineEnd}\` | End of line |
|
|
@@ -4727,7 +4801,6 @@ export class InteractiveMode {
|
|
|
4727
4801
|
}
|
|
4728
4802
|
}
|
|
4729
4803
|
stop() {
|
|
4730
|
-
this.unregisterSignalHandlers();
|
|
4731
4804
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
4732
4805
|
this.ui.terminal.setProgress(false);
|
|
4733
4806
|
}
|
|
@@ -4745,6 +4818,7 @@ export class InteractiveMode {
|
|
|
4745
4818
|
this.ui.stop();
|
|
4746
4819
|
this.isInitialized = false;
|
|
4747
4820
|
}
|
|
4821
|
+
this.unregisterSignalHandlers();
|
|
4748
4822
|
}
|
|
4749
4823
|
}
|
|
4750
4824
|
//# sourceMappingURL=interactive-mode.js.map
|
|
@@ -512,46 +512,7 @@ function getAnsiColorLuminance(index) {
|
|
|
512
512
|
export function getThemeForRgbColor(rgb) {
|
|
513
513
|
return getRgbColorLuminance(rgb) >= 0.5 ? "light" : "dark";
|
|
514
514
|
}
|
|
515
|
-
function
|
|
516
|
-
if (!/^[0-9a-f]+$/i.test(channel)) {
|
|
517
|
-
return undefined;
|
|
518
|
-
}
|
|
519
|
-
const max = 16 ** channel.length - 1;
|
|
520
|
-
if (max <= 0) {
|
|
521
|
-
return undefined;
|
|
522
|
-
}
|
|
523
|
-
return Math.round((parseInt(channel, 16) / max) * 255);
|
|
524
|
-
}
|
|
525
|
-
export function parseOsc11BackgroundColor(data) {
|
|
526
|
-
const match = data.match(/^\x1b\]11;([^\x07\x1b]*)(?:\x07|\x1b\\)$/i);
|
|
527
|
-
if (!match) {
|
|
528
|
-
return undefined;
|
|
529
|
-
}
|
|
530
|
-
const value = match[1].trim();
|
|
531
|
-
if (value.startsWith("#")) {
|
|
532
|
-
const hex = value.slice(1);
|
|
533
|
-
if (/^[0-9a-f]{6}$/i.test(hex)) {
|
|
534
|
-
return hexToRgb(value);
|
|
535
|
-
}
|
|
536
|
-
if (/^[0-9a-f]{12}$/i.test(hex)) {
|
|
537
|
-
const r = parseOscHexChannel(hex.slice(0, 4));
|
|
538
|
-
const g = parseOscHexChannel(hex.slice(4, 8));
|
|
539
|
-
const b = parseOscHexChannel(hex.slice(8, 12));
|
|
540
|
-
return r !== undefined && g !== undefined && b !== undefined ? { r, g, b } : undefined;
|
|
541
|
-
}
|
|
542
|
-
return undefined;
|
|
543
|
-
}
|
|
544
|
-
const rgbValue = value.replace(/^rgba?:/i, "");
|
|
545
|
-
const [red, green, blue] = rgbValue.split("/");
|
|
546
|
-
if (red === undefined || green === undefined || blue === undefined) {
|
|
547
|
-
return undefined;
|
|
548
|
-
}
|
|
549
|
-
const r = parseOscHexChannel(red);
|
|
550
|
-
const g = parseOscHexChannel(green);
|
|
551
|
-
const b = parseOscHexChannel(blue);
|
|
552
|
-
return r !== undefined && g !== undefined && b !== undefined ? { r, g, b } : undefined;
|
|
553
|
-
}
|
|
554
|
-
export function detectTerminalBackground(options = {}) {
|
|
515
|
+
export function detectTerminalBackgroundFromEnv(options = {}) {
|
|
555
516
|
const env = options.env ?? process.env;
|
|
556
517
|
const colorfgbg = env.COLORFGBG || "";
|
|
557
518
|
const bg = getColorFgBgBackgroundIndex(colorfgbg);
|
|
@@ -570,8 +531,25 @@ export function detectTerminalBackground(options = {}) {
|
|
|
570
531
|
confidence: "low",
|
|
571
532
|
};
|
|
572
533
|
}
|
|
534
|
+
export async function detectTerminalBackgroundTheme({ ui, timeoutMs, env, }) {
|
|
535
|
+
try {
|
|
536
|
+
const rgb = await ui.queryTerminalBackgroundColor({ timeoutMs });
|
|
537
|
+
if (rgb) {
|
|
538
|
+
return {
|
|
539
|
+
theme: getThemeForRgbColor(rgb),
|
|
540
|
+
source: "terminal background",
|
|
541
|
+
detail: `OSC 11 background rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`,
|
|
542
|
+
confidence: "high",
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
catch {
|
|
547
|
+
// Fall back to environment-based detection when the terminal query fails.
|
|
548
|
+
}
|
|
549
|
+
return detectTerminalBackgroundFromEnv({ env });
|
|
550
|
+
}
|
|
573
551
|
export function getDefaultTheme() {
|
|
574
|
-
return
|
|
552
|
+
return detectTerminalBackgroundFromEnv().theme;
|
|
575
553
|
}
|
|
576
554
|
// ============================================================================
|
|
577
555
|
// Global Theme Instance
|