@gajae-code/coding-agent 0.5.1 → 0.5.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 +17 -0
- package/README.md +1 -1
- package/dist/types/cli/setup-cli.d.ts +8 -1
- package/dist/types/commands/setup.d.ts +7 -0
- package/dist/types/config/file-lock.d.ts +24 -2
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/models-config-schema.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +62 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +64 -2
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +10 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +29 -0
- package/dist/types/modes/components/provider-onboarding-selector.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +56 -1
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +10 -0
- package/dist/types/modes/theme/defaults/index.d.ts +302 -0
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -1
- package/dist/types/session/history-storage.d.ts +2 -2
- package/dist/types/session/session-manager.d.ts +10 -1
- package/dist/types/setup/credential-import.d.ts +79 -0
- package/dist/types/task/executor.d.ts +1 -0
- package/dist/types/task/render.d.ts +1 -1
- package/dist/types/tools/subagent-render.d.ts +7 -1
- package/dist/types/tools/subagent.d.ts +21 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +5 -0
- package/dist/types/web/search/index.d.ts +4 -4
- package/dist/types/web/search/provider.d.ts +16 -20
- package/dist/types/web/search/providers/base.d.ts +2 -1
- package/dist/types/web/search/providers/openai-compatible.d.ts +9 -0
- package/dist/types/web/search/types.d.ts +14 -2
- package/package.json +7 -7
- package/scripts/build-binary.ts +7 -0
- package/src/cli/args.ts +2 -0
- package/src/cli/fast-help.ts +2 -0
- package/src/cli/setup-cli.ts +138 -3
- package/src/commands/setup.ts +5 -1
- package/src/commands/ultragoal.ts +3 -1
- package/src/config/file-lock-gc.ts +14 -2
- package/src/config/file-lock.ts +54 -12
- package/src/config/model-profile-activation.ts +15 -3
- package/src/config/model-profiles.ts +15 -15
- package/src/config/model-registry.ts +21 -1
- package/src/config/models-config-schema.ts +1 -0
- package/src/config/settings-schema.ts +62 -0
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +30 -8
- package/src/gjc-runtime/deep-interview-recorder.ts +40 -0
- package/src/gjc-runtime/launch-tmux.ts +3 -4
- package/src/gjc-runtime/ralplan-runtime.ts +174 -12
- package/src/gjc-runtime/state-runtime.ts +2 -1
- package/src/gjc-runtime/state-writer.ts +254 -7
- package/src/gjc-runtime/tmux-gc.ts +2 -1
- package/src/gjc-runtime/ultragoal-guard.ts +155 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +1227 -31
- package/src/gjc-runtime/workflow-manifest.generated.json +44 -0
- package/src/gjc-runtime/workflow-manifest.ts +12 -0
- package/src/harness-control-plane/owner.ts +3 -2
- package/src/harness-control-plane/rpc-adapter.ts +1 -1
- package/src/hooks/skill-state.ts +121 -2
- package/src/internal-urls/docs-index.generated.ts +13 -9
- package/src/lsp/defaults.json +1 -0
- package/src/main.ts +14 -4
- package/src/modes/acp/acp-agent.ts +4 -2
- package/src/modes/bridge/bridge-mode.ts +2 -1
- package/src/modes/components/history-search.ts +5 -2
- package/src/modes/components/model-selector.ts +26 -0
- package/src/modes/components/provider-onboarding-selector.ts +6 -1
- package/src/modes/controllers/selector-controller.ts +80 -1
- package/src/modes/interactive-mode.ts +11 -1
- package/src/modes/rpc/rpc-mode.ts +132 -18
- package/src/modes/shared/agent-wire/command-dispatch.ts +5 -2
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +3 -0
- package/src/modes/shared/agent-wire/unattended-session.ts +16 -1
- package/src/modes/theme/defaults/claude-code.json +100 -0
- package/src/modes/theme/defaults/codex.json +100 -0
- package/src/modes/theme/defaults/index.ts +6 -0
- package/src/modes/theme/defaults/opencode.json +102 -0
- package/src/modes/theme/theme.ts +2 -2
- package/src/modes/types.ts +1 -1
- package/src/prompts/agents/executor.md +5 -2
- package/src/sdk.ts +12 -1
- package/src/session/agent-session.ts +22 -11
- package/src/session/history-storage.ts +32 -11
- package/src/session/session-manager.ts +70 -18
- package/src/setup/credential-import.ts +429 -0
- package/src/skill-state/deep-interview-mutation-guard.ts +2 -1
- package/src/task/executor.ts +7 -1
- package/src/task/render.ts +18 -7
- package/src/tools/ask.ts +4 -2
- package/src/tools/cron.ts +1 -1
- package/src/tools/subagent-render.ts +119 -29
- package/src/tools/subagent.ts +147 -7
- package/src/tools/ultragoal-ask-guard.ts +39 -0
- package/src/web/search/index.ts +25 -25
- package/src/web/search/provider.ts +178 -87
- package/src/web/search/providers/base.ts +2 -1
- package/src/web/search/providers/openai-compatible.ts +151 -0
- package/src/web/search/types.ts +47 -22
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/can1357/gajae-code/main/packages/coding-agent/theme-schema.json",
|
|
3
|
+
"name": "claude-code",
|
|
4
|
+
"vars": {
|
|
5
|
+
"bg": "#1a1a1a",
|
|
6
|
+
"surface": "#373737",
|
|
7
|
+
"surfaceSubtle": "#2a2a2a",
|
|
8
|
+
"separator": "#505050",
|
|
9
|
+
"fg": "#ffffff",
|
|
10
|
+
"muted": "#888888",
|
|
11
|
+
"dim": "#666666",
|
|
12
|
+
"brandTerracotta": "#d77757",
|
|
13
|
+
"shimmerTerracotta": "#eb9f7f",
|
|
14
|
+
"toolPink": "#fd5db1",
|
|
15
|
+
"lavender": "#b1b9f9",
|
|
16
|
+
"autoAcceptPurple": "#af87ff",
|
|
17
|
+
"successGreen": "#4eba65",
|
|
18
|
+
"warningAmber": "#ffc107",
|
|
19
|
+
"errorSoftRed": "#ff6b80",
|
|
20
|
+
"diffAddedBg": "#225c2b",
|
|
21
|
+
"diffRemovedBg": "#7a2936",
|
|
22
|
+
"diffRemovedFg": "#ff8fa0"
|
|
23
|
+
},
|
|
24
|
+
"colors": {
|
|
25
|
+
"accent": "brandTerracotta",
|
|
26
|
+
"border": "separator",
|
|
27
|
+
"borderAccent": "toolPink",
|
|
28
|
+
"borderMuted": "dim",
|
|
29
|
+
"success": "successGreen",
|
|
30
|
+
"error": "errorSoftRed",
|
|
31
|
+
"warning": "warningAmber",
|
|
32
|
+
"muted": "muted",
|
|
33
|
+
"dim": "dim",
|
|
34
|
+
"text": "fg",
|
|
35
|
+
"thinkingText": "muted",
|
|
36
|
+
"selectedBg": "surface",
|
|
37
|
+
"userMessageBg": "surface",
|
|
38
|
+
"userMessageText": "fg",
|
|
39
|
+
"customMessageBg": "surfaceSubtle",
|
|
40
|
+
"customMessageText": "fg",
|
|
41
|
+
"customMessageLabel": "brandTerracotta",
|
|
42
|
+
"toolPendingBg": "surfaceSubtle",
|
|
43
|
+
"toolSuccessBg": "diffAddedBg",
|
|
44
|
+
"toolErrorBg": "diffRemovedBg",
|
|
45
|
+
"toolTitle": "fg",
|
|
46
|
+
"toolOutput": "muted",
|
|
47
|
+
"mdHeading": "brandTerracotta",
|
|
48
|
+
"mdLink": "lavender",
|
|
49
|
+
"mdLinkUrl": "muted",
|
|
50
|
+
"mdCode": "shimmerTerracotta",
|
|
51
|
+
"mdCodeBlock": "fg",
|
|
52
|
+
"mdCodeBlockBorder": "toolPink",
|
|
53
|
+
"mdQuote": "muted",
|
|
54
|
+
"mdQuoteBorder": "separator",
|
|
55
|
+
"mdHr": "dim",
|
|
56
|
+
"mdListBullet": "brandTerracotta",
|
|
57
|
+
"toolDiffAdded": "successGreen",
|
|
58
|
+
"toolDiffRemoved": "diffRemovedFg",
|
|
59
|
+
"toolDiffContext": "muted",
|
|
60
|
+
"syntaxComment": "muted",
|
|
61
|
+
"syntaxKeyword": "lavender",
|
|
62
|
+
"syntaxFunction": "shimmerTerracotta",
|
|
63
|
+
"syntaxVariable": "fg",
|
|
64
|
+
"syntaxString": "successGreen",
|
|
65
|
+
"syntaxNumber": "warningAmber",
|
|
66
|
+
"syntaxType": "autoAcceptPurple",
|
|
67
|
+
"syntaxOperator": "toolPink",
|
|
68
|
+
"syntaxPunctuation": "muted",
|
|
69
|
+
"thinkingOff": "dim",
|
|
70
|
+
"thinkingMinimal": "muted",
|
|
71
|
+
"thinkingLow": "shimmerTerracotta",
|
|
72
|
+
"thinkingMedium": "brandTerracotta",
|
|
73
|
+
"thinkingHigh": "toolPink",
|
|
74
|
+
"thinkingXhigh": "errorSoftRed",
|
|
75
|
+
"bashMode": "toolPink",
|
|
76
|
+
"pythonMode": "lavender",
|
|
77
|
+
"statusLineBg": "bg",
|
|
78
|
+
"statusLineSep": "separator",
|
|
79
|
+
"statusLineModel": "brandTerracotta",
|
|
80
|
+
"statusLinePath": "lavender",
|
|
81
|
+
"statusLineGitClean": "successGreen",
|
|
82
|
+
"statusLineGitDirty": "warningAmber",
|
|
83
|
+
"statusLineContext": "lavender",
|
|
84
|
+
"statusLineSpend": "warningAmber",
|
|
85
|
+
"statusLineStaged": "successGreen",
|
|
86
|
+
"statusLineDirty": "warningAmber",
|
|
87
|
+
"statusLineUntracked": "errorSoftRed",
|
|
88
|
+
"statusLineOutput": "fg",
|
|
89
|
+
"statusLineCost": "shimmerTerracotta",
|
|
90
|
+
"statusLineSubagents": "autoAcceptPurple"
|
|
91
|
+
},
|
|
92
|
+
"export": {
|
|
93
|
+
"pageBg": "#1a1a1a",
|
|
94
|
+
"cardBg": "#2a2a2a",
|
|
95
|
+
"infoBg": "#373737"
|
|
96
|
+
},
|
|
97
|
+
"symbols": {
|
|
98
|
+
"preset": "unicode"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/can1357/gajae-code/main/packages/coding-agent/theme-schema.json",
|
|
3
|
+
"name": "codex",
|
|
4
|
+
"vars": {
|
|
5
|
+
"bg": "#0f1115",
|
|
6
|
+
"surface": "#151922",
|
|
7
|
+
"surfaceBright": "#1c2230",
|
|
8
|
+
"selection": "#24313a",
|
|
9
|
+
"fg": "#d7d7d7",
|
|
10
|
+
"muted": "#8a8f98",
|
|
11
|
+
"dim": "#5f6670",
|
|
12
|
+
"borderNeutral": "#343a46",
|
|
13
|
+
"ansiCyan": "#00bcd4",
|
|
14
|
+
"cyanSoft": "#58d5e8",
|
|
15
|
+
"brandMagenta": "#c678dd",
|
|
16
|
+
"magentaSoft": "#d7a4e8",
|
|
17
|
+
"successGreen": "#4caf50",
|
|
18
|
+
"errorRed": "#ef5350",
|
|
19
|
+
"warningOrange": "#f59e0b",
|
|
20
|
+
"diffRemovalRed": "#d84a4a",
|
|
21
|
+
"toolSuccessBg": "#14241a",
|
|
22
|
+
"toolErrorBg": "#2a1718"
|
|
23
|
+
},
|
|
24
|
+
"colors": {
|
|
25
|
+
"accent": "ansiCyan",
|
|
26
|
+
"border": "borderNeutral",
|
|
27
|
+
"borderAccent": "ansiCyan",
|
|
28
|
+
"borderMuted": "dim",
|
|
29
|
+
"success": "successGreen",
|
|
30
|
+
"error": "errorRed",
|
|
31
|
+
"warning": "warningOrange",
|
|
32
|
+
"muted": "muted",
|
|
33
|
+
"dim": "dim",
|
|
34
|
+
"text": "fg",
|
|
35
|
+
"thinkingText": "muted",
|
|
36
|
+
"selectedBg": "selection",
|
|
37
|
+
"userMessageBg": "surface",
|
|
38
|
+
"userMessageText": "fg",
|
|
39
|
+
"customMessageBg": "surface",
|
|
40
|
+
"customMessageText": "fg",
|
|
41
|
+
"customMessageLabel": "brandMagenta",
|
|
42
|
+
"toolPendingBg": "surface",
|
|
43
|
+
"toolSuccessBg": "toolSuccessBg",
|
|
44
|
+
"toolErrorBg": "toolErrorBg",
|
|
45
|
+
"toolTitle": "fg",
|
|
46
|
+
"toolOutput": "muted",
|
|
47
|
+
"mdHeading": "brandMagenta",
|
|
48
|
+
"mdLink": "ansiCyan",
|
|
49
|
+
"mdLinkUrl": "muted",
|
|
50
|
+
"mdCode": "cyanSoft",
|
|
51
|
+
"mdCodeBlock": "fg",
|
|
52
|
+
"mdCodeBlockBorder": "borderNeutral",
|
|
53
|
+
"mdQuote": "muted",
|
|
54
|
+
"mdQuoteBorder": "borderNeutral",
|
|
55
|
+
"mdHr": "dim",
|
|
56
|
+
"mdListBullet": "ansiCyan",
|
|
57
|
+
"toolDiffAdded": "successGreen",
|
|
58
|
+
"toolDiffRemoved": "diffRemovalRed",
|
|
59
|
+
"toolDiffContext": "muted",
|
|
60
|
+
"syntaxComment": "dim",
|
|
61
|
+
"syntaxKeyword": "brandMagenta",
|
|
62
|
+
"syntaxFunction": "cyanSoft",
|
|
63
|
+
"syntaxVariable": "fg",
|
|
64
|
+
"syntaxString": "successGreen",
|
|
65
|
+
"syntaxNumber": "magentaSoft",
|
|
66
|
+
"syntaxType": "ansiCyan",
|
|
67
|
+
"syntaxOperator": "muted",
|
|
68
|
+
"syntaxPunctuation": "dim",
|
|
69
|
+
"thinkingOff": "dim",
|
|
70
|
+
"thinkingMinimal": "muted",
|
|
71
|
+
"thinkingLow": "cyanSoft",
|
|
72
|
+
"thinkingMedium": "ansiCyan",
|
|
73
|
+
"thinkingHigh": "brandMagenta",
|
|
74
|
+
"thinkingXhigh": "errorRed",
|
|
75
|
+
"bashMode": "ansiCyan",
|
|
76
|
+
"pythonMode": "brandMagenta",
|
|
77
|
+
"statusLineBg": "bg",
|
|
78
|
+
"statusLineSep": "dim",
|
|
79
|
+
"statusLineModel": "brandMagenta",
|
|
80
|
+
"statusLinePath": "cyanSoft",
|
|
81
|
+
"statusLineGitClean": "successGreen",
|
|
82
|
+
"statusLineGitDirty": "warningOrange",
|
|
83
|
+
"statusLineContext": "ansiCyan",
|
|
84
|
+
"statusLineSpend": "cyanSoft",
|
|
85
|
+
"statusLineStaged": "successGreen",
|
|
86
|
+
"statusLineDirty": "warningOrange",
|
|
87
|
+
"statusLineUntracked": "diffRemovalRed",
|
|
88
|
+
"statusLineOutput": "fg",
|
|
89
|
+
"statusLineCost": "muted",
|
|
90
|
+
"statusLineSubagents": "brandMagenta"
|
|
91
|
+
},
|
|
92
|
+
"export": {
|
|
93
|
+
"pageBg": "#0f1115",
|
|
94
|
+
"cardBg": "#151922",
|
|
95
|
+
"infoBg": "#1c2230"
|
|
96
|
+
},
|
|
97
|
+
"symbols": {
|
|
98
|
+
"preset": "unicode"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import blue_crab from "./blue-crab.json" with { type: "json" };
|
|
2
|
+
import claude_code from "./claude-code.json" with { type: "json" };
|
|
3
|
+
import codex from "./codex.json" with { type: "json" };
|
|
4
|
+
import opencode from "./opencode.json" with { type: "json" };
|
|
2
5
|
import red_claw from "./red-claw.json" with { type: "json" };
|
|
3
6
|
|
|
4
7
|
export const defaultThemes = {
|
|
5
8
|
"blue-crab": blue_crab,
|
|
9
|
+
"claude-code": claude_code,
|
|
10
|
+
codex,
|
|
11
|
+
opencode,
|
|
6
12
|
"red-claw": red_claw,
|
|
7
13
|
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/can1357/gajae-code/main/packages/coding-agent/theme-schema.json",
|
|
3
|
+
"name": "opencode",
|
|
4
|
+
"vars": {
|
|
5
|
+
"background": "#212121",
|
|
6
|
+
"currentLine": "#252525",
|
|
7
|
+
"selection": "#303030",
|
|
8
|
+
"backgroundDarker": "#121212",
|
|
9
|
+
"foreground": "#e0e0e0",
|
|
10
|
+
"comment": "#6a6a6a",
|
|
11
|
+
"primary": "#fab283",
|
|
12
|
+
"secondary": "#5c9cf5",
|
|
13
|
+
"accentPurple": "#9d7cd8",
|
|
14
|
+
"errorRed": "#e06c75",
|
|
15
|
+
"warningOrange": "#f5a742",
|
|
16
|
+
"successGreen": "#7fd88f",
|
|
17
|
+
"infoCyan": "#56b6c2",
|
|
18
|
+
"emphasizedYellow": "#e5c07b",
|
|
19
|
+
"border": "#4b4c5c",
|
|
20
|
+
"diffAdded": "#478247",
|
|
21
|
+
"diffRemoved": "#7c4444",
|
|
22
|
+
"diffContext": "#a0a0a0",
|
|
23
|
+
"addedBg": "#303a30",
|
|
24
|
+
"removedBg": "#3a3030"
|
|
25
|
+
},
|
|
26
|
+
"colors": {
|
|
27
|
+
"accent": "primary",
|
|
28
|
+
"border": "border",
|
|
29
|
+
"borderAccent": "accentPurple",
|
|
30
|
+
"borderMuted": "comment",
|
|
31
|
+
"success": "successGreen",
|
|
32
|
+
"error": "errorRed",
|
|
33
|
+
"warning": "warningOrange",
|
|
34
|
+
"muted": "comment",
|
|
35
|
+
"dim": "comment",
|
|
36
|
+
"text": "foreground",
|
|
37
|
+
"thinkingText": "diffContext",
|
|
38
|
+
"selectedBg": "selection",
|
|
39
|
+
"userMessageBg": "currentLine",
|
|
40
|
+
"userMessageText": "foreground",
|
|
41
|
+
"customMessageBg": "currentLine",
|
|
42
|
+
"customMessageText": "foreground",
|
|
43
|
+
"customMessageLabel": "primary",
|
|
44
|
+
"toolPendingBg": "currentLine",
|
|
45
|
+
"toolSuccessBg": "addedBg",
|
|
46
|
+
"toolErrorBg": "removedBg",
|
|
47
|
+
"toolTitle": "foreground",
|
|
48
|
+
"toolOutput": "comment",
|
|
49
|
+
"mdHeading": "secondary",
|
|
50
|
+
"mdLink": "primary",
|
|
51
|
+
"mdLinkUrl": "infoCyan",
|
|
52
|
+
"mdCode": "successGreen",
|
|
53
|
+
"mdCodeBlock": "foreground",
|
|
54
|
+
"mdCodeBlockBorder": "border",
|
|
55
|
+
"mdQuote": "emphasizedYellow",
|
|
56
|
+
"mdQuoteBorder": "emphasizedYellow",
|
|
57
|
+
"mdHr": "comment",
|
|
58
|
+
"mdListBullet": "primary",
|
|
59
|
+
"toolDiffAdded": "diffAdded",
|
|
60
|
+
"toolDiffRemoved": "diffRemoved",
|
|
61
|
+
"toolDiffContext": "diffContext",
|
|
62
|
+
"syntaxComment": "comment",
|
|
63
|
+
"syntaxKeyword": "secondary",
|
|
64
|
+
"syntaxFunction": "primary",
|
|
65
|
+
"syntaxVariable": "errorRed",
|
|
66
|
+
"syntaxString": "successGreen",
|
|
67
|
+
"syntaxNumber": "accentPurple",
|
|
68
|
+
"syntaxType": "emphasizedYellow",
|
|
69
|
+
"syntaxOperator": "infoCyan",
|
|
70
|
+
"syntaxPunctuation": "foreground",
|
|
71
|
+
"thinkingOff": "comment",
|
|
72
|
+
"thinkingMinimal": "diffContext",
|
|
73
|
+
"thinkingLow": "infoCyan",
|
|
74
|
+
"thinkingMedium": "secondary",
|
|
75
|
+
"thinkingHigh": "accentPurple",
|
|
76
|
+
"thinkingXhigh": "errorRed",
|
|
77
|
+
"bashMode": "infoCyan",
|
|
78
|
+
"pythonMode": "accentPurple",
|
|
79
|
+
"statusLineBg": "backgroundDarker",
|
|
80
|
+
"statusLineSep": "border",
|
|
81
|
+
"statusLineModel": "primary",
|
|
82
|
+
"statusLinePath": "secondary",
|
|
83
|
+
"statusLineGitClean": "successGreen",
|
|
84
|
+
"statusLineGitDirty": "warningOrange",
|
|
85
|
+
"statusLineContext": "infoCyan",
|
|
86
|
+
"statusLineSpend": "emphasizedYellow",
|
|
87
|
+
"statusLineStaged": "diffAdded",
|
|
88
|
+
"statusLineDirty": "warningOrange",
|
|
89
|
+
"statusLineUntracked": "errorRed",
|
|
90
|
+
"statusLineOutput": "foreground",
|
|
91
|
+
"statusLineCost": "primary",
|
|
92
|
+
"statusLineSubagents": "accentPurple"
|
|
93
|
+
},
|
|
94
|
+
"export": {
|
|
95
|
+
"pageBg": "#121212",
|
|
96
|
+
"cardBg": "#212121",
|
|
97
|
+
"infoBg": "#252525"
|
|
98
|
+
},
|
|
99
|
+
"symbols": {
|
|
100
|
+
"preset": "unicode"
|
|
101
|
+
}
|
|
102
|
+
}
|
package/src/modes/theme/theme.ts
CHANGED
|
@@ -810,7 +810,7 @@ const colorValueSchema = z.union([
|
|
|
810
810
|
|
|
811
811
|
type ColorValue = z.infer<typeof colorValueSchema>;
|
|
812
812
|
|
|
813
|
-
const THEME_COLOR_KEYS = [
|
|
813
|
+
export const THEME_COLOR_KEYS = [
|
|
814
814
|
"accent",
|
|
815
815
|
"border",
|
|
816
816
|
"borderAccent",
|
|
@@ -1648,7 +1648,7 @@ async function loadThemeJson(name: string): Promise<ThemeJson> {
|
|
|
1648
1648
|
errorMessage += `\nMissing required color tokens:\n`;
|
|
1649
1649
|
errorMessage += missingColors.map(c => ` - ${c}`).join("\n");
|
|
1650
1650
|
errorMessage += `\n\nPlease add these colors to your theme's "colors" object.`;
|
|
1651
|
-
errorMessage += `\nSee the built-in themes
|
|
1651
|
+
errorMessage += `\nSee the built-in themes under src/modes/theme/defaults/ for reference values.`;
|
|
1652
1652
|
}
|
|
1653
1653
|
if (otherErrors.length > 0) {
|
|
1654
1654
|
errorMessage += `\n\nOther errors:\n${otherErrors.join("\n")}`;
|
package/src/modes/types.ts
CHANGED
|
@@ -109,7 +109,7 @@ export interface InteractiveModeContext {
|
|
|
109
109
|
retryLoader: Loader | undefined;
|
|
110
110
|
autoCompactionEscapeHandler?: () => void;
|
|
111
111
|
retryEscapeHandler?: () => void;
|
|
112
|
-
retryCountdownTimer?:
|
|
112
|
+
retryCountdownTimer?: NodeJS.Timeout;
|
|
113
113
|
unsubscribe?: () => void;
|
|
114
114
|
onInputCallback?: (input: SubmittedUserInput) => void;
|
|
115
115
|
optimisticUserMessageSignature: string | undefined;
|
|
@@ -36,10 +36,13 @@ This mode activates only when the assignment explicitly labels Executor as Ultra
|
|
|
36
36
|
|
|
37
37
|
When active:
|
|
38
38
|
- Start from the approved plan/spec/acceptance criteria, then user-facing contracts, then implementation code only as supporting evidence. Treat plan/code mismatches as blockers.
|
|
39
|
-
- Exercise the real user-facing invocation rather than inspecting internals alone: GUI/web
|
|
39
|
+
- Exercise the real user-facing invocation rather than inspecting internals alone. Live artifacts must be runtime-valid: GUI/web needs a real automation transcript plus non-uniform screenshot; CLI needs executed argv-only replay; native/desktop/TUI needs a real screenshot, PTY capture with control codes, or app-automation transcript. `inlineEvidence` is supplemental only and is never sole proof for live surfaces.
|
|
40
|
+
- For CLI evidence, emit argv-only replay JSON with `schemaVersion: 1`, `kind: "cli-replay"`, `replaySafe: true`, and `command` as a string array. Use only allowlisted deterministic executables/arguments, or mark unsafe/non-deterministic commands with audited `replayExempt` metadata plus a valid structural fallback artifact.
|
|
41
|
+
- Native/TUI evidence must be structural, not prose-only: screenshot, app transcript, or PTY artifact with terminal control codes.
|
|
42
|
+
- Do not call the `ask` tool while an Ultragoal run is active; record unresolved decisions with `gjc ultragoal record-review-blockers`.
|
|
40
43
|
- Try to break the work with adversarial cases, not just happy-path confirmations.
|
|
41
44
|
- Report the QA matrix with the final field names `executorQa.contractCoverage`, `executorQa.surfaceEvidence`, `executorQa.adversarialCases`, and `executorQa.artifactRefs`.
|
|
42
|
-
- Include artifact refs for every executed surface and adversarial case: transcript ids, log paths, screenshots, image verdicts, test outputs, or other durable evidence.
|
|
45
|
+
- Include artifact refs for every executed surface and adversarial case: transcript ids, log paths, screenshots, image verdicts, CLI replay records, PTY captures, test outputs, or other durable evidence.
|
|
43
46
|
- Use `status: "not_applicable"` only for rows in `executorQa.contractCoverage` and `executorQa.surfaceEvidence`; each not-applicable row requires `contractRef` plus `reason`. `executorQa.adversarialCases` rows cannot be not-applicable.
|
|
44
47
|
- Report blockers for any missing plan/spec/acceptance source, contract ambiguity, plan/code mismatch, untestable surface, failed adversarial case, shallow evidence, or missing artifact ref.
|
|
45
48
|
</ultragoal_red_team_mode>
|
package/src/sdk.ts
CHANGED
|
@@ -115,6 +115,7 @@ import {
|
|
|
115
115
|
FindTool,
|
|
116
116
|
getSearchTools,
|
|
117
117
|
HIDDEN_TOOLS,
|
|
118
|
+
isConfigurableSearchProviderId,
|
|
118
119
|
isSearchProviderPreference,
|
|
119
120
|
type LspStartupServerInfo,
|
|
120
121
|
loadSshTool,
|
|
@@ -124,6 +125,7 @@ import {
|
|
|
124
125
|
SearchTool,
|
|
125
126
|
setPreferredImageProvider,
|
|
126
127
|
setPreferredSearchProvider,
|
|
128
|
+
setSearchFallbackProviders,
|
|
127
129
|
type Tool,
|
|
128
130
|
type ToolSession,
|
|
129
131
|
WebSearchTool,
|
|
@@ -133,6 +135,7 @@ import {
|
|
|
133
135
|
import { ToolContextStore } from "./tools/context";
|
|
134
136
|
import { getImageGenTools } from "./tools/image-gen";
|
|
135
137
|
import { wrapToolWithMetaNotice } from "./tools/output-meta";
|
|
138
|
+
import { guardToolForUltragoalAsk } from "./tools/ultragoal-ask-guard";
|
|
136
139
|
import { EventBus } from "./utils/event-bus";
|
|
137
140
|
import { buildNamedToolChoice, buildNamedToolChoiceResult } from "./utils/tool-choice";
|
|
138
141
|
import { buildWorkspaceTree, type WorkspaceTree } from "./workspace-tree";
|
|
@@ -865,6 +868,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
865
868
|
if (typeof webSearchProvider === "string" && isSearchProviderPreference(webSearchProvider)) {
|
|
866
869
|
setPreferredSearchProvider(webSearchProvider);
|
|
867
870
|
}
|
|
871
|
+
const webSearchFallback = settings.get("web_search.fallback");
|
|
872
|
+
if (Array.isArray(webSearchFallback)) {
|
|
873
|
+
setSearchFallbackProviders(
|
|
874
|
+
webSearchFallback.filter(value => typeof value === "string" && isConfigurableSearchProviderId(value)),
|
|
875
|
+
);
|
|
876
|
+
}
|
|
868
877
|
|
|
869
878
|
const imageProvider = settings.get("providers.image");
|
|
870
879
|
if (
|
|
@@ -1806,7 +1815,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1806
1815
|
|
|
1807
1816
|
const initialTools = initialToolNames
|
|
1808
1817
|
.map(name => toolRegistry.get(name))
|
|
1809
|
-
.filter((tool): tool is AgentTool => tool !== undefined)
|
|
1818
|
+
.filter((tool): tool is AgentTool => tool !== undefined)
|
|
1819
|
+
// AgentSession tool wrapping is not installed until after Agent construction.
|
|
1820
|
+
.map(tool => guardToolForUltragoalAsk(tool, () => sessionManager.getCwd()));
|
|
1810
1821
|
|
|
1811
1822
|
const openaiWebsocketSetting = settings.get("providers.openaiWebsockets") ?? "off";
|
|
1812
1823
|
const preferOpenAICodexWebsockets =
|
|
@@ -240,6 +240,7 @@ import { normalizeLocalScheme, resolveToCwd } from "../tools/path-utils";
|
|
|
240
240
|
import { getLatestTodoPhasesFromEntries, type TodoItem, type TodoPhase } from "../tools/todo-write";
|
|
241
241
|
import { ToolAbortError, ToolError } from "../tools/tool-errors";
|
|
242
242
|
import { clampTimeout } from "../tools/tool-timeouts";
|
|
243
|
+
import { guardToolForUltragoalAsk } from "../tools/ultragoal-ask-guard";
|
|
243
244
|
import { parseCommandArgs } from "../utils/command-args";
|
|
244
245
|
import { type EditMode, resolveEditMode } from "../utils/edit-mode";
|
|
245
246
|
import { resolveFileDisplayMode } from "../utils/file-display-mode";
|
|
@@ -1186,6 +1187,7 @@ export class AgentSession {
|
|
|
1186
1187
|
};
|
|
1187
1188
|
this.agent.setProviderResponseInterceptor(this.#onResponse);
|
|
1188
1189
|
this.agent.setRawSseEventInterceptor(this.#onSseEvent);
|
|
1190
|
+
this.#setGuardedAgentTools(this.agent.state.tools);
|
|
1189
1191
|
this.yieldQueue = new YieldQueue({
|
|
1190
1192
|
isStreaming: () => this.isStreaming,
|
|
1191
1193
|
injectStreaming: message => this.agent.followUp(message),
|
|
@@ -3690,6 +3692,16 @@ export class AgentSession {
|
|
|
3690
3692
|
}) as T;
|
|
3691
3693
|
}
|
|
3692
3694
|
|
|
3695
|
+
#prepareToolForExecution<T extends AgentTool>(tool: T): T {
|
|
3696
|
+
return this.#wrapToolForDeepInterviewMutationGuard(
|
|
3697
|
+
this.#wrapToolForAcpPermission(guardToolForUltragoalAsk(tool, () => this.sessionManager.getCwd())),
|
|
3698
|
+
);
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3701
|
+
#setGuardedAgentTools(tools: AgentTool[]): void {
|
|
3702
|
+
this.agent.setTools(tools.map(tool => this.#prepareToolForExecution(tool)));
|
|
3703
|
+
}
|
|
3704
|
+
|
|
3693
3705
|
async #applyActiveToolsByName(
|
|
3694
3706
|
toolNames: string[],
|
|
3695
3707
|
options?: { persistMCPSelection?: boolean; previousSelectedMCPToolNames?: string[] },
|
|
@@ -3701,7 +3713,7 @@ export class AgentSession {
|
|
|
3701
3713
|
for (const name of toolNames) {
|
|
3702
3714
|
const tool = this.#toolRegistry.get(name);
|
|
3703
3715
|
if (tool) {
|
|
3704
|
-
tools.push(
|
|
3716
|
+
tools.push(tool);
|
|
3705
3717
|
validToolNames.push(name);
|
|
3706
3718
|
}
|
|
3707
3719
|
}
|
|
@@ -3718,7 +3730,7 @@ export class AgentSession {
|
|
|
3718
3730
|
this.#selectedDiscoveredToolNames.delete(name);
|
|
3719
3731
|
}
|
|
3720
3732
|
}
|
|
3721
|
-
this
|
|
3733
|
+
this.#setGuardedAgentTools(tools);
|
|
3722
3734
|
|
|
3723
3735
|
// Active tool set changed → discoverable tool list (which excludes already-active tools)
|
|
3724
3736
|
// is now stale. Invalidate before any prompt-template hook reads the discovery list.
|
|
@@ -3976,6 +3988,9 @@ export class AgentSession {
|
|
|
3976
3988
|
if (uniqueToolNames.size !== nextToolNames.length) {
|
|
3977
3989
|
throw new Error("RPC host tool names must be unique");
|
|
3978
3990
|
}
|
|
3991
|
+
if (uniqueToolNames.has("ask")) {
|
|
3992
|
+
throw new Error('RPC host tool "ask" is reserved and cannot be supplied by the host');
|
|
3993
|
+
}
|
|
3979
3994
|
|
|
3980
3995
|
for (const name of uniqueToolNames) {
|
|
3981
3996
|
if (this.#toolRegistry.has(name) && !this.#rpcHostToolNames.has(name)) {
|
|
@@ -4303,11 +4318,8 @@ export class AgentSession {
|
|
|
4303
4318
|
this.#toolRegistry.set(finalTool.name, finalTool);
|
|
4304
4319
|
|
|
4305
4320
|
if (!this.getActiveToolNames().includes(finalTool.name)) {
|
|
4306
|
-
const activeTools = [
|
|
4307
|
-
|
|
4308
|
-
this.#wrapToolForDeepInterviewMutationGuard(this.#wrapToolForAcpPermission(finalTool)),
|
|
4309
|
-
];
|
|
4310
|
-
this.agent.setTools(activeTools);
|
|
4321
|
+
const activeTools = [...this.agent.state.tools, finalTool];
|
|
4322
|
+
this.#setGuardedAgentTools(activeTools);
|
|
4311
4323
|
this.#invalidateDiscoveryCaches();
|
|
4312
4324
|
void this.refreshBaseSystemPrompt().catch(error => {
|
|
4313
4325
|
logger.warn("Failed to refresh system prompt after workflow gate ask tool registration", {
|
|
@@ -4339,9 +4351,8 @@ export class AgentSession {
|
|
|
4339
4351
|
const activeToolNames = this.getActiveToolNames();
|
|
4340
4352
|
const activeTools = activeToolNames
|
|
4341
4353
|
.map(name => this.#toolRegistry.get(name))
|
|
4342
|
-
.filter((tool): tool is AgentTool => tool !== undefined)
|
|
4343
|
-
|
|
4344
|
-
this.agent.setTools(activeTools);
|
|
4354
|
+
.filter((tool): tool is AgentTool => tool !== undefined);
|
|
4355
|
+
this.#setGuardedAgentTools(activeTools);
|
|
4345
4356
|
}
|
|
4346
4357
|
|
|
4347
4358
|
getCheckpointState(): CheckpointState | undefined {
|
|
@@ -9174,7 +9185,7 @@ export class AgentSession {
|
|
|
9174
9185
|
error: String(mcpError),
|
|
9175
9186
|
});
|
|
9176
9187
|
this.#selectedMCPToolNames = new Set(previousSelectedMCPToolNames);
|
|
9177
|
-
this
|
|
9188
|
+
this.#setGuardedAgentTools(previousTools);
|
|
9178
9189
|
this.#baseSystemPrompt = previousBaseSystemPrompt;
|
|
9179
9190
|
this.agent.setSystemPrompt(previousSystemPrompt);
|
|
9180
9191
|
}
|
|
@@ -67,10 +67,14 @@ export class HistoryStorage {
|
|
|
67
67
|
// Prepared statements
|
|
68
68
|
#insertRowStmt: Statement;
|
|
69
69
|
#recentStmt: Statement;
|
|
70
|
+
#recentByCwdStmt: Statement;
|
|
70
71
|
#searchStmt: Statement;
|
|
72
|
+
#searchByCwdStmt: Statement;
|
|
71
73
|
#lastPromptStmt: Statement;
|
|
72
74
|
// Cache substring-fallback prepared statements keyed by token count.
|
|
73
75
|
#substringStmts = new Map<number, Statement>();
|
|
76
|
+
// Cache cwd-filtered substring-fallback statements keyed by token count.
|
|
77
|
+
#substringCwdStmts = new Map<number, Statement>();
|
|
74
78
|
|
|
75
79
|
// In-memory cache of last prompt to avoid sync DB reads on add
|
|
76
80
|
#lastPromptCache: string | null = null;
|
|
@@ -94,6 +98,7 @@ CREATE TABLE IF NOT EXISTS history (
|
|
|
94
98
|
cwd TEXT
|
|
95
99
|
);
|
|
96
100
|
CREATE INDEX IF NOT EXISTS idx_history_created_at ON history(created_at DESC);
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_history_cwd_created_at ON history(cwd, created_at DESC);
|
|
97
102
|
|
|
98
103
|
CREATE VIRTUAL TABLE IF NOT EXISTS history_fts USING fts5(prompt, content='history', content_rowid='id');
|
|
99
104
|
|
|
@@ -117,9 +122,15 @@ CREATE TRIGGER IF NOT EXISTS history_ai AFTER INSERT ON history BEGIN
|
|
|
117
122
|
this.#recentStmt = this.#db.prepare(
|
|
118
123
|
"SELECT id, prompt, created_at, cwd FROM history ORDER BY created_at DESC, id DESC LIMIT ?",
|
|
119
124
|
);
|
|
125
|
+
this.#recentByCwdStmt = this.#db.prepare(
|
|
126
|
+
"SELECT id, prompt, created_at, cwd FROM history WHERE cwd = ? ORDER BY created_at DESC, id DESC LIMIT ?",
|
|
127
|
+
);
|
|
120
128
|
this.#searchStmt = this.#db.prepare(
|
|
121
129
|
"SELECT h.id, h.prompt, h.created_at, h.cwd FROM history_fts f JOIN history h ON h.id = f.rowid WHERE history_fts MATCH ? ORDER BY h.created_at DESC, h.id DESC LIMIT ?",
|
|
122
130
|
);
|
|
131
|
+
this.#searchByCwdStmt = this.#db.prepare(
|
|
132
|
+
"SELECT h.id, h.prompt, h.created_at, h.cwd FROM history_fts f JOIN history h ON h.id = f.rowid WHERE history_fts MATCH ? AND h.cwd = ? ORDER BY h.created_at DESC, h.id DESC LIMIT ?",
|
|
133
|
+
);
|
|
123
134
|
this.#lastPromptStmt = this.#db.prepare("SELECT prompt FROM history ORDER BY id DESC LIMIT 1");
|
|
124
135
|
|
|
125
136
|
this.#insertRowStmt = this.#db.prepare("INSERT INTO history (prompt, cwd) VALUES (?, ?)");
|
|
@@ -158,12 +169,14 @@ CREATE TRIGGER IF NOT EXISTS history_ai AFTER INSERT ON history BEGIN
|
|
|
158
169
|
});
|
|
159
170
|
}
|
|
160
171
|
|
|
161
|
-
getRecent(limit: number): HistoryEntry[] {
|
|
172
|
+
getRecent(limit: number, cwd?: string): HistoryEntry[] {
|
|
162
173
|
const safeLimit = this.#normalizeLimit(limit);
|
|
163
174
|
if (safeLimit === 0) return [];
|
|
164
175
|
|
|
165
176
|
try {
|
|
166
|
-
const rows =
|
|
177
|
+
const rows = (
|
|
178
|
+
cwd === undefined ? this.#recentStmt.all(safeLimit) : this.#recentByCwdStmt.all(cwd, safeLimit)
|
|
179
|
+
) as HistoryRow[];
|
|
167
180
|
return rows.map(row => this.#toEntry(row));
|
|
168
181
|
} catch (error) {
|
|
169
182
|
logger.error("HistoryStorage getRecent failed", { error: String(error) });
|
|
@@ -171,7 +184,7 @@ CREATE TRIGGER IF NOT EXISTS history_ai AFTER INSERT ON history BEGIN
|
|
|
171
184
|
}
|
|
172
185
|
}
|
|
173
186
|
|
|
174
|
-
search(query: string, limit: number): HistoryEntry[] {
|
|
187
|
+
search(query: string, limit: number, cwd?: string): HistoryEntry[] {
|
|
175
188
|
const safeLimit = this.#normalizeLimit(limit);
|
|
176
189
|
if (safeLimit === 0) return [];
|
|
177
190
|
|
|
@@ -184,7 +197,11 @@ CREATE TRIGGER IF NOT EXISTS history_ai AFTER INSERT ON history BEGIN
|
|
|
184
197
|
const ftsQuery = tokens.map(tok => `"${tok.replace(/"/g, '""')}"*`).join(" ");
|
|
185
198
|
let ftsRows: HistoryRow[] = [];
|
|
186
199
|
try {
|
|
187
|
-
ftsRows =
|
|
200
|
+
ftsRows = (
|
|
201
|
+
cwd === undefined
|
|
202
|
+
? this.#searchStmt.all(ftsQuery, safeLimit)
|
|
203
|
+
: this.#searchByCwdStmt.all(ftsQuery, cwd, safeLimit)
|
|
204
|
+
) as HistoryRow[];
|
|
188
205
|
} catch (error) {
|
|
189
206
|
// Malformed FTS expression - fall through to substring path.
|
|
190
207
|
logger.debug("HistoryStorage FTS query failed, using substring only", { error: String(error) });
|
|
@@ -199,7 +216,7 @@ CREATE TRIGGER IF NOT EXISTS history_ai AFTER INSERT ON history BEGIN
|
|
|
199
216
|
// by safeLimit, ordered by recency - no full-table load into JS.
|
|
200
217
|
let subRows: HistoryRow[] = [];
|
|
201
218
|
try {
|
|
202
|
-
subRows = this.#searchSubstring(tokens, safeLimit);
|
|
219
|
+
subRows = this.#searchSubstring(tokens, safeLimit, cwd);
|
|
203
220
|
} catch (error) {
|
|
204
221
|
logger.error("HistoryStorage substring search failed", { error: String(error) });
|
|
205
222
|
}
|
|
@@ -250,6 +267,7 @@ CREATE TABLE history (
|
|
|
250
267
|
cwd TEXT
|
|
251
268
|
);
|
|
252
269
|
CREATE INDEX IF NOT EXISTS idx_history_created_at ON history(created_at DESC);
|
|
270
|
+
CREATE INDEX IF NOT EXISTS idx_history_cwd_created_at ON history(cwd, created_at DESC);
|
|
253
271
|
INSERT INTO history (id, prompt, created_at, cwd)
|
|
254
272
|
SELECT id, prompt, created_at, cwd
|
|
255
273
|
FROM history_legacy;
|
|
@@ -282,21 +300,24 @@ END;
|
|
|
282
300
|
.filter(tok => tok.length > 0);
|
|
283
301
|
}
|
|
284
302
|
|
|
285
|
-
#searchSubstring(tokens: string[], limit: number): HistoryRow[] {
|
|
286
|
-
const stmt = this.#getSubstringStmt(tokens.length);
|
|
303
|
+
#searchSubstring(tokens: string[], limit: number, cwd?: string): HistoryRow[] {
|
|
304
|
+
const stmt = this.#getSubstringStmt(tokens.length, cwd !== undefined);
|
|
287
305
|
const params: unknown[] = tokens.map(tok => `%${escapeLikePattern(tok)}%`);
|
|
306
|
+
if (cwd !== undefined) params.push(cwd);
|
|
288
307
|
params.push(limit);
|
|
289
308
|
return stmt.all(...(params as [string, ...unknown[]])) as HistoryRow[];
|
|
290
309
|
}
|
|
291
310
|
|
|
292
|
-
#getSubstringStmt(tokenCount: number): Statement {
|
|
293
|
-
|
|
311
|
+
#getSubstringStmt(tokenCount: number, withCwd: boolean): Statement {
|
|
312
|
+
const cache = withCwd ? this.#substringCwdStmts : this.#substringStmts;
|
|
313
|
+
let stmt = cache.get(tokenCount);
|
|
294
314
|
if (stmt) return stmt;
|
|
295
315
|
const whereClause = Array(tokenCount).fill("prompt LIKE ? ESCAPE '\\' COLLATE NOCASE").join(" AND ");
|
|
316
|
+
const cwdClause = withCwd ? " AND cwd = ?" : "";
|
|
296
317
|
stmt = this.#db.prepare(
|
|
297
|
-
`SELECT id, prompt, created_at, cwd FROM history WHERE ${whereClause} ORDER BY created_at DESC, id DESC LIMIT ?`,
|
|
318
|
+
`SELECT id, prompt, created_at, cwd FROM history WHERE ${whereClause}${cwdClause} ORDER BY created_at DESC, id DESC LIMIT ?`,
|
|
298
319
|
);
|
|
299
|
-
|
|
320
|
+
cache.set(tokenCount, stmt);
|
|
300
321
|
return stmt;
|
|
301
322
|
}
|
|
302
323
|
|