@gajae-code/coding-agent 0.2.3 → 0.2.5
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 +34 -8600
- package/README.md +1 -1
- package/dist/types/async/job-manager.d.ts +61 -0
- package/dist/types/cli/update-cli.d.ts +3 -0
- package/dist/types/config/settings-schema.d.ts +27 -3
- package/dist/types/config/settings.d.ts +1 -1
- package/dist/types/defaults/gjc-defaults.d.ts +19 -6
- package/dist/types/discovery/helpers.d.ts +1 -0
- package/dist/types/exec/bash-executor.d.ts +8 -1
- package/dist/types/gjc-runtime/restricted-role-agent-bash.d.ts +2 -0
- package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -1
- package/dist/types/modes/components/settings-selector.d.ts +4 -0
- package/dist/types/modes/components/skill-hud/render.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- package/dist/types/modes/theme/defaults/index.d.ts +45 -9351
- package/dist/types/modes/theme/theme.d.ts +6 -5
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/skill-state/active-state.d.ts +1 -0
- package/dist/types/task/types.d.ts +1 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +5 -0
- package/dist/types/tools/bash.d.ts +24 -0
- package/dist/types/tools/cron.d.ts +110 -0
- package/dist/types/tools/index.d.ts +4 -0
- package/dist/types/tools/monitor.d.ts +54 -0
- package/dist/types/web/search/index.d.ts +1 -0
- package/dist/types/web/search/provider.d.ts +11 -4
- package/dist/types/web/search/providers/duckduckgo.d.ts +57 -0
- package/dist/types/web/search/types.d.ts +1 -1
- package/package.json +7 -7
- package/src/async/job-manager.ts +224 -0
- package/src/cli/agents-cli.ts +3 -0
- package/src/cli/update-cli.ts +67 -16
- package/src/config/settings-schema.ts +30 -2
- package/src/config/settings.ts +44 -7
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +48 -6
- package/src/defaults/gjc/skills/deep-interview/auto-answer-uncertain.md +37 -0
- package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +42 -0
- package/src/defaults/gjc/skills/ralplan/SKILL.md +8 -4
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +9 -6
- package/src/defaults/gjc-defaults.ts +68 -16
- package/src/discovery/helpers.ts +5 -0
- package/src/eval/js/shared/rewrite-imports.ts +1 -2
- package/src/exec/bash-executor.ts +20 -9
- package/src/gjc-runtime/deep-interview-runtime.ts +44 -0
- package/src/gjc-runtime/ralplan-runtime.ts +2 -0
- package/src/gjc-runtime/restricted-role-agent-bash.ts +5 -0
- package/src/gjc-runtime/state-runtime.ts +3 -2
- package/src/goals/tools/goal-tool.ts +5 -1
- package/src/hooks/skill-state.ts +1 -1
- package/src/internal-urls/docs-index.generated.ts +8 -4
- package/src/lsp/render.ts +1 -1
- package/src/memories/index.ts +5 -4
- package/src/modes/acp/acp-agent.ts +1 -1
- package/src/modes/acp/acp-client-bridge.ts +1 -1
- package/src/modes/components/agent-dashboard.ts +1 -1
- package/src/modes/components/diff.ts +2 -2
- package/src/modes/components/settings-selector.ts +25 -14
- package/src/modes/components/skill-hud/render.ts +7 -2
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +10 -2
- package/src/modes/controllers/selector-controller.ts +67 -0
- package/src/modes/interactive-mode.ts +34 -3
- package/src/modes/theme/defaults/blue-crab.json +126 -0
- package/src/modes/theme/defaults/index.ts +2 -196
- package/src/modes/theme/theme.ts +75 -36
- package/src/modes/types.ts +2 -0
- package/src/prompts/agents/architect.md +5 -1
- package/src/prompts/agents/critic.md +5 -1
- package/src/prompts/agents/frontmatter.md +1 -0
- package/src/prompts/agents/planner.md +5 -1
- package/src/prompts/memories/unavailable.md +9 -0
- package/src/prompts/tools/bash.md +9 -0
- package/src/prompts/tools/cron.md +25 -0
- package/src/prompts/tools/monitor.md +30 -0
- package/src/runtime-mcp/oauth-flow.ts +4 -2
- package/src/sdk.ts +7 -0
- package/src/session/agent-session.ts +16 -5
- package/src/session/streaming-output.ts +21 -0
- package/src/skill-state/active-state.ts +163 -12
- package/src/slash-commands/builtin-registry.ts +11 -1
- package/src/task/agents.ts +1 -0
- package/src/task/executor.ts +1 -0
- package/src/task/types.ts +1 -0
- package/src/tools/bash-allowed-prefixes.ts +169 -0
- package/src/tools/bash.ts +190 -29
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/cron.ts +665 -0
- package/src/tools/index.ts +20 -2
- package/src/tools/monitor.ts +136 -0
- package/src/vim/engine.ts +3 -3
- package/src/web/search/index.ts +31 -18
- package/src/web/search/provider.ts +57 -12
- package/src/web/search/providers/duckduckgo.ts +279 -0
- package/src/web/search/types.ts +2 -0
- package/src/modes/theme/dark.json +0 -95
- 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-catppuccin.json +0 -107
- 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-dracula.json +0 -98
- 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-gruvbox.json +0 -112
- 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-poimandres.json +0 -141
- 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-solarized.json +0 -97
- 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-tokyo-night.json +0 -101
- 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-catppuccin.json +0 -106
- 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-github.json +0 -115
- 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-poimandres.json +0 -141
- 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-solarized.json +0 -102
- 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/modes/theme/light.json +0 -93
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DuckDuckGo Web Search Provider
|
|
3
|
+
*
|
|
4
|
+
* Keyless, permissionless web search. Scrapes DuckDuckGo's no-JavaScript HTML
|
|
5
|
+
* endpoints and maps anchors/snippets into the unified SearchResponse shape
|
|
6
|
+
* (sources only — DuckDuckGo does not synthesize an answer).
|
|
7
|
+
*
|
|
8
|
+
* This is the zero-config default/fallback backend: it requires no API key and
|
|
9
|
+
* no OAuth, so `isAvailable()` is always true. Because DuckDuckGo applies
|
|
10
|
+
* anti-bot rate limiting (HTTP 202 / 403 / empty responses) from datacenter and
|
|
11
|
+
* VPN IPs, the provider is best-effort: it retries with backoff, rotates the
|
|
12
|
+
* user-agent, and alternates between the `html` and `lite` endpoints. When every
|
|
13
|
+
* attempt fails it throws a {@link SearchProviderError} rather than returning an
|
|
14
|
+
* empty success — it never falls through to keyed providers.
|
|
15
|
+
*
|
|
16
|
+
* Endpoints:
|
|
17
|
+
* https://html.duckduckgo.com/html/ (primary)
|
|
18
|
+
* https://lite.duckduckgo.com/lite/ (fallback markup)
|
|
19
|
+
*
|
|
20
|
+
* The HTML markup is liable to drift; the parser is deliberately small and is
|
|
21
|
+
* pinned by fixture-driven tests (see test/tools/web-search-duckduckgo.test.ts).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import type { AuthStorage } from "@gajae-code/ai";
|
|
25
|
+
|
|
26
|
+
import type { SearchResponse, SearchSource } from "../../../web/search/types";
|
|
27
|
+
import { SearchProviderError } from "../../../web/search/types";
|
|
28
|
+
import { clampNumResults } from "../utils";
|
|
29
|
+
import type { SearchParams } from "./base";
|
|
30
|
+
import { SearchProvider } from "./base";
|
|
31
|
+
import { classifyProviderHttpError, withHardTimeout } from "./utils";
|
|
32
|
+
|
|
33
|
+
const HTML_ENDPOINT = "https://html.duckduckgo.com/html/";
|
|
34
|
+
const LITE_ENDPOINT = "https://lite.duckduckgo.com/lite/";
|
|
35
|
+
|
|
36
|
+
const DEFAULT_NUM_RESULTS = 10;
|
|
37
|
+
const MAX_NUM_RESULTS = 20;
|
|
38
|
+
|
|
39
|
+
/** Endpoint order across retry attempts; rotates markup and user-agent. */
|
|
40
|
+
const ATTEMPTS: Array<"html" | "lite"> = ["html", "lite", "html"];
|
|
41
|
+
|
|
42
|
+
/** Backoff (ms) applied between attempts. Index 0 is unused (first attempt). */
|
|
43
|
+
const BACKOFF_MS = [0, 400, 800];
|
|
44
|
+
|
|
45
|
+
/** Realistic desktop user-agents rotated per attempt to dodge naive blocks. */
|
|
46
|
+
const USER_AGENTS = [
|
|
47
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
|
|
48
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
|
|
49
|
+
"Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0",
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
/** Map our recency filter to DuckDuckGo's `df` time parameter. */
|
|
53
|
+
const RECENCY_MAP: Record<"day" | "week" | "month" | "year", string> = {
|
|
54
|
+
day: "d",
|
|
55
|
+
week: "w",
|
|
56
|
+
month: "m",
|
|
57
|
+
year: "y",
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
interface ParsedResult {
|
|
61
|
+
title: string;
|
|
62
|
+
url: string;
|
|
63
|
+
snippet?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Decode a small set of HTML entities without pulling in a DOM library. */
|
|
67
|
+
function decodeEntities(input: string): string {
|
|
68
|
+
return input
|
|
69
|
+
.replace(/&/g, "&")
|
|
70
|
+
.replace(/</g, "<")
|
|
71
|
+
.replace(/>/g, ">")
|
|
72
|
+
.replace(/"/g, '"')
|
|
73
|
+
.replace(/�*39;|�*27;|'/gi, "'")
|
|
74
|
+
.replace(/�*2f;/gi, "/")
|
|
75
|
+
.replace(/&#(\d+);/g, (_, dec: string) => String.fromCodePoint(Number(dec)))
|
|
76
|
+
.replace(/&#x([0-9a-f]+);/gi, (_, hex: string) => String.fromCodePoint(Number.parseInt(hex, 16)))
|
|
77
|
+
.replace(/ /g, " ");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Strip tags, decode entities, and collapse whitespace from an HTML fragment. */
|
|
81
|
+
function cleanText(fragment: string): string {
|
|
82
|
+
return decodeEntities(fragment.replace(/<[^>]+>/g, ""))
|
|
83
|
+
.replace(/\s+/g, " ")
|
|
84
|
+
.trim();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Resolve a DuckDuckGo result href to the real destination URL. DuckDuckGo wraps
|
|
89
|
+
* external links in a `/l/?uddg=<encoded>` redirect; `lite` sometimes links
|
|
90
|
+
* directly. Returns null for unusable or internal links (so ads/redirect shells
|
|
91
|
+
* are dropped).
|
|
92
|
+
*/
|
|
93
|
+
export function decodeResultUrl(href: string): string | null {
|
|
94
|
+
let h = decodeEntities(href.trim());
|
|
95
|
+
if (!h || h.startsWith("#")) return null;
|
|
96
|
+
if (h.startsWith("//")) h = `https:${h}`;
|
|
97
|
+
let parsed: URL;
|
|
98
|
+
try {
|
|
99
|
+
parsed = new URL(h, "https://duckduckgo.com");
|
|
100
|
+
} catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const uddg = parsed.searchParams.get("uddg");
|
|
104
|
+
if (uddg) {
|
|
105
|
+
try {
|
|
106
|
+
const target = new URL(uddg);
|
|
107
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") return null;
|
|
108
|
+
if (target.hostname.endsWith("duckduckgo.com")) return null;
|
|
109
|
+
return target.toString();
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// No redirect wrapper: accept only real external http(s) links.
|
|
115
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
|
116
|
+
if (parsed.hostname.endsWith("duckduckgo.com")) return null;
|
|
117
|
+
return parsed.toString();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Parse results from the `html.duckduckgo.com/html/` markup. */
|
|
121
|
+
export function parseHtmlResults(html: string): ParsedResult[] {
|
|
122
|
+
const titleRe = /<a\b[^>]*class="[^"]*\bresult__a\b[^"]*"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/gi;
|
|
123
|
+
const snippetRe = /<a\b[^>]*class="[^"]*\bresult__snippet\b[^"]*"[^>]*>([\s\S]*?)<\/a>/gi;
|
|
124
|
+
const snippets: string[] = [];
|
|
125
|
+
for (const m of html.matchAll(snippetRe)) snippets.push(cleanText(m[1]));
|
|
126
|
+
|
|
127
|
+
const results: ParsedResult[] = [];
|
|
128
|
+
let idx = 0;
|
|
129
|
+
for (const m of html.matchAll(titleRe)) {
|
|
130
|
+
const url = decodeResultUrl(m[1]);
|
|
131
|
+
const title = cleanText(m[2]);
|
|
132
|
+
const snippet = snippets[idx];
|
|
133
|
+
idx++;
|
|
134
|
+
if (!url || !title) continue;
|
|
135
|
+
results.push({ title, url, snippet: snippet || undefined });
|
|
136
|
+
}
|
|
137
|
+
return results;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Parse results from the `lite.duckduckgo.com/lite/` markup. */
|
|
141
|
+
export function parseLiteResults(html: string): ParsedResult[] {
|
|
142
|
+
const linkRe = /<a\b[^>]*class="[^"]*\bresult-link\b[^"]*"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/gi;
|
|
143
|
+
const snippetRe = /<td\b[^>]*class="[^"]*\bresult-snippet\b[^"]*"[^>]*>([\s\S]*?)<\/td>/gi;
|
|
144
|
+
const snippets: string[] = [];
|
|
145
|
+
for (const m of html.matchAll(snippetRe)) snippets.push(cleanText(m[1]));
|
|
146
|
+
|
|
147
|
+
const results: ParsedResult[] = [];
|
|
148
|
+
let idx = 0;
|
|
149
|
+
for (const m of html.matchAll(linkRe)) {
|
|
150
|
+
const url = decodeResultUrl(m[1]);
|
|
151
|
+
const title = cleanText(m[2]);
|
|
152
|
+
const snippet = snippets[idx];
|
|
153
|
+
idx++;
|
|
154
|
+
if (!url || !title) continue;
|
|
155
|
+
results.push({ title, url, snippet: snippet || undefined });
|
|
156
|
+
}
|
|
157
|
+
return results;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function delay(ms: number, signal?: AbortSignal): Promise<void> {
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
if (signal?.aborted) {
|
|
163
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const timer = setTimeout(resolve, ms);
|
|
167
|
+
signal?.addEventListener(
|
|
168
|
+
"abort",
|
|
169
|
+
() => {
|
|
170
|
+
clearTimeout(timer);
|
|
171
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
172
|
+
},
|
|
173
|
+
{ once: true },
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Fetch one endpoint and parse it. Throws on HTTP error, rate-limit, or empty parse. */
|
|
179
|
+
async function fetchAndParse(
|
|
180
|
+
endpoint: "html" | "lite",
|
|
181
|
+
query: string,
|
|
182
|
+
df: string | undefined,
|
|
183
|
+
userAgent: string,
|
|
184
|
+
signal: AbortSignal | undefined,
|
|
185
|
+
): Promise<ParsedResult[]> {
|
|
186
|
+
const url = endpoint === "html" ? HTML_ENDPOINT : LITE_ENDPOINT;
|
|
187
|
+
const body = new URLSearchParams({ q: query });
|
|
188
|
+
if (df) body.set("df", df);
|
|
189
|
+
|
|
190
|
+
const response = await fetch(url, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
headers: {
|
|
193
|
+
"User-Agent": userAgent,
|
|
194
|
+
Accept: "text/html,application/xhtml+xml",
|
|
195
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
196
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
197
|
+
},
|
|
198
|
+
body,
|
|
199
|
+
signal: withHardTimeout(signal),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// DuckDuckGo signals soft blocks with 202 (which is still response.ok).
|
|
203
|
+
if (response.status === 202) {
|
|
204
|
+
throw new SearchProviderError("duckduckgo", "duckduckgo: rate-limited (202)", 202);
|
|
205
|
+
}
|
|
206
|
+
if (!response.ok) {
|
|
207
|
+
const errorText = await response.text();
|
|
208
|
+
const classified = classifyProviderHttpError("duckduckgo", response.status, errorText);
|
|
209
|
+
if (classified) throw classified;
|
|
210
|
+
throw new SearchProviderError("duckduckgo", `DuckDuckGo error (${response.status})`, response.status);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const text = await response.text();
|
|
214
|
+
const parsed = endpoint === "html" ? parseHtmlResults(text) : parseLiteResults(text);
|
|
215
|
+
if (parsed.length === 0) {
|
|
216
|
+
throw new SearchProviderError("duckduckgo", "duckduckgo: no parseable results (possible block)");
|
|
217
|
+
}
|
|
218
|
+
return parsed;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Execute a keyless DuckDuckGo web search with light resilience. */
|
|
222
|
+
export async function searchDuckDuckGo(params: {
|
|
223
|
+
query: string;
|
|
224
|
+
num_results?: number;
|
|
225
|
+
recency?: "day" | "week" | "month" | "year";
|
|
226
|
+
signal?: AbortSignal;
|
|
227
|
+
}): Promise<SearchResponse> {
|
|
228
|
+
const numResults = clampNumResults(params.num_results, DEFAULT_NUM_RESULTS, MAX_NUM_RESULTS);
|
|
229
|
+
const df = params.recency ? RECENCY_MAP[params.recency] : undefined;
|
|
230
|
+
|
|
231
|
+
let lastError: unknown;
|
|
232
|
+
for (let attempt = 0; attempt < ATTEMPTS.length; attempt++) {
|
|
233
|
+
if (params.signal?.aborted) throw new DOMException("Aborted", "AbortError");
|
|
234
|
+
if (BACKOFF_MS[attempt] > 0) await delay(BACKOFF_MS[attempt], params.signal);
|
|
235
|
+
|
|
236
|
+
const endpoint = ATTEMPTS[attempt];
|
|
237
|
+
const userAgent = USER_AGENTS[attempt % USER_AGENTS.length];
|
|
238
|
+
try {
|
|
239
|
+
const parsed = await fetchAndParse(endpoint, params.query, df, userAgent, params.signal);
|
|
240
|
+
const sources: SearchSource[] = parsed.slice(0, numResults).map(result => ({
|
|
241
|
+
title: result.title,
|
|
242
|
+
url: result.url,
|
|
243
|
+
snippet: result.snippet,
|
|
244
|
+
}));
|
|
245
|
+
return { provider: "duckduckgo", sources };
|
|
246
|
+
} catch (error) {
|
|
247
|
+
// A caller cancellation must abort immediately, never silently retry.
|
|
248
|
+
if (params.signal?.aborted) throw error;
|
|
249
|
+
lastError = error;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (lastError instanceof SearchProviderError) throw lastError;
|
|
254
|
+
throw new SearchProviderError(
|
|
255
|
+
"duckduckgo",
|
|
256
|
+
`DuckDuckGo search failed after ${ATTEMPTS.length} attempts${
|
|
257
|
+
lastError instanceof Error ? `: ${lastError.message}` : ""
|
|
258
|
+
}`,
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** Keyless, permissionless web search provider backed by DuckDuckGo. */
|
|
263
|
+
export class DuckDuckGoProvider extends SearchProvider {
|
|
264
|
+
readonly id = "duckduckgo";
|
|
265
|
+
readonly label = "DuckDuckGo";
|
|
266
|
+
|
|
267
|
+
isAvailable(_authStorage: AuthStorage): boolean {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
search(params: SearchParams): Promise<SearchResponse> {
|
|
272
|
+
return searchDuckDuckGo({
|
|
273
|
+
query: params.query,
|
|
274
|
+
num_results: params.numSearchResults ?? params.limit,
|
|
275
|
+
recency: params.recency,
|
|
276
|
+
signal: params.signal,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
package/src/web/search/types.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
/** Supported web search providers */
|
|
8
8
|
export type SearchProviderId =
|
|
9
|
+
| "duckduckgo"
|
|
9
10
|
| "exa"
|
|
10
11
|
| "brave"
|
|
11
12
|
| "jina"
|
|
@@ -23,6 +24,7 @@ export type SearchProviderId =
|
|
|
23
24
|
|
|
24
25
|
export function isSearchProviderId(value: string): value is SearchProviderId {
|
|
25
26
|
return [
|
|
27
|
+
"duckduckgo",
|
|
26
28
|
"exa",
|
|
27
29
|
"brave",
|
|
28
30
|
"jina",
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/can1357/gajae-code/main/packages/coding-agent/theme-schema.json",
|
|
3
|
-
"name": "dark",
|
|
4
|
-
"vars": {
|
|
5
|
-
"cyan": "#0088fa",
|
|
6
|
-
"blue": "#178fb9",
|
|
7
|
-
"green": "#89d281",
|
|
8
|
-
"red": "#fc3a4b",
|
|
9
|
-
"yellow": "#e4c00f",
|
|
10
|
-
"gray": "#777d88",
|
|
11
|
-
"dimGray": "#5f6673",
|
|
12
|
-
"darkGray": "#3d424a",
|
|
13
|
-
"accent": "#febc38",
|
|
14
|
-
"selectedBg": "#31363f",
|
|
15
|
-
"userMsgBg": "#221d1a",
|
|
16
|
-
"toolPendingBg": "#1d2129",
|
|
17
|
-
"toolSuccessBg": "#161a1f",
|
|
18
|
-
"toolErrorBg": "#291d1d",
|
|
19
|
-
"customMsgBg": "#2a2530"
|
|
20
|
-
},
|
|
21
|
-
"colors": {
|
|
22
|
-
"accent": "accent",
|
|
23
|
-
"border": "blue",
|
|
24
|
-
"borderAccent": "cyan",
|
|
25
|
-
"borderMuted": "darkGray",
|
|
26
|
-
"success": "green",
|
|
27
|
-
"error": "red",
|
|
28
|
-
"warning": "yellow",
|
|
29
|
-
"muted": "gray",
|
|
30
|
-
"dim": "dimGray",
|
|
31
|
-
"text": "",
|
|
32
|
-
"thinkingText": "gray",
|
|
33
|
-
"selectedBg": "selectedBg",
|
|
34
|
-
"userMessageBg": "userMsgBg",
|
|
35
|
-
"userMessageText": "",
|
|
36
|
-
"customMessageBg": "customMsgBg",
|
|
37
|
-
"customMessageText": "",
|
|
38
|
-
"customMessageLabel": "#b281d6",
|
|
39
|
-
"toolPendingBg": "toolPendingBg",
|
|
40
|
-
"toolSuccessBg": "toolSuccessBg",
|
|
41
|
-
"toolErrorBg": "toolErrorBg",
|
|
42
|
-
"toolTitle": "",
|
|
43
|
-
"toolOutput": "gray",
|
|
44
|
-
"mdHeading": "#febc38",
|
|
45
|
-
"mdLink": "#0088fa",
|
|
46
|
-
"mdLinkUrl": "dimGray",
|
|
47
|
-
"mdCode": "#e5c1ff",
|
|
48
|
-
"mdCodeBlock": "#9CDCFE",
|
|
49
|
-
"mdCodeBlockBorder": "darkGray",
|
|
50
|
-
"mdQuote": "gray",
|
|
51
|
-
"mdQuoteBorder": "darkGray",
|
|
52
|
-
"mdHr": "darkGray",
|
|
53
|
-
"mdListBullet": "accent",
|
|
54
|
-
"toolDiffAdded": "green",
|
|
55
|
-
"toolDiffRemoved": "red",
|
|
56
|
-
"toolDiffContext": "gray",
|
|
57
|
-
"link": "#0088fa",
|
|
58
|
-
"syntaxComment": "#6A9955",
|
|
59
|
-
"syntaxKeyword": "#569CD6",
|
|
60
|
-
"syntaxFunction": "#DCDCAA",
|
|
61
|
-
"syntaxVariable": "#9CDCFE",
|
|
62
|
-
"syntaxString": "#CE9178",
|
|
63
|
-
"syntaxNumber": "#B5CEA8",
|
|
64
|
-
"syntaxType": "#4EC9B0",
|
|
65
|
-
"syntaxOperator": "#D4D4D4",
|
|
66
|
-
"syntaxPunctuation": "#D4D4D4",
|
|
67
|
-
"thinkingOff": "darkGray",
|
|
68
|
-
"thinkingMinimal": "dimGray",
|
|
69
|
-
"thinkingLow": "#178fb9",
|
|
70
|
-
"thinkingMedium": "#0088fa",
|
|
71
|
-
"thinkingHigh": "#b281d6",
|
|
72
|
-
"thinkingXhigh": "#e5c1ff",
|
|
73
|
-
"bashMode": "cyan",
|
|
74
|
-
"statusLineBg": "#121212",
|
|
75
|
-
"statusLineSep": 244,
|
|
76
|
-
"statusLineModel": "#d787af",
|
|
77
|
-
"statusLinePath": "#00afaf",
|
|
78
|
-
"statusLineGitClean": "#5faf5f",
|
|
79
|
-
"statusLineGitDirty": "#d7af5f",
|
|
80
|
-
"statusLineContext": "#8787af",
|
|
81
|
-
"statusLineSpend": "#5fafaf",
|
|
82
|
-
"statusLineStaged": 70,
|
|
83
|
-
"statusLineDirty": 178,
|
|
84
|
-
"statusLineUntracked": 39,
|
|
85
|
-
"statusLineOutput": 205,
|
|
86
|
-
"statusLineCost": 205,
|
|
87
|
-
"statusLineSubagents": "accent",
|
|
88
|
-
"pythonMode": "yellow"
|
|
89
|
-
},
|
|
90
|
-
"export": {
|
|
91
|
-
"pageBg": "#18181e",
|
|
92
|
-
"cardBg": "#1e1e24",
|
|
93
|
-
"infoBg": "#3c3728"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/can1357/gajae-code/main/packages/coding-agent/theme-schema.json",
|
|
3
|
-
"name": "alabaster",
|
|
4
|
-
"vars": {
|
|
5
|
-
"alabaster": "#fdfcfb",
|
|
6
|
-
"chiseledBlack": "#1a1c20",
|
|
7
|
-
"shadowGray": "#505860",
|
|
8
|
-
"carvedDepth": "#6a7080",
|
|
9
|
-
"subtleShadow": "#e8e8ec",
|
|
10
|
-
"lightShadow": "#f0f0f4",
|
|
11
|
-
"accent": "#404850",
|
|
12
|
-
"warmShadow": "#8a7060",
|
|
13
|
-
"selectedBg": "#f0eff0",
|
|
14
|
-
"userMsgBg": "#f5f4f5",
|
|
15
|
-
"toolPendingBg": "#f3f3f8",
|
|
16
|
-
"toolSuccessBg": "#f4f5f4",
|
|
17
|
-
"toolErrorBg": "#f8f3f3",
|
|
18
|
-
"customMsgBg": "#f6f4f7"
|
|
19
|
-
},
|
|
20
|
-
"colors": {
|
|
21
|
-
"accent": "shadowGray",
|
|
22
|
-
"border": "subtleShadow",
|
|
23
|
-
"borderAccent": "shadowGray",
|
|
24
|
-
"borderMuted": "lightShadow",
|
|
25
|
-
"success": "#405840",
|
|
26
|
-
"error": "#704040",
|
|
27
|
-
"warning": "#806850",
|
|
28
|
-
"muted": "carvedDepth",
|
|
29
|
-
"dim": "#909098",
|
|
30
|
-
"text": "",
|
|
31
|
-
"thinkingText": "carvedDepth",
|
|
32
|
-
"selectedBg": "selectedBg",
|
|
33
|
-
"userMessageBg": "userMsgBg",
|
|
34
|
-
"userMessageText": "",
|
|
35
|
-
"customMessageBg": "customMsgBg",
|
|
36
|
-
"customMessageText": "",
|
|
37
|
-
"customMessageLabel": "shadowGray",
|
|
38
|
-
"toolPendingBg": "toolPendingBg",
|
|
39
|
-
"toolSuccessBg": "toolSuccessBg",
|
|
40
|
-
"toolErrorBg": "toolErrorBg",
|
|
41
|
-
"toolTitle": "",
|
|
42
|
-
"toolOutput": "carvedDepth",
|
|
43
|
-
"mdHeading": "chiseledBlack",
|
|
44
|
-
"mdLink": "shadowGray",
|
|
45
|
-
"mdLinkUrl": "carvedDepth",
|
|
46
|
-
"mdCode": "accent",
|
|
47
|
-
"mdCodeBlock": "shadowGray",
|
|
48
|
-
"mdCodeBlockBorder": "subtleShadow",
|
|
49
|
-
"mdQuote": "carvedDepth",
|
|
50
|
-
"mdQuoteBorder": "subtleShadow",
|
|
51
|
-
"mdHr": "subtleShadow",
|
|
52
|
-
"mdListBullet": "shadowGray",
|
|
53
|
-
"toolDiffAdded": "#405840",
|
|
54
|
-
"toolDiffRemoved": "#704040",
|
|
55
|
-
"toolDiffContext": "carvedDepth",
|
|
56
|
-
"syntaxComment": "#707880",
|
|
57
|
-
"syntaxKeyword": "#303840",
|
|
58
|
-
"syntaxFunction": "chiseledBlack",
|
|
59
|
-
"syntaxVariable": "chiseledBlack",
|
|
60
|
-
"syntaxString": "warmShadow",
|
|
61
|
-
"syntaxNumber": "shadowGray",
|
|
62
|
-
"syntaxType": "#303840",
|
|
63
|
-
"syntaxOperator": "#404850",
|
|
64
|
-
"syntaxPunctuation": "#505860",
|
|
65
|
-
"thinkingOff": "#c0c0c8",
|
|
66
|
-
"thinkingMinimal": "#a0a0a8",
|
|
67
|
-
"thinkingLow": "#808090",
|
|
68
|
-
"thinkingMedium": "#606870",
|
|
69
|
-
"thinkingHigh": "#505860",
|
|
70
|
-
"thinkingXhigh": "#303840",
|
|
71
|
-
"bashMode": "#405840",
|
|
72
|
-
"statusLineBg": "#ececf0",
|
|
73
|
-
"statusLineSep": "#a0a0a8",
|
|
74
|
-
"statusLineModel": "#505860",
|
|
75
|
-
"statusLinePath": "#404850",
|
|
76
|
-
"statusLineGitClean": "#305030",
|
|
77
|
-
"statusLineGitDirty": "#806030",
|
|
78
|
-
"statusLineContext": "#404860",
|
|
79
|
-
"statusLineSpend": "#405050",
|
|
80
|
-
"statusLineStaged": 28,
|
|
81
|
-
"statusLineDirty": 136,
|
|
82
|
-
"statusLineUntracked": 31,
|
|
83
|
-
"statusLineOutput": 133,
|
|
84
|
-
"statusLineCost": 133,
|
|
85
|
-
"statusLineSubagents": "shadowGray",
|
|
86
|
-
"pythonMode": "#f0c040"
|
|
87
|
-
},
|
|
88
|
-
"export": {
|
|
89
|
-
"pageBg": "#fdfcfb",
|
|
90
|
-
"cardBg": "#ffffff",
|
|
91
|
-
"infoBg": "#faf9f8"
|
|
92
|
-
}
|
|
93
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/can1357/gajae-code/main/packages/coding-agent/theme-schema.json",
|
|
3
|
-
"name": "amethyst",
|
|
4
|
-
"vars": {
|
|
5
|
-
"amethyst": "#b48eff",
|
|
6
|
-
"violet": "#9b6fd8",
|
|
7
|
-
"deepPurple": "#6b4d9e",
|
|
8
|
-
"quartz": "#f0e8f4",
|
|
9
|
-
"roseQuartz": "#e5b4d4",
|
|
10
|
-
"gold": "#d4af37",
|
|
11
|
-
"lavender": "#c8a8e9",
|
|
12
|
-
"crystalFacet": "#2a2435",
|
|
13
|
-
"caveDark": "#140f18",
|
|
14
|
-
"caveDeep": "#0f0b13",
|
|
15
|
-
"selectedBg": "#221b28",
|
|
16
|
-
"userMsgBg": "#1a1420",
|
|
17
|
-
"toolPendingBg": "#1b1624",
|
|
18
|
-
"toolSuccessBg": "#151220",
|
|
19
|
-
"toolErrorBg": "#261418",
|
|
20
|
-
"customMsgBg": "#1f1828"
|
|
21
|
-
},
|
|
22
|
-
"colors": {
|
|
23
|
-
"accent": "amethyst",
|
|
24
|
-
"border": "deepPurple",
|
|
25
|
-
"borderAccent": "amethyst",
|
|
26
|
-
"borderMuted": "crystalFacet",
|
|
27
|
-
"success": "#8eb897",
|
|
28
|
-
"error": "#d96c75",
|
|
29
|
-
"warning": "gold",
|
|
30
|
-
"muted": "#8b7a99",
|
|
31
|
-
"dim": "#6a5a78",
|
|
32
|
-
"text": "",
|
|
33
|
-
"thinkingText": "#8b7a99",
|
|
34
|
-
"selectedBg": "selectedBg",
|
|
35
|
-
"userMessageBg": "userMsgBg",
|
|
36
|
-
"userMessageText": "",
|
|
37
|
-
"customMessageBg": "customMsgBg",
|
|
38
|
-
"customMessageText": "",
|
|
39
|
-
"customMessageLabel": "lavender",
|
|
40
|
-
"toolPendingBg": "toolPendingBg",
|
|
41
|
-
"toolSuccessBg": "toolSuccessBg",
|
|
42
|
-
"toolErrorBg": "toolErrorBg",
|
|
43
|
-
"toolTitle": "",
|
|
44
|
-
"toolOutput": "#8b7a99",
|
|
45
|
-
"mdHeading": "amethyst",
|
|
46
|
-
"mdLink": "violet",
|
|
47
|
-
"mdLinkUrl": "#6a5a78",
|
|
48
|
-
"mdCode": "roseQuartz",
|
|
49
|
-
"mdCodeBlock": "quartz",
|
|
50
|
-
"mdCodeBlockBorder": "crystalFacet",
|
|
51
|
-
"mdQuote": "#8b7a99",
|
|
52
|
-
"mdQuoteBorder": "crystalFacet",
|
|
53
|
-
"mdHr": "crystalFacet",
|
|
54
|
-
"mdListBullet": "amethyst",
|
|
55
|
-
"toolDiffAdded": "#8eb897",
|
|
56
|
-
"toolDiffRemoved": "#d96c75",
|
|
57
|
-
"toolDiffContext": "#8b7a99",
|
|
58
|
-
"link": "violet",
|
|
59
|
-
"syntaxComment": "#7a6b88",
|
|
60
|
-
"syntaxKeyword": "amethyst",
|
|
61
|
-
"syntaxFunction": "gold",
|
|
62
|
-
"syntaxVariable": "lavender",
|
|
63
|
-
"syntaxString": "roseQuartz",
|
|
64
|
-
"syntaxNumber": "#a8c9b0",
|
|
65
|
-
"syntaxType": "violet",
|
|
66
|
-
"syntaxOperator": "quartz",
|
|
67
|
-
"syntaxPunctuation": "#c0b0cf",
|
|
68
|
-
"thinkingOff": "crystalFacet",
|
|
69
|
-
"thinkingMinimal": "#6a5a78",
|
|
70
|
-
"thinkingLow": "deepPurple",
|
|
71
|
-
"thinkingMedium": "violet",
|
|
72
|
-
"thinkingHigh": "amethyst",
|
|
73
|
-
"thinkingXhigh": "lavender",
|
|
74
|
-
"bashMode": "amethyst",
|
|
75
|
-
"statusLineBg": "caveDeep",
|
|
76
|
-
"statusLineSep": 240,
|
|
77
|
-
"statusLineModel": "roseQuartz",
|
|
78
|
-
"statusLinePath": "violet",
|
|
79
|
-
"statusLineGitClean": "#8eb897",
|
|
80
|
-
"statusLineGitDirty": "gold",
|
|
81
|
-
"statusLineContext": "lavender",
|
|
82
|
-
"statusLineSpend": "deepPurple",
|
|
83
|
-
"statusLineStaged": 141,
|
|
84
|
-
"statusLineDirty": 179,
|
|
85
|
-
"statusLineUntracked": 183,
|
|
86
|
-
"statusLineOutput": 213,
|
|
87
|
-
"statusLineCost": 213,
|
|
88
|
-
"statusLineSubagents": "amethyst",
|
|
89
|
-
"pythonMode": "gold"
|
|
90
|
-
},
|
|
91
|
-
"export": {
|
|
92
|
-
"pageBg": "caveDark",
|
|
93
|
-
"cardBg": "#1b1520",
|
|
94
|
-
"infoBg": "#251d2b"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/can1357/gajae-code/main/packages/coding-agent/theme-schema.json",
|
|
3
|
-
"name": "anthracite",
|
|
4
|
-
"vars": {
|
|
5
|
-
"coal": "#121419",
|
|
6
|
-
"steel": "#3d4555",
|
|
7
|
-
"steelLight": "#4f5566",
|
|
8
|
-
"ember": "#e8734a",
|
|
9
|
-
"emberDim": "#b5583a",
|
|
10
|
-
"ash": "#d4d8e4",
|
|
11
|
-
"ashGray": "#9ca3b5",
|
|
12
|
-
"soot": "#6b7280",
|
|
13
|
-
"sootDark": "#4d5561",
|
|
14
|
-
"coalLighter": "#1a1e25",
|
|
15
|
-
"success": "#7fb069",
|
|
16
|
-
"error": "#d9534f",
|
|
17
|
-
"warning": "#e89c4a"
|
|
18
|
-
},
|
|
19
|
-
"colors": {
|
|
20
|
-
"accent": "ember",
|
|
21
|
-
"border": "steel",
|
|
22
|
-
"borderAccent": "steelLight",
|
|
23
|
-
"borderMuted": "sootDark",
|
|
24
|
-
"success": "success",
|
|
25
|
-
"error": "error",
|
|
26
|
-
"warning": "warning",
|
|
27
|
-
"muted": "ashGray",
|
|
28
|
-
"dim": "soot",
|
|
29
|
-
"text": "",
|
|
30
|
-
"thinkingText": "soot",
|
|
31
|
-
"selectedBg": "#252932",
|
|
32
|
-
"userMessageBg": "#1a1511",
|
|
33
|
-
"userMessageText": "",
|
|
34
|
-
"customMessageBg": "#1f1a24",
|
|
35
|
-
"customMessageText": "",
|
|
36
|
-
"customMessageLabel": "#c99a6e",
|
|
37
|
-
"toolPendingBg": "#171a21",
|
|
38
|
-
"toolSuccessBg": "#141a16",
|
|
39
|
-
"toolErrorBg": "#221617",
|
|
40
|
-
"toolTitle": "",
|
|
41
|
-
"toolOutput": "ashGray",
|
|
42
|
-
"mdHeading": "ember",
|
|
43
|
-
"mdLink": "#6ba3d4",
|
|
44
|
-
"mdLinkUrl": "soot",
|
|
45
|
-
"mdCode": "#e8b089",
|
|
46
|
-
"mdCodeBlock": "#c1cfe0",
|
|
47
|
-
"mdCodeBlockBorder": "steel",
|
|
48
|
-
"mdQuote": "ashGray",
|
|
49
|
-
"mdQuoteBorder": "sootDark",
|
|
50
|
-
"mdHr": "steel",
|
|
51
|
-
"mdListBullet": "ember",
|
|
52
|
-
"toolDiffAdded": "success",
|
|
53
|
-
"toolDiffRemoved": "error",
|
|
54
|
-
"toolDiffContext": "soot",
|
|
55
|
-
"link": "#6ba3d4",
|
|
56
|
-
"syntaxComment": "#6b8099",
|
|
57
|
-
"syntaxKeyword": "#7ba8d4",
|
|
58
|
-
"syntaxFunction": "#e8a069",
|
|
59
|
-
"syntaxVariable": "#a9b8cf",
|
|
60
|
-
"syntaxString": "#c98963",
|
|
61
|
-
"syntaxNumber": "#89b084",
|
|
62
|
-
"syntaxType": "#67b8a8",
|
|
63
|
-
"syntaxOperator": "#b8bfcc",
|
|
64
|
-
"syntaxPunctuation": "#9ca3b5",
|
|
65
|
-
"thinkingOff": "sootDark",
|
|
66
|
-
"thinkingMinimal": "soot",
|
|
67
|
-
"thinkingLow": "#5f7fa3",
|
|
68
|
-
"thinkingMedium": "#6ba3d4",
|
|
69
|
-
"thinkingHigh": "#c99a6e",
|
|
70
|
-
"thinkingXhigh": "#e8b089",
|
|
71
|
-
"bashMode": "#6ba3d4",
|
|
72
|
-
"statusLineBg": "#0f1114",
|
|
73
|
-
"statusLineSep": 240,
|
|
74
|
-
"statusLineModel": "#c99a6e",
|
|
75
|
-
"statusLinePath": "#6ba3d4",
|
|
76
|
-
"statusLineGitClean": "#7fb069",
|
|
77
|
-
"statusLineGitDirty": "#e89c4a",
|
|
78
|
-
"statusLineContext": "#8791a6",
|
|
79
|
-
"statusLineSpend": "#6ba3d4",
|
|
80
|
-
"statusLineStaged": 107,
|
|
81
|
-
"statusLineDirty": 179,
|
|
82
|
-
"statusLineUntracked": 74,
|
|
83
|
-
"statusLineOutput": 173,
|
|
84
|
-
"statusLineCost": 173,
|
|
85
|
-
"statusLineSubagents": "ember",
|
|
86
|
-
"pythonMode": "#f0c040"
|
|
87
|
-
},
|
|
88
|
-
"export": {
|
|
89
|
-
"pageBg": "#121419",
|
|
90
|
-
"cardBg": "#1a1e25",
|
|
91
|
-
"infoBg": "#2a2317"
|
|
92
|
-
}
|
|
93
|
-
}
|