@nghyane/arcane 0.1.8 → 0.1.11
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/package.json +6 -6
- package/src/config/settings-schema.ts +0 -10
- package/src/discovery/helpers.ts +1 -6
- package/src/index.ts +1 -0
- package/src/main.ts +3 -0
- package/src/memories/index.ts +3 -3
- package/src/modes/components/model-selector.ts +1 -1
- package/src/modes/components/settings-defs.ts +0 -8
- package/src/modes/components/status-line.ts +15 -40
- package/src/modes/components/user-message.ts +2 -0
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/interactive-mode.ts +2 -0
- package/src/modes/theme/dark.json +56 -59
- package/src/modes/theme/defaults/dark-catppuccin.json +47 -56
- package/src/modes/theme/defaults/dark-dracula.json +24 -32
- package/src/modes/theme/defaults/dark-gruvbox.json +53 -74
- package/src/modes/theme/defaults/dark-solarized.json +33 -35
- package/src/modes/theme/defaults/dark-tokyo-night.json +57 -67
- package/src/modes/theme/defaults/index.ts +3 -179
- package/src/modes/theme/defaults/light-catppuccin.json +42 -50
- package/src/modes/theme/defaults/light-github.json +68 -94
- package/src/modes/theme/defaults/light-solarized.json +41 -49
- package/src/modes/theme/light.json +14 -12
- package/src/modes/theme/theme-schema.json +4 -0
- package/src/modes/theme/theme.ts +89 -6
- package/src/patch/applicator.ts +12 -4
- package/src/prompts/agents/task.md +1 -1
- package/src/prompts/system/subagent-system-prompt.md +2 -14
- package/src/prompts/system/system-prompt.md +12 -14
- package/src/prompts/tools/task.md +49 -178
- package/src/prompts/tools/todo-write.md +4 -4
- package/src/sdk.ts +15 -16
- package/src/session/session-manager.ts +1 -3
- package/src/task/executor.ts +2 -2
- package/src/task/index.ts +5 -5
- package/src/task/types.ts +7 -20
- package/src/tools/index.ts +16 -33
- package/src/tools/subagent-tool.ts +5 -5
- package/src/tools/todo-write.ts +0 -37
- package/src/tui/output-block.ts +2 -12
- package/src/modes/theme/defaults/alabaster.json +0 -93
- package/src/modes/theme/defaults/amethyst.json +0 -96
- package/src/modes/theme/defaults/anthracite.json +0 -93
- package/src/modes/theme/defaults/basalt.json +0 -91
- package/src/modes/theme/defaults/birch.json +0 -95
- package/src/modes/theme/defaults/dark-abyss.json +0 -91
- package/src/modes/theme/defaults/dark-arctic.json +0 -104
- package/src/modes/theme/defaults/dark-aurora.json +0 -95
- package/src/modes/theme/defaults/dark-cavern.json +0 -91
- package/src/modes/theme/defaults/dark-copper.json +0 -95
- package/src/modes/theme/defaults/dark-cosmos.json +0 -90
- package/src/modes/theme/defaults/dark-cyberpunk.json +0 -102
- package/src/modes/theme/defaults/dark-eclipse.json +0 -91
- package/src/modes/theme/defaults/dark-ember.json +0 -95
- package/src/modes/theme/defaults/dark-equinox.json +0 -90
- package/src/modes/theme/defaults/dark-forest.json +0 -96
- package/src/modes/theme/defaults/dark-github.json +0 -105
- package/src/modes/theme/defaults/dark-lavender.json +0 -95
- package/src/modes/theme/defaults/dark-lunar.json +0 -89
- package/src/modes/theme/defaults/dark-midnight.json +0 -95
- package/src/modes/theme/defaults/dark-monochrome.json +0 -94
- package/src/modes/theme/defaults/dark-monokai.json +0 -98
- package/src/modes/theme/defaults/dark-nebula.json +0 -90
- package/src/modes/theme/defaults/dark-nord.json +0 -97
- package/src/modes/theme/defaults/dark-ocean.json +0 -101
- package/src/modes/theme/defaults/dark-one.json +0 -100
- package/src/modes/theme/defaults/dark-rainforest.json +0 -91
- package/src/modes/theme/defaults/dark-reef.json +0 -91
- package/src/modes/theme/defaults/dark-retro.json +0 -92
- package/src/modes/theme/defaults/dark-rose-pine.json +0 -96
- package/src/modes/theme/defaults/dark-sakura.json +0 -95
- package/src/modes/theme/defaults/dark-slate.json +0 -95
- package/src/modes/theme/defaults/dark-solstice.json +0 -90
- package/src/modes/theme/defaults/dark-starfall.json +0 -91
- package/src/modes/theme/defaults/dark-sunset.json +0 -99
- package/src/modes/theme/defaults/dark-swamp.json +0 -90
- package/src/modes/theme/defaults/dark-synthwave.json +0 -103
- package/src/modes/theme/defaults/dark-taiga.json +0 -91
- package/src/modes/theme/defaults/dark-terminal.json +0 -95
- package/src/modes/theme/defaults/dark-tundra.json +0 -91
- package/src/modes/theme/defaults/dark-twilight.json +0 -91
- package/src/modes/theme/defaults/dark-volcanic.json +0 -91
- package/src/modes/theme/defaults/graphite.json +0 -92
- package/src/modes/theme/defaults/light-arctic.json +0 -107
- package/src/modes/theme/defaults/light-aurora-day.json +0 -91
- package/src/modes/theme/defaults/light-canyon.json +0 -91
- package/src/modes/theme/defaults/light-cirrus.json +0 -90
- package/src/modes/theme/defaults/light-coral.json +0 -95
- package/src/modes/theme/defaults/light-cyberpunk.json +0 -96
- package/src/modes/theme/defaults/light-dawn.json +0 -90
- package/src/modes/theme/defaults/light-dunes.json +0 -91
- package/src/modes/theme/defaults/light-eucalyptus.json +0 -95
- package/src/modes/theme/defaults/light-forest.json +0 -100
- package/src/modes/theme/defaults/light-frost.json +0 -95
- package/src/modes/theme/defaults/light-glacier.json +0 -91
- package/src/modes/theme/defaults/light-gruvbox.json +0 -108
- package/src/modes/theme/defaults/light-haze.json +0 -90
- package/src/modes/theme/defaults/light-honeycomb.json +0 -95
- package/src/modes/theme/defaults/light-lagoon.json +0 -91
- package/src/modes/theme/defaults/light-lavender.json +0 -95
- package/src/modes/theme/defaults/light-meadow.json +0 -91
- package/src/modes/theme/defaults/light-mint.json +0 -95
- package/src/modes/theme/defaults/light-monochrome.json +0 -101
- package/src/modes/theme/defaults/light-ocean.json +0 -99
- package/src/modes/theme/defaults/light-one.json +0 -99
- package/src/modes/theme/defaults/light-opal.json +0 -91
- package/src/modes/theme/defaults/light-orchard.json +0 -91
- package/src/modes/theme/defaults/light-paper.json +0 -95
- package/src/modes/theme/defaults/light-prism.json +0 -90
- package/src/modes/theme/defaults/light-retro.json +0 -98
- package/src/modes/theme/defaults/light-sand.json +0 -95
- package/src/modes/theme/defaults/light-savanna.json +0 -91
- package/src/modes/theme/defaults/light-soleil.json +0 -90
- package/src/modes/theme/defaults/light-sunset.json +0 -99
- package/src/modes/theme/defaults/light-synthwave.json +0 -98
- package/src/modes/theme/defaults/light-tokyo-night.json +0 -111
- package/src/modes/theme/defaults/light-wetland.json +0 -91
- package/src/modes/theme/defaults/light-zenith.json +0 -89
- package/src/modes/theme/defaults/limestone.json +0 -94
- package/src/modes/theme/defaults/mahogany.json +0 -97
- package/src/modes/theme/defaults/marble.json +0 -93
- package/src/modes/theme/defaults/obsidian.json +0 -91
- package/src/modes/theme/defaults/onyx.json +0 -91
- package/src/modes/theme/defaults/pearl.json +0 -93
- package/src/modes/theme/defaults/porcelain.json +0 -91
- package/src/modes/theme/defaults/quartz.json +0 -96
- package/src/modes/theme/defaults/sandstone.json +0 -95
- package/src/modes/theme/defaults/titanium.json +0 -90
- package/src/prompts/system/subagent-submit-reminder.md +0 -11
- package/src/tools/jtd-to-json-schema.ts +0 -247
- package/src/tools/submit-result.ts +0 -152
|
@@ -2,14 +2,11 @@
|
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/nghyane/arcane/main/packages/coding-agent/theme-schema.json",
|
|
3
3
|
"name": "light-solarized",
|
|
4
4
|
"vars": {
|
|
5
|
-
"base03": "#002b36",
|
|
6
|
-
"base02": "#073642",
|
|
7
|
-
"base01": "#586e75",
|
|
8
|
-
"base00": "#657b83",
|
|
9
|
-
"base0": "#839496",
|
|
10
|
-
"base1": "#93a1a1",
|
|
11
5
|
"base2": "#eee8d5",
|
|
12
6
|
"base3": "#fdf6e3",
|
|
7
|
+
"base00": "#657b83",
|
|
8
|
+
"base01": "#586e75",
|
|
9
|
+
"base1": "#93a1a1",
|
|
13
10
|
"yellow": "#b58900",
|
|
14
11
|
"orange": "#cb4b16",
|
|
15
12
|
"red": "#dc322f",
|
|
@@ -17,86 +14,81 @@
|
|
|
17
14
|
"violet": "#6c71c4",
|
|
18
15
|
"blue": "#268bd2",
|
|
19
16
|
"cyan": "#2aa198",
|
|
20
|
-
"green": "#859900"
|
|
21
|
-
"selectedBg": "#e3dcc8",
|
|
22
|
-
"userMsgBg": "#f5f0e6",
|
|
23
|
-
"toolPendingBg": "#eef4f9",
|
|
24
|
-
"toolSuccessBg": "#eff5ed",
|
|
25
|
-
"toolErrorBg": "#f9eeee",
|
|
26
|
-
"customMsgBg": "#f2eff7"
|
|
17
|
+
"green": "#859900"
|
|
27
18
|
},
|
|
28
19
|
"colors": {
|
|
29
|
-
"accent": "
|
|
30
|
-
"border": "
|
|
31
|
-
"borderAccent": "
|
|
20
|
+
"accent": "blue",
|
|
21
|
+
"border": "cyan",
|
|
22
|
+
"borderAccent": "blue",
|
|
32
23
|
"borderMuted": "base1",
|
|
33
24
|
"success": "green",
|
|
34
25
|
"error": "red",
|
|
35
26
|
"warning": "yellow",
|
|
36
|
-
"muted": "
|
|
27
|
+
"muted": "base00",
|
|
37
28
|
"dim": "base1",
|
|
38
29
|
"text": "",
|
|
39
|
-
"thinkingText": "
|
|
40
|
-
"selectedBg": "
|
|
41
|
-
"userMessageBg": "
|
|
30
|
+
"thinkingText": "base00",
|
|
31
|
+
"selectedBg": "^-2",
|
|
32
|
+
"userMessageBg": "^-2",
|
|
42
33
|
"userMessageText": "",
|
|
43
|
-
"customMessageBg": "
|
|
34
|
+
"customMessageBg": "^-2",
|
|
44
35
|
"customMessageText": "",
|
|
45
|
-
"customMessageLabel": "
|
|
46
|
-
"toolPendingBg": "
|
|
47
|
-
"toolSuccessBg": "
|
|
48
|
-
"toolErrorBg": "
|
|
36
|
+
"customMessageLabel": "blue",
|
|
37
|
+
"toolPendingBg": "^-3",
|
|
38
|
+
"toolSuccessBg": "^-2",
|
|
39
|
+
"toolErrorBg": "^-3",
|
|
49
40
|
"toolTitle": "",
|
|
50
|
-
"toolOutput": "
|
|
41
|
+
"toolOutput": "base00",
|
|
51
42
|
"mdHeading": "yellow",
|
|
52
43
|
"mdLink": "blue",
|
|
53
|
-
"mdLinkUrl": "
|
|
44
|
+
"mdLinkUrl": "base00",
|
|
54
45
|
"mdCode": "cyan",
|
|
55
46
|
"mdCodeBlock": "green",
|
|
56
47
|
"mdCodeBlockBorder": "base1",
|
|
57
|
-
"mdQuote": "
|
|
48
|
+
"mdQuote": "base00",
|
|
58
49
|
"mdQuoteBorder": "base1",
|
|
59
50
|
"mdHr": "base1",
|
|
60
|
-
"mdListBullet": "
|
|
51
|
+
"mdListBullet": "cyan",
|
|
61
52
|
"toolDiffAdded": "green",
|
|
62
53
|
"toolDiffRemoved": "red",
|
|
63
|
-
"toolDiffContext": "
|
|
54
|
+
"toolDiffContext": "base00",
|
|
64
55
|
"link": "blue",
|
|
65
56
|
"syntaxComment": "base1",
|
|
66
|
-
"syntaxKeyword": "
|
|
57
|
+
"syntaxKeyword": "orange",
|
|
67
58
|
"syntaxFunction": "blue",
|
|
68
59
|
"syntaxVariable": "cyan",
|
|
69
|
-
"syntaxString": "
|
|
60
|
+
"syntaxString": "green",
|
|
70
61
|
"syntaxNumber": "magenta",
|
|
71
62
|
"syntaxType": "yellow",
|
|
72
|
-
"syntaxOperator": "
|
|
73
|
-
"syntaxPunctuation": "
|
|
63
|
+
"syntaxOperator": "base01",
|
|
64
|
+
"syntaxPunctuation": "base01",
|
|
74
65
|
"thinkingOff": "base1",
|
|
75
|
-
"thinkingMinimal": "
|
|
76
|
-
"thinkingLow": "
|
|
77
|
-
"thinkingMedium": "
|
|
66
|
+
"thinkingMinimal": "base00",
|
|
67
|
+
"thinkingLow": "cyan",
|
|
68
|
+
"thinkingMedium": "blue",
|
|
78
69
|
"thinkingHigh": "violet",
|
|
79
70
|
"thinkingXhigh": "magenta",
|
|
80
71
|
"bashMode": "green",
|
|
81
|
-
"statusLineBg": "
|
|
72
|
+
"statusLineBg": "^2",
|
|
82
73
|
"statusLineSep": "base1",
|
|
83
|
-
"statusLineModel": "
|
|
74
|
+
"statusLineModel": "blue",
|
|
84
75
|
"statusLinePath": "cyan",
|
|
85
76
|
"statusLineGitClean": "green",
|
|
86
77
|
"statusLineGitDirty": "yellow",
|
|
87
|
-
"statusLineContext": "
|
|
78
|
+
"statusLineContext": "base00",
|
|
88
79
|
"statusLineSpend": "cyan",
|
|
89
|
-
"statusLineStaged":
|
|
90
|
-
"statusLineDirty":
|
|
91
|
-
"statusLineUntracked":
|
|
92
|
-
"statusLineOutput":
|
|
93
|
-
"statusLineCost":
|
|
94
|
-
"statusLineSubagents": "
|
|
95
|
-
"pythonMode": "yellow"
|
|
80
|
+
"statusLineStaged": 64,
|
|
81
|
+
"statusLineDirty": 136,
|
|
82
|
+
"statusLineUntracked": 37,
|
|
83
|
+
"statusLineOutput": 37,
|
|
84
|
+
"statusLineCost": 64,
|
|
85
|
+
"statusLineSubagents": "blue",
|
|
86
|
+
"pythonMode": "yellow",
|
|
87
|
+
"appBg": "^0"
|
|
96
88
|
},
|
|
97
89
|
"export": {
|
|
98
|
-
"pageBg": "
|
|
90
|
+
"pageBg": "#fdf6e3",
|
|
99
91
|
"cardBg": "#ffffff",
|
|
100
|
-
"infoBg": "
|
|
92
|
+
"infoBg": "#eee8d5"
|
|
101
93
|
}
|
|
102
94
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/nghyane/arcane/main/packages/coding-agent/theme-schema.json",
|
|
3
3
|
"name": "light",
|
|
4
4
|
"vars": {
|
|
5
|
-
"teal": "#
|
|
5
|
+
"teal": "#3e8a8a",
|
|
6
6
|
"blue": "#547da7",
|
|
7
7
|
"green": "#588458",
|
|
8
8
|
"red": "#aa5555",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"mdHeading": "yellow",
|
|
44
44
|
"mdLink": "blue",
|
|
45
45
|
"mdLinkUrl": "dimGray",
|
|
46
|
+
"link": "blue",
|
|
46
47
|
"mdCode": "teal",
|
|
47
48
|
"mdCodeBlock": "green",
|
|
48
49
|
"mdCodeBlockBorder": "mediumGray",
|
|
@@ -53,17 +54,17 @@
|
|
|
53
54
|
"toolDiffAdded": "green",
|
|
54
55
|
"toolDiffRemoved": "red",
|
|
55
56
|
"toolDiffContext": "mediumGray",
|
|
56
|
-
"syntaxComment": "#
|
|
57
|
-
"syntaxKeyword": "#
|
|
58
|
-
"syntaxFunction": "#
|
|
59
|
-
"syntaxVariable": "#
|
|
60
|
-
"syntaxString": "#
|
|
61
|
-
"syntaxNumber": "#
|
|
62
|
-
"syntaxType": "#
|
|
63
|
-
"syntaxOperator": "#
|
|
64
|
-
"syntaxPunctuation": "#
|
|
57
|
+
"syntaxComment": "#8a8a8a",
|
|
58
|
+
"syntaxKeyword": "#a626a4",
|
|
59
|
+
"syntaxFunction": "#4078f2",
|
|
60
|
+
"syntaxVariable": "#986801",
|
|
61
|
+
"syntaxString": "#50a14f",
|
|
62
|
+
"syntaxNumber": "#986801",
|
|
63
|
+
"syntaxType": "#c18401",
|
|
64
|
+
"syntaxOperator": "#4078f2",
|
|
65
|
+
"syntaxPunctuation": "#696c77",
|
|
65
66
|
"thinkingOff": "lightGray",
|
|
66
|
-
"thinkingMinimal": "
|
|
67
|
+
"thinkingMinimal": "dimGray",
|
|
67
68
|
"thinkingLow": "blue",
|
|
68
69
|
"thinkingMedium": "teal",
|
|
69
70
|
"thinkingHigh": "#875f87",
|
|
@@ -83,7 +84,8 @@
|
|
|
83
84
|
"statusLineOutput": 133,
|
|
84
85
|
"statusLineCost": 133,
|
|
85
86
|
"statusLineSubagents": "teal",
|
|
86
|
-
"pythonMode": "yellow"
|
|
87
|
+
"pythonMode": "yellow",
|
|
88
|
+
"appBg": "^0"
|
|
87
89
|
},
|
|
88
90
|
"export": {
|
|
89
91
|
"pageBg": "#f8f8f8",
|
|
@@ -315,6 +315,10 @@
|
|
|
315
315
|
"$ref": "#/$defs/colorValue",
|
|
316
316
|
"description": "Status line background"
|
|
317
317
|
},
|
|
318
|
+
"appBg": {
|
|
319
|
+
"$ref": "#/$defs/colorValue",
|
|
320
|
+
"description": "App-wide background color"
|
|
321
|
+
},
|
|
318
322
|
"statusLineSep": {
|
|
319
323
|
"$ref": "#/$defs/colorValue",
|
|
320
324
|
"description": "Status line separator color"
|
package/src/modes/theme/theme.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
supportsLanguage as nativeSupportsLanguage,
|
|
7
7
|
} from "@nghyane/arcane-natives";
|
|
8
8
|
import type { EditorTheme, MarkdownTheme, SelectListTheme, SymbolTheme } from "@nghyane/arcane-tui";
|
|
9
|
-
import { adjustHsv, isEnoent, logger } from "@nghyane/arcane-utils";
|
|
9
|
+
import { adjustHsv, hexToHsv, hsvToHex, isEnoent, logger } from "@nghyane/arcane-utils";
|
|
10
10
|
import { getCustomThemesDir } from "@nghyane/arcane-utils/dirs";
|
|
11
11
|
import { type Static, Type } from "@sinclair/typebox";
|
|
12
12
|
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
@@ -959,7 +959,8 @@ export type ThemeBg =
|
|
|
959
959
|
| "toolPendingBg"
|
|
960
960
|
| "toolSuccessBg"
|
|
961
961
|
| "toolErrorBg"
|
|
962
|
-
| "statusLineBg"
|
|
962
|
+
| "statusLineBg"
|
|
963
|
+
| "appBg";
|
|
963
964
|
|
|
964
965
|
type ColorMode = "truecolor" | "256color";
|
|
965
966
|
|
|
@@ -1015,7 +1016,7 @@ function resolveVarRefs(
|
|
|
1015
1016
|
vars: Record<string, ColorValue>,
|
|
1016
1017
|
visited = new Set<string>(),
|
|
1017
1018
|
): string | number {
|
|
1018
|
-
if (typeof value === "number" || value === "" || value.startsWith("#")) {
|
|
1019
|
+
if (typeof value === "number" || value === "" || value.startsWith("#") || value.startsWith("^")) {
|
|
1019
1020
|
return value;
|
|
1020
1021
|
}
|
|
1021
1022
|
if (visited.has(value)) {
|
|
@@ -1171,10 +1172,28 @@ export class Theme {
|
|
|
1171
1172
|
return `${ansi}${text}\x1b[39m`; // Reset only foreground color
|
|
1172
1173
|
}
|
|
1173
1174
|
|
|
1174
|
-
|
|
1175
|
+
/**
|
|
1176
|
+
* Wrap text with a background color, stabilizing inner SGR resets.
|
|
1177
|
+
* When terminal bg is not detected, uses reverse video as fallback.
|
|
1178
|
+
* This is the single source of truth for bg wrapping — all bg rendering goes through here.
|
|
1179
|
+
*/
|
|
1180
|
+
wrapBg(color: ThemeBg, text: string): string {
|
|
1175
1181
|
const ansi = this.#bgColors[color];
|
|
1176
1182
|
if (!ansi) throw new Error(`Unknown theme background color: ${color}`);
|
|
1177
|
-
|
|
1183
|
+
if (ansi === "\x1b[49m") {
|
|
1184
|
+
// Transparent fallback: reverse video with fg color preservation
|
|
1185
|
+
const stabilized = text
|
|
1186
|
+
.replace(/\x1b\[(?:0)?m/g, m => `${m}\x1b[7m`)
|
|
1187
|
+
.replace(/\x1b\[(?:3[0-9]m|38;)/g, m => `\x1b[27m${m}`);
|
|
1188
|
+
return `\x1b[7m${stabilized}\x1b[27m`;
|
|
1189
|
+
}
|
|
1190
|
+
// Real bg: stabilize inner resets by re-applying bg after them
|
|
1191
|
+
const stabilized = text.replace(/\x1b\[(?:0)?m/g, m => `${m}${ansi}`).replace(/\x1b\[49m/g, m => `${m}${ansi}`);
|
|
1192
|
+
return `${ansi}${stabilized}${this.#bgColors.appBg}`;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
bg(color: ThemeBg, text: string): string {
|
|
1196
|
+
return this.wrapBg(color, text);
|
|
1178
1197
|
}
|
|
1179
1198
|
|
|
1180
1199
|
bold(text: string): string {
|
|
@@ -1209,6 +1228,19 @@ export class Theme {
|
|
|
1209
1228
|
return ansi;
|
|
1210
1229
|
}
|
|
1211
1230
|
|
|
1231
|
+
getAppBgAnsi(): string {
|
|
1232
|
+
return this.#bgColors.appBg;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
getAppBgPackedRgb(): number {
|
|
1236
|
+
const ansi = this.#bgColors.appBg;
|
|
1237
|
+
const match = ansi.match(/\x1b\[48;2;(\d+);(\d+);(\d+)m/);
|
|
1238
|
+
if (!match) return 0;
|
|
1239
|
+
return (
|
|
1240
|
+
((Number(match[1]) & 0xff) << 16) | ((Number(match[2]) & 0xff) << 8) | (Number(match[3]) & 0xff) | 0x01000000
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1212
1244
|
getColorMode(): ColorMode {
|
|
1213
1245
|
return this.mode;
|
|
1214
1246
|
}
|
|
@@ -1563,11 +1595,48 @@ interface CreateThemeOptions {
|
|
|
1563
1595
|
mode?: ColorMode;
|
|
1564
1596
|
symbolPresetOverride?: SymbolPreset;
|
|
1565
1597
|
colorBlindMode?: boolean;
|
|
1598
|
+
terminalBg?: string;
|
|
1566
1599
|
}
|
|
1567
1600
|
|
|
1568
1601
|
/** HSV adjustment to shift green toward blue for colorblind mode (red-green colorblindness) */
|
|
1569
1602
|
const COLORBLIND_ADJUSTMENT = { h: 60, s: 0.71 };
|
|
1570
1603
|
|
|
1604
|
+
/**
|
|
1605
|
+
* Resolve a relative bg color value against the terminal background.
|
|
1606
|
+
* Format: "^N" where N is a brightness adjustment percentage.
|
|
1607
|
+
* Positive = lighter, negative = darker. E.g., "^5" or "^-3".
|
|
1608
|
+
* Returns the resolved hex color, or the original value if not relative.
|
|
1609
|
+
*/
|
|
1610
|
+
function resolveRelativeBg(value: string | number, terminalBg: string): string | number {
|
|
1611
|
+
if (typeof value !== "string" || !value.startsWith("^")) return value;
|
|
1612
|
+
const delta = parseFloat(value.slice(1));
|
|
1613
|
+
if (Number.isNaN(delta)) return value;
|
|
1614
|
+
const hsv = hexToHsv(terminalBg);
|
|
1615
|
+
hsv.v = Math.max(0, Math.min(1, hsv.v + delta / 100));
|
|
1616
|
+
return hsvToHex(hsv);
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
function detectDefaultSymbolPreset(): SymbolPreset {
|
|
1620
|
+
const termProgram = Bun.env.TERM_PROGRAM ?? "";
|
|
1621
|
+
const term = Bun.env.TERM ?? "";
|
|
1622
|
+
|
|
1623
|
+
// Terminals with known Nerd Font fallback support
|
|
1624
|
+
const nerdFontTerminals = new Set([
|
|
1625
|
+
"iTerm.app",
|
|
1626
|
+
"WezTerm",
|
|
1627
|
+
"Hyper",
|
|
1628
|
+
"vscode",
|
|
1629
|
+
"Termius",
|
|
1630
|
+
"WarpTerminal",
|
|
1631
|
+
"ghostty",
|
|
1632
|
+
"Tabby",
|
|
1633
|
+
]);
|
|
1634
|
+
if (nerdFontTerminals.has(termProgram)) return "nerd";
|
|
1635
|
+
if (term === "xterm-kitty") return "nerd";
|
|
1636
|
+
|
|
1637
|
+
return "unicode";
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1571
1640
|
function createTheme(themeJson: ThemeJson, options: CreateThemeOptions = {}): Theme {
|
|
1572
1641
|
const { mode, symbolPresetOverride, colorBlindMode } = options;
|
|
1573
1642
|
const colorMode = mode ?? detectColorMode();
|
|
@@ -1580,6 +1649,15 @@ function createTheme(themeJson: ThemeJson, options: CreateThemeOptions = {}): Th
|
|
|
1580
1649
|
}
|
|
1581
1650
|
}
|
|
1582
1651
|
|
|
1652
|
+
// Resolve relative bg colors (^N format) against terminal background
|
|
1653
|
+
const termBg = options.terminalBg;
|
|
1654
|
+
for (const key of Object.keys(resolvedColors) as Array<keyof typeof resolvedColors>) {
|
|
1655
|
+
const value = resolvedColors[key];
|
|
1656
|
+
if (typeof value === "string" && value.startsWith("^")) {
|
|
1657
|
+
resolvedColors[key] = termBg ? resolveRelativeBg(value, termBg) : "";
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1583
1661
|
const fgColors: Record<ThemeColor, string | number> = {} as Record<ThemeColor, string | number>;
|
|
1584
1662
|
const bgColors: Record<ThemeBg, string | number> = {} as Record<ThemeBg, string | number>;
|
|
1585
1663
|
const bgColorKeys: Set<string> = new Set([
|
|
@@ -1590,6 +1668,7 @@ function createTheme(themeJson: ThemeJson, options: CreateThemeOptions = {}): Th
|
|
|
1590
1668
|
"toolSuccessBg",
|
|
1591
1669
|
"toolErrorBg",
|
|
1592
1670
|
"statusLineBg",
|
|
1671
|
+
"appBg",
|
|
1593
1672
|
]);
|
|
1594
1673
|
for (const [key, value] of Object.entries(resolvedColors)) {
|
|
1595
1674
|
if (bgColorKeys.has(key)) {
|
|
@@ -1599,7 +1678,7 @@ function createTheme(themeJson: ThemeJson, options: CreateThemeOptions = {}): Th
|
|
|
1599
1678
|
}
|
|
1600
1679
|
}
|
|
1601
1680
|
// Extract symbol configuration - settings override takes precedence over theme
|
|
1602
|
-
const symbolPreset: SymbolPreset = symbolPresetOverride ?? themeJson.symbols?.preset ??
|
|
1681
|
+
const symbolPreset: SymbolPreset = symbolPresetOverride ?? themeJson.symbols?.preset ?? detectDefaultSymbolPreset();
|
|
1603
1682
|
const symbolOverrides = themeJson.symbols?.overrides ?? {};
|
|
1604
1683
|
return new Theme(fgColors, bgColors, colorMode, symbolPreset, symbolOverrides);
|
|
1605
1684
|
}
|
|
@@ -1650,6 +1729,7 @@ export function getCurrentThemeName(): string | undefined {
|
|
|
1650
1729
|
}
|
|
1651
1730
|
var currentSymbolPresetOverride: SymbolPreset | undefined;
|
|
1652
1731
|
var currentColorBlindMode: boolean = false;
|
|
1732
|
+
var currentTerminalBg: string | undefined;
|
|
1653
1733
|
var themeWatcher: fs.FSWatcher | undefined;
|
|
1654
1734
|
var sigwinchHandler: (() => void) | undefined;
|
|
1655
1735
|
var autoDetectedTheme: boolean = false;
|
|
@@ -1662,6 +1742,7 @@ function getCurrentThemeOptions(): CreateThemeOptions {
|
|
|
1662
1742
|
return {
|
|
1663
1743
|
symbolPresetOverride: currentSymbolPresetOverride,
|
|
1664
1744
|
colorBlindMode: currentColorBlindMode,
|
|
1745
|
+
terminalBg: currentTerminalBg,
|
|
1665
1746
|
};
|
|
1666
1747
|
}
|
|
1667
1748
|
|
|
@@ -1671,6 +1752,7 @@ export async function initTheme(
|
|
|
1671
1752
|
colorBlindMode?: boolean,
|
|
1672
1753
|
darkTheme?: string,
|
|
1673
1754
|
lightTheme?: string,
|
|
1755
|
+
terminalBg?: string,
|
|
1674
1756
|
): Promise<void> {
|
|
1675
1757
|
autoDetectedTheme = true;
|
|
1676
1758
|
autoDarkTheme = darkTheme ?? "dark";
|
|
@@ -1679,6 +1761,7 @@ export async function initTheme(
|
|
|
1679
1761
|
currentThemeName = name;
|
|
1680
1762
|
currentSymbolPresetOverride = symbolPreset;
|
|
1681
1763
|
currentColorBlindMode = colorBlindMode ?? false;
|
|
1764
|
+
currentTerminalBg = terminalBg;
|
|
1682
1765
|
try {
|
|
1683
1766
|
theme = await loadTheme(name, getCurrentThemeOptions());
|
|
1684
1767
|
if (enableWatcher) {
|
package/src/patch/applicator.ts
CHANGED
|
@@ -890,10 +890,11 @@ function applyCharacterMatch(
|
|
|
890
890
|
const adjustedNewText = adjustIndentation(normalizedOldText, matchOutcome.match.actualText, newText);
|
|
891
891
|
|
|
892
892
|
const warnings: string[] = [];
|
|
893
|
-
if (matchOutcome.
|
|
893
|
+
if (matchOutcome.match && matchOutcome.match.confidence < 0.97) {
|
|
894
894
|
const similarity = Math.round(matchOutcome.match.confidence * 100);
|
|
895
|
+
const qualifier = matchOutcome.dominantFuzzy ? "Dominant fuzzy" : "Fuzzy";
|
|
895
896
|
warnings.push(
|
|
896
|
-
|
|
897
|
+
`${qualifier} match applied in ${path} near line ${matchOutcome.match.startLine} (${similarity}% similar).`,
|
|
897
898
|
);
|
|
898
899
|
}
|
|
899
900
|
|
|
@@ -1152,9 +1153,16 @@ function computeReplacements(
|
|
|
1152
1153
|
|
|
1153
1154
|
const found = searchResult.index;
|
|
1154
1155
|
|
|
1155
|
-
if (
|
|
1156
|
+
if (
|
|
1157
|
+
searchResult.strategy === "prefix" ||
|
|
1158
|
+
searchResult.strategy === "substring" ||
|
|
1159
|
+
searchResult.strategy === "fuzzy" ||
|
|
1160
|
+
searchResult.strategy === "fuzzy-dominant"
|
|
1161
|
+
) {
|
|
1156
1162
|
const similarity = Math.round(searchResult.confidence * 100);
|
|
1157
|
-
warnings.push(
|
|
1163
|
+
warnings.push(
|
|
1164
|
+
`Non-exact match applied in ${path} near line ${found + 1} (${similarity}% similar, strategy: ${searchResult.strategy}).`,
|
|
1165
|
+
);
|
|
1158
1166
|
}
|
|
1159
1167
|
|
|
1160
1168
|
// Reject if match is ambiguous (prefix/substring matching found multiple matches)
|
|
@@ -8,7 +8,7 @@ Finish only the assigned work and return the minimum useful result.
|
|
|
8
8
|
- Avoid full-file reads unless necessary.
|
|
9
9
|
- Prefer edits to existing files over creating new ones.
|
|
10
10
|
- NEVER create documentation files (*.md) unless explicitly requested.
|
|
11
|
-
- When
|
|
11
|
+
- When done, write a concise summary of what you did as your final response. This is your output.
|
|
12
12
|
- Include the smallest relevant code snippet when discussing code or config.
|
|
13
13
|
- Follow the main agent's instructions.
|
|
14
14
|
</directives>
|
|
@@ -11,20 +11,8 @@ For additional parent conversation context, check {{contextFile}} (`tail -100` o
|
|
|
11
11
|
{{/if}}
|
|
12
12
|
|
|
13
13
|
<critical>
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
{{#if outputSchema}}
|
|
17
|
-
- If cannot complete, call `submit_result` with `status="aborted"` and error message. Do not provide success result or pretend completion.
|
|
18
|
-
{{else}}
|
|
19
|
-
- If cannot complete, call `submit_result` with `status="aborted"` and error message. Do not claim success.
|
|
20
|
-
{{/if}}
|
|
21
|
-
{{#if outputSchema}}
|
|
22
|
-
- `data` parameter MUST be valid JSON matching TypeScript interface:
|
|
23
|
-
```ts
|
|
24
|
-
{{jtdToTypeScript outputSchema}}
|
|
25
|
-
```
|
|
26
|
-
{{/if}}
|
|
27
|
-
- If cannot complete, call `submit_result` exactly once with result indicating failure/abort status (use failure/notes field if available). Do not claim success.
|
|
14
|
+
- When done, stop. Your final text response is your output — the parent receives it as the task result.
|
|
15
|
+
- If cannot complete, report failure clearly in your final response. Do not claim success.
|
|
28
16
|
- Do NOT abort due to uncertainty or missing info that can be obtained via tools or repo context. Use `find`/`grep`/`read` first, then proceed with reasonable defaults if multiple options are acceptable.
|
|
29
17
|
- Aborting is only acceptable when truly blocked after exhausting tools and reasonable attempts. If you abort, include what you tried and the exact blocker in the result.
|
|
30
18
|
- Keep going until request is fully fulfilled. This matters.
|
|
@@ -115,8 +115,17 @@ The question is not "does this work?" but "under what conditions? What happens o
|
|
|
115
115
|
- Skip entirely for single-step or trivial requests.
|
|
116
116
|
|
|
117
117
|
{{#has tools "task"}}
|
|
118
|
-
###
|
|
119
|
-
|
|
118
|
+
### Delegation
|
|
119
|
+
You have subagents. Pick the right one:
|
|
120
|
+
- "I need to think through architecture/plan" → **Oracle**
|
|
121
|
+
- "I need to understand unfamiliar code" → **Explore / Librarian**
|
|
122
|
+
- "I know what to do, need parallel execution" → **Task tool**
|
|
123
|
+
|
|
124
|
+
Workflow for complex work: Oracle (plan) → Explore (validate scope) → Task (execute).
|
|
125
|
+
|
|
126
|
+
Task tool is a fire-and-forget executor — a productive junior engineer who cannot ask follow-ups once started. Prompt it with detailed instructions, enumerate deliverables, include constraints and verification steps.
|
|
127
|
+
|
|
128
|
+
Use Task tool when work genuinely forks into independent streams:
|
|
120
129
|
- Editing 4+ files with no dependencies between edits
|
|
121
130
|
- Investigating 2+ independent subsystems
|
|
122
131
|
- Work that decomposes into pieces not needing each other's results
|
|
@@ -231,18 +240,7 @@ Current date: {{date}}
|
|
|
231
240
|
|
|
232
241
|
{{#has tools "task"}}
|
|
233
242
|
<parallel_reflex>
|
|
234
|
-
When work forks, you fork.
|
|
235
|
-
|
|
236
|
-
Notice the sequential habit:
|
|
237
|
-
- Comfort in doing one thing at a time
|
|
238
|
-
- Illusion that order = correctness
|
|
239
|
-
- Assumption that B depends on A
|
|
240
|
-
**Use Task tool when:**
|
|
241
|
-
- Editing 4+ files with no dependencies between edits
|
|
242
|
-
- Investigating 2+ independent subsystems
|
|
243
|
-
- Work decomposes into pieces not needing each other's results
|
|
244
|
-
|
|
245
|
-
Sequential work requires justification. If you cannot articulate why B depends on A → parallelize.
|
|
243
|
+
When work forks, you fork. Sequential work requires justification — if you cannot articulate why B depends on A, parallelize via Task tool.
|
|
246
244
|
</parallel_reflex>
|
|
247
245
|
{{/has}}
|
|
248
246
|
|