@kenkaiiii/ggcoder 4.3.158 → 4.3.160
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/dist/cli.d.ts +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/language-detector.d.ts +32 -0
- package/dist/core/language-detector.d.ts.map +1 -0
- package/dist/core/language-detector.js +191 -0
- package/dist/core/language-detector.js.map +1 -0
- package/dist/core/language-detector.test.d.ts +2 -0
- package/dist/core/language-detector.test.d.ts.map +1 -0
- package/dist/core/language-detector.test.js +109 -0
- package/dist/core/language-detector.test.js.map +1 -0
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js +93 -0
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/setup-history.d.ts +7 -0
- package/dist/core/setup-history.d.ts.map +1 -0
- package/dist/core/setup-history.js +50 -0
- package/dist/core/setup-history.js.map +1 -0
- package/dist/core/setup-history.test.d.ts +2 -0
- package/dist/core/setup-history.test.d.ts.map +1 -0
- package/dist/core/setup-history.test.js +48 -0
- package/dist/core/setup-history.test.js.map +1 -0
- package/dist/core/style-packs/index.d.ts +19 -0
- package/dist/core/style-packs/index.d.ts.map +1 -0
- package/dist/core/style-packs/index.js +50 -0
- package/dist/core/style-packs/index.js.map +1 -0
- package/dist/core/style-packs/packs.d.ts +18 -0
- package/dist/core/style-packs/packs.d.ts.map +1 -0
- package/dist/core/style-packs/packs.js +228 -0
- package/dist/core/style-packs/packs.js.map +1 -0
- package/dist/core/verify-commands.d.ts +35 -0
- package/dist/core/verify-commands.d.ts.map +1 -0
- package/dist/core/verify-commands.js +209 -0
- package/dist/core/verify-commands.js.map +1 -0
- package/dist/core/verify-commands.test.d.ts +2 -0
- package/dist/core/verify-commands.test.d.ts.map +1 -0
- package/dist/core/verify-commands.test.js +85 -0
- package/dist/core/verify-commands.test.js.map +1 -0
- package/dist/system-prompt.d.ts +2 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +25 -3
- package/dist/system-prompt.js.map +1 -1
- package/dist/ui/App.d.ts +19 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +189 -7
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/theme/dark-ansi.json +2 -1
- package/dist/ui/theme/dark-daltonized.json +2 -1
- package/dist/ui/theme/dark.json +2 -1
- package/dist/ui/theme/light-ansi.json +2 -1
- package/dist/ui/theme/light-daltonized.json +2 -1
- package/dist/ui/theme/light.json +2 -1
- package/dist/ui/theme/theme.d.ts +1 -0
- package/dist/ui/theme/theme.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/system-prompt.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Skill } from "./core/skills.js";
|
|
2
|
+
import type { LanguageId } from "./core/language-detector.js";
|
|
2
3
|
/**
|
|
3
4
|
* Build the system prompt dynamically based on cwd and context.
|
|
4
5
|
*
|
|
@@ -6,5 +7,5 @@ import { type Skill } from "./core/skills.js";
|
|
|
6
7
|
* Pass `tools.map(t => t.name)` from the session so the prompt reflects
|
|
7
8
|
* exactly what the model can call. Defaults to the full built-in set.
|
|
8
9
|
*/
|
|
9
|
-
export declare function buildSystemPrompt(cwd: string, skills?: Skill[], planMode?: boolean, approvedPlanPath?: string, toolNames?: readonly string[]): Promise<string>;
|
|
10
|
+
export declare function buildSystemPrompt(cwd: string, skills?: Skill[], planMode?: boolean, approvedPlanPath?: string, toolNames?: readonly string[], activeLanguages?: Set<LanguageId>): Promise<string>;
|
|
10
11
|
//# sourceMappingURL=system-prompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAM9D;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,KAAK,EAAE,EAChB,QAAQ,CAAC,EAAE,OAAO,EAClB,gBAAgB,CAAC,EAAE,MAAM,EACzB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,EAC7B,eAAe,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,GAChC,OAAO,CAAC,MAAM,CAAC,CAqNjB"}
|
package/dist/system-prompt.js
CHANGED
|
@@ -3,6 +3,8 @@ import path from "node:path";
|
|
|
3
3
|
import { isEyesActive, readJournal } from "@kenkaiiii/ggcoder-eyes";
|
|
4
4
|
import { formatSkillsForPrompt } from "./core/skills.js";
|
|
5
5
|
import { TOOL_PROMPT_HINTS, DEFAULT_TOOL_NAMES } from "./tools/prompt-hints.js";
|
|
6
|
+
import { renderStylePacksSection } from "./core/style-packs/index.js";
|
|
7
|
+
import { detectVerifyCommands, renderVerifySection } from "./core/verify-commands.js";
|
|
6
8
|
const CONTEXT_FILES = ["AGENTS.md", "CLAUDE.md", ".cursorrules", "CONVENTIONS.md"];
|
|
7
9
|
/**
|
|
8
10
|
* Build the system prompt dynamically based on cwd and context.
|
|
@@ -11,7 +13,7 @@ const CONTEXT_FILES = ["AGENTS.md", "CLAUDE.md", ".cursorrules", "CONVENTIONS.md
|
|
|
11
13
|
* Pass `tools.map(t => t.name)` from the session so the prompt reflects
|
|
12
14
|
* exactly what the model can call. Defaults to the full built-in set.
|
|
13
15
|
*/
|
|
14
|
-
export async function buildSystemPrompt(cwd, skills, planMode, approvedPlanPath, toolNames) {
|
|
16
|
+
export async function buildSystemPrompt(cwd, skills, planMode, approvedPlanPath, toolNames, activeLanguages) {
|
|
15
17
|
const sections = [];
|
|
16
18
|
// 1. Identity
|
|
17
19
|
sections.push(`You are GG Coder by Ken Kai — a coding agent that works directly in the user's codebase. ` +
|
|
@@ -37,7 +39,8 @@ export async function buildSystemPrompt(cwd, skills, planMode, approvedPlanPath,
|
|
|
37
39
|
`- **Just do it.** Routine follow-up (build, migrate, seed, re-run) is yours — don't ask.\n` +
|
|
38
40
|
`- **Ask first for destructive actions**: deleting files, force-push, dropping data, killing processes, \`rm -rf\`, \`--hard\`, \`--force\`.\n` +
|
|
39
41
|
`- **Investigate unexpected state** (unfamiliar files, branches, locks) — may be the user's in-progress work.\n` +
|
|
40
|
-
`- **
|
|
42
|
+
`- **Precedence when rules conflict** (highest first): CLAUDE.md / AGENTS.md → existing patterns in the file/module being edited → Language Style Packs → defaults in this prompt. Apply pack conventions to new code; mirror existing patterns when extending old code. Library names in packs are illustrative — use what the project already imports.\n` +
|
|
43
|
+
`- **Verify after meaningful edits.** When a Verification section is present, run the relevant commands for the language(s) you touched. Fix failures before reporting completion.\n` +
|
|
41
44
|
`- **Untracked files → \`.gitignore\`**: artifacts, configs, secrets, logs, scratch, \`.env\`, caches.\n` +
|
|
42
45
|
`- **Never fake verification.** If you didn't run the check or it failed, say so. Don't invent results.`);
|
|
43
46
|
// 2b. Plan mode
|
|
@@ -137,7 +140,26 @@ export async function buildSystemPrompt(cwd, skills, planMode, approvedPlanPath,
|
|
|
137
140
|
dir = parent;
|
|
138
141
|
}
|
|
139
142
|
if (contextParts.length > 0) {
|
|
140
|
-
sections.push(`## Project Context\n\n
|
|
143
|
+
sections.push(`## Project Context\n\n` +
|
|
144
|
+
`**Highest precedence** — the files below override anything stated earlier ` +
|
|
145
|
+
`in this prompt (How to Talk / How to Work / Code Quality / Style Packs).\n\n` +
|
|
146
|
+
contextParts.join("\n\n"));
|
|
147
|
+
}
|
|
148
|
+
// 6b. Language Style Packs — injected when the language detector has
|
|
149
|
+
// identified the project's active languages. See `core/language-detector.ts`
|
|
150
|
+
// and the swap logic in `ui/App.tsx`.
|
|
151
|
+
if (activeLanguages && activeLanguages.size > 0) {
|
|
152
|
+
const stylePacks = renderStylePacksSection(activeLanguages, cwd);
|
|
153
|
+
if (stylePacks)
|
|
154
|
+
sections.push(stylePacks);
|
|
155
|
+
// 6c. Verification — detected commands for the active languages, so the
|
|
156
|
+
// agent can close the feedback loop after pack-influenced edits. Without
|
|
157
|
+
// this anchor, packs are advisory; with it, the model has concrete
|
|
158
|
+
// commands to run and verify against.
|
|
159
|
+
const verifyCmds = detectVerifyCommands(cwd, activeLanguages);
|
|
160
|
+
const verifySection = renderVerifySection(verifyCmds);
|
|
161
|
+
if (verifySection)
|
|
162
|
+
sections.push(verifySection);
|
|
141
163
|
}
|
|
142
164
|
// 7. Eyes — open improvement signals from past probe use (gated on .gg/eyes/manifest.json)
|
|
143
165
|
if (isEyesActive(cwd)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAc,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;AAEnF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,MAAgB,EAChB,QAAkB,EAClB,gBAAyB,EACzB,SAA6B;
|
|
1
|
+
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/App.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { AgentTool } from "@kenkaiiii/gg-agent";
|
|
|
3
3
|
import type { PasteInfo } from "./components/InputArea.js";
|
|
4
4
|
import { type SubAgentInfo } from "./components/SubAgentPanel.js";
|
|
5
5
|
import type { ProcessManager } from "../core/process-manager.js";
|
|
6
|
+
import { type LanguageId } from "../core/language-detector.js";
|
|
6
7
|
import type { Skill } from "../core/skills.js";
|
|
7
8
|
import { type PlanStep } from "../utils/plan-steps.js";
|
|
8
9
|
import type { MCPClientManager } from "../core/mcp/index.js";
|
|
@@ -56,6 +57,23 @@ interface InfoItem {
|
|
|
56
57
|
text: string;
|
|
57
58
|
id: string;
|
|
58
59
|
}
|
|
60
|
+
interface StylePackItem {
|
|
61
|
+
kind: "style_pack";
|
|
62
|
+
/** Newly-added language ids in this injection. Rendered via LANGUAGE_DISPLAY_NAMES. */
|
|
63
|
+
added: readonly LanguageId[];
|
|
64
|
+
/** Show the one-time /setup hint. Only true for the first badge in a session. */
|
|
65
|
+
showSetupHint: boolean;
|
|
66
|
+
id: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Shown once per session when initial language detection finds no packs —
|
|
70
|
+
* keeps `/setup` discoverable in dirs that don't look like a project root
|
|
71
|
+
* (parent folders, scratch dirs, etc.).
|
|
72
|
+
*/
|
|
73
|
+
interface SetupHintItem {
|
|
74
|
+
kind: "setup_hint";
|
|
75
|
+
id: string;
|
|
76
|
+
}
|
|
59
77
|
interface UpdateNoticeItem {
|
|
60
78
|
kind: "update_notice";
|
|
61
79
|
text: string;
|
|
@@ -142,7 +160,7 @@ export interface ToolGroupItem {
|
|
|
142
160
|
tools: ToolGroupTool[];
|
|
143
161
|
id: string;
|
|
144
162
|
}
|
|
145
|
-
export type CompletedItem = UserItem | TaskItem | AssistantItem | ToolStartItem | ToolDoneItem | ServerToolStartItem | ServerToolDoneItem | ErrorItem | InfoItem | UpdateNoticeItem | QueuedItem | CompactingItem | CompactedItem | DurationItem | BannerItem | SubAgentGroupItem | ToolGroupItem | PlanTransitionItem | TombstoneItem | StepDoneItem;
|
|
163
|
+
export type CompletedItem = UserItem | TaskItem | AssistantItem | ToolStartItem | ToolDoneItem | ServerToolStartItem | ServerToolDoneItem | ErrorItem | InfoItem | StylePackItem | SetupHintItem | UpdateNoticeItem | QueuedItem | CompactingItem | CompactedItem | DurationItem | BannerItem | SubAgentGroupItem | ToolGroupItem | PlanTransitionItem | TombstoneItem | StepDoneItem;
|
|
146
164
|
export interface AppProps {
|
|
147
165
|
provider: Provider;
|
|
148
166
|
model: string;
|
package/dist/ui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAA6B,MAAM,kBAAkB,CAAC;AAEpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAmBjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/App.js
CHANGED
|
@@ -46,8 +46,11 @@ import { SettingsManager } from "../core/settings-manager.js";
|
|
|
46
46
|
import { shouldCompact, compact } from "../core/compaction/compactor.js";
|
|
47
47
|
import { estimateConversationTokens } from "../core/compaction/token-estimator.js";
|
|
48
48
|
import { PROMPT_COMMANDS, getPromptCommand } from "../core/prompt-commands.js";
|
|
49
|
+
import { isFirstTimeSetup, markSetupAudited } from "../core/setup-history.js";
|
|
49
50
|
import { loadCustomCommands } from "../core/custom-commands.js";
|
|
50
51
|
import { buildSystemPrompt } from "../system-prompt.js";
|
|
52
|
+
import { detectLanguages, LANGUAGE_DISPLAY_NAMES, } from "../core/language-detector.js";
|
|
53
|
+
import { detectVerifyCommands } from "../core/verify-commands.js";
|
|
51
54
|
import { extractPlanSteps, findCompletedMarkers, markStepsCompleted, segmentDisplayText, stripDoneMarkers, } from "../utils/plan-steps.js";
|
|
52
55
|
import { getMCPServers } from "../core/mcp/index.js";
|
|
53
56
|
import { trimFlushedItems, flushOnTurnText, flushOnTurnEnd, flushOverflow, } from "./live-item-flush.js";
|
|
@@ -349,6 +352,26 @@ export function App(props) {
|
|
|
349
352
|
const lastActualTokensTimestampRef = useRef(0);
|
|
350
353
|
/** Timestamp of last compaction — used for time-based cooldown and staleness detection. */
|
|
351
354
|
const lastCompactionTimeRef = useRef(0);
|
|
355
|
+
/**
|
|
356
|
+
* Languages whose style packs are currently injected into the system prompt.
|
|
357
|
+
* Grown by `maybeInjectLanguagePacks` after `write`/`bash` tool results when
|
|
358
|
+
* the language detector sees new marker files. Reset on `chdir` (pixel-fix).
|
|
359
|
+
* Only grows within a session; we never strip packs once injected (cheaper
|
|
360
|
+
* than invalidating prompt caching, and stale guidance is harmless).
|
|
361
|
+
*/
|
|
362
|
+
const injectedLanguagesRef = useRef(new Set());
|
|
363
|
+
/**
|
|
364
|
+
* True until the first style-pack badge is pushed. Used to gate the
|
|
365
|
+
* one-time "/setup" hint so users learn the slash command without being
|
|
366
|
+
* spammed on every subsequent pack swap.
|
|
367
|
+
*/
|
|
368
|
+
const setupHintShownRef = useRef(false);
|
|
369
|
+
/**
|
|
370
|
+
* Callback that fires `/setup` programmatically. Assigned later in the
|
|
371
|
+
* component once `agentLoop` is in scope. Called from the initial
|
|
372
|
+
* language-detection path when this cwd has never been audited before.
|
|
373
|
+
*/
|
|
374
|
+
const triggerAutoSetupRef = useRef(async () => { });
|
|
352
375
|
const getId = () => String(nextIdRef.current++);
|
|
353
376
|
// Two-phase flush: items waiting to be moved to Static history after the
|
|
354
377
|
// live area has been cleared and Ink has committed the smaller output.
|
|
@@ -432,10 +455,84 @@ export function App(props) {
|
|
|
432
455
|
props.planModeRef.current = planMode;
|
|
433
456
|
}
|
|
434
457
|
}, [planMode, props.planModeRef]);
|
|
458
|
+
/**
|
|
459
|
+
* Unified "apply detection result" pipeline. Called from three sites:
|
|
460
|
+
* 1. Initial mount (existing project at startup).
|
|
461
|
+
* 2. After every `write`/`bash` tool result (reactive to new manifests).
|
|
462
|
+
* 3. Before every user submit (catches external changes between turns,
|
|
463
|
+
* and ensures non-writing prompts still surface the badge).
|
|
464
|
+
*
|
|
465
|
+
* No-op when no new languages were added vs `injectedLanguagesRef.current`.
|
|
466
|
+
* The set-growth gate keeps this safe to call from every hot path.
|
|
467
|
+
*/
|
|
468
|
+
const applyLanguageDetectionRef = useRef(async () => { });
|
|
469
|
+
applyLanguageDetectionRef.current = async (source) => {
|
|
470
|
+
const cwd = cwdRef.current;
|
|
471
|
+
const detected = detectLanguages(cwd);
|
|
472
|
+
const added = [];
|
|
473
|
+
for (const id of detected) {
|
|
474
|
+
if (!injectedLanguagesRef.current.has(id))
|
|
475
|
+
added.push(id);
|
|
476
|
+
}
|
|
477
|
+
if (added.length === 0) {
|
|
478
|
+
// No new packs to inject. The empty-detection hint + auto-run are
|
|
479
|
+
// first-time-per-cwd only — once the user has been shown the box and
|
|
480
|
+
// /setup has had a chance to run, re-showing on every session is noise.
|
|
481
|
+
// (Contrast with the with-packs path: the badge re-shows each session
|
|
482
|
+
// as project-state info; only its embedded /setup tip is one-time.)
|
|
483
|
+
if (source === "initial" &&
|
|
484
|
+
!setupHintShownRef.current &&
|
|
485
|
+
injectedLanguagesRef.current.size === 0 &&
|
|
486
|
+
isFirstTimeSetup(cwd)) {
|
|
487
|
+
setupHintShownRef.current = true;
|
|
488
|
+
markSetupAudited(cwd);
|
|
489
|
+
log("INFO", "language", `No style packs detected for ${cwd}`, { source });
|
|
490
|
+
setLiveItems((prev) => [...prev, { kind: "setup_hint", id: getId() }]);
|
|
491
|
+
// /setup handles the empty / parent-folder / scratch-dir case via
|
|
492
|
+
// its brand-new-empty-project branch in the prompt template.
|
|
493
|
+
void triggerAutoSetupRef.current();
|
|
494
|
+
}
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
injectedLanguagesRef.current = detected;
|
|
498
|
+
try {
|
|
499
|
+
const newPrompt = await buildSystemPrompt(cwd, props.skills, planMode, approvedPlanPathRef.current, undefined, detected);
|
|
500
|
+
if (messagesRef.current[0]?.role === "system") {
|
|
501
|
+
messagesRef.current[0] = { role: "system", content: newPrompt };
|
|
502
|
+
}
|
|
503
|
+
const verifyCmds = detectVerifyCommands(cwd, detected);
|
|
504
|
+
const tag = source === "initial" ? "Initial style packs" : "Style pack(s) loaded";
|
|
505
|
+
log("INFO", "language", `${tag}: ${added.join(", ")}`, {
|
|
506
|
+
source,
|
|
507
|
+
active: [...detected].join(","),
|
|
508
|
+
verify_count: String(verifyCmds.length),
|
|
509
|
+
verify: verifyCmds.map((c) => `${c.language}:${c.label}=${c.command}`).join(" | "),
|
|
510
|
+
});
|
|
511
|
+
const showSetupHint = !setupHintShownRef.current;
|
|
512
|
+
setupHintShownRef.current = true;
|
|
513
|
+
setLiveItems((prev) => [...prev, { kind: "style_pack", added, showSetupHint, id: getId() }]);
|
|
514
|
+
// First-time-per-project auto-run. Fires only on the initial mount
|
|
515
|
+
// detection path — not on tool/input triggers — so we don't surprise
|
|
516
|
+
// users mid-session. Persisted across sessions via setup-history.json.
|
|
517
|
+
if (source === "initial" && isFirstTimeSetup(cwd)) {
|
|
518
|
+
markSetupAudited(cwd);
|
|
519
|
+
void triggerAutoSetupRef.current();
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
catch (err) {
|
|
523
|
+
log("WARN", "language", `Detection apply failed (${source}): ${err.message}`);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
// Initial language detection — runs once on mount so existing projects with
|
|
527
|
+
// marker files (package.json, Cargo.toml, etc.) get their style packs from
|
|
528
|
+
// turn 1, with a visible badge.
|
|
529
|
+
useEffect(() => {
|
|
530
|
+
void applyLanguageDetectionRef.current("initial");
|
|
531
|
+
}, []);
|
|
435
532
|
// Rebuild system prompt when plan mode changes
|
|
436
533
|
useEffect(() => {
|
|
437
534
|
void (async () => {
|
|
438
|
-
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, approvedPlanPathRef.current);
|
|
535
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, approvedPlanPathRef.current, undefined, injectedLanguagesRef.current);
|
|
439
536
|
if (messagesRef.current[0]?.role === "system") {
|
|
440
537
|
messagesRef.current[0] = {
|
|
441
538
|
role: "system",
|
|
@@ -514,6 +611,29 @@ export function App(props) {
|
|
|
514
611
|
}
|
|
515
612
|
persistedIndexRef.current = allMsgs.length;
|
|
516
613
|
}, []);
|
|
614
|
+
/**
|
|
615
|
+
* Run the language detector against the current cwd. If the detected set is a
|
|
616
|
+
* strict superset of what's already injected, rebuild the system prompt with
|
|
617
|
+
* the expanded set and swap `messagesRef.current[0]`.
|
|
618
|
+
*
|
|
619
|
+
* Called from `onToolEnd` after `write`/`bash` succeeds — these are the only
|
|
620
|
+
* tools that can introduce new marker files (package.json, Cargo.toml, etc.).
|
|
621
|
+
* Other tool kinds skip detection entirely to avoid wasted filesystem stats.
|
|
622
|
+
*
|
|
623
|
+
* No restart required: the system prompt is mutated in place, same mechanism
|
|
624
|
+
* already used for plan mode + pixel-fix chdir.
|
|
625
|
+
*
|
|
626
|
+
* Stored in a ref so `onToolEnd` (whose useCallback dep array is intentionally
|
|
627
|
+
* empty to keep agent-loop options stable) can call the freshest version.
|
|
628
|
+
*/
|
|
629
|
+
const maybeInjectLanguagePacksRef = useRef(async () => { });
|
|
630
|
+
maybeInjectLanguagePacksRef.current = async (toolName, isError) => {
|
|
631
|
+
if (isError)
|
|
632
|
+
return;
|
|
633
|
+
if (toolName !== "write" && toolName !== "bash")
|
|
634
|
+
return;
|
|
635
|
+
await applyLanguageDetectionRef.current("tool");
|
|
636
|
+
};
|
|
517
637
|
// ── Compaction ─────────────────────────────────────────
|
|
518
638
|
// Load settings for auto-compaction + buddy
|
|
519
639
|
const settingsRef = useRef(null);
|
|
@@ -680,7 +800,7 @@ export function App(props) {
|
|
|
680
800
|
approvedPlanPathRef.current = undefined;
|
|
681
801
|
// Rebuild system prompt to remove the completed plan from context
|
|
682
802
|
void (async () => {
|
|
683
|
-
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined);
|
|
803
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined, undefined, injectedLanguagesRef.current);
|
|
684
804
|
if (messagesRef.current[0]?.role === "system") {
|
|
685
805
|
messagesRef.current[0] = { role: "system", content: newPrompt };
|
|
686
806
|
}
|
|
@@ -921,6 +1041,10 @@ export function App(props) {
|
|
|
921
1041
|
});
|
|
922
1042
|
}, []),
|
|
923
1043
|
onToolEnd: useCallback((toolCallId, name, result, isError, durationMs, details) => {
|
|
1044
|
+
// Language-pack detection — gated on `write`/`bash` inside the
|
|
1045
|
+
// helper; cheap to call unconditionally. Fire-and-forget; the next
|
|
1046
|
+
// LLM turn picks up the swapped system prompt automatically.
|
|
1047
|
+
void maybeInjectLanguagePacksRef.current(name, isError);
|
|
924
1048
|
const level = isError ? "ERROR" : "INFO";
|
|
925
1049
|
log(level, "tool", `Tool call ended: ${name}`, {
|
|
926
1050
|
id: toolCallId,
|
|
@@ -1261,6 +1385,44 @@ export function App(props) {
|
|
|
1261
1385
|
setLiveItems([userItem]);
|
|
1262
1386
|
}, []),
|
|
1263
1387
|
});
|
|
1388
|
+
// First-time-per-project auto-run of /setup. Bound after `agentLoop` is in
|
|
1389
|
+
// scope so the ref closure can dispatch to it. Called from the initial
|
|
1390
|
+
// language-detection path when `isFirstTimeSetup(cwd)` is true. Pushes a
|
|
1391
|
+
// notice item explaining what's happening, then runs the audit prompt.
|
|
1392
|
+
triggerAutoSetupRef.current = async () => {
|
|
1393
|
+
const setupCmd = getPromptCommand("setup");
|
|
1394
|
+
if (!setupCmd) {
|
|
1395
|
+
log("WARN", "setup", "Auto-setup skipped — /setup command not found in registry.");
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
log("INFO", "setup", `Auto-running /setup (first session for ${cwdRef.current})`);
|
|
1399
|
+
setLiveItems((prev) => [
|
|
1400
|
+
...prev,
|
|
1401
|
+
{
|
|
1402
|
+
kind: "info",
|
|
1403
|
+
text: "First time in this project — auto-running /setup to audit hygiene, tooling, and style-pack alignment. " +
|
|
1404
|
+
"Press Esc to cancel.",
|
|
1405
|
+
id: getId(),
|
|
1406
|
+
},
|
|
1407
|
+
{ kind: "user", text: "/setup", id: getId() },
|
|
1408
|
+
]);
|
|
1409
|
+
setLastUserMessage("/setup");
|
|
1410
|
+
setDoneStatus(null);
|
|
1411
|
+
try {
|
|
1412
|
+
await agentLoop.run(setupCmd.prompt);
|
|
1413
|
+
}
|
|
1414
|
+
catch (err) {
|
|
1415
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1416
|
+
const isAbort = msg.includes("aborted") || msg.includes("abort");
|
|
1417
|
+
log(isAbort ? "INFO" : "ERROR", "setup", `Auto-setup ended: ${msg}`);
|
|
1418
|
+
setLiveItems((prev) => [
|
|
1419
|
+
...prev,
|
|
1420
|
+
isAbort
|
|
1421
|
+
? { kind: "info", text: "Auto-setup cancelled.", id: getId() }
|
|
1422
|
+
: { kind: "error", message: msg, id: getId() },
|
|
1423
|
+
]);
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1264
1426
|
// Phase 2 of the two-phase flush: after onDone clears liveItems (phase 1)
|
|
1265
1427
|
// and Ink renders the smaller live area (updating its internal line
|
|
1266
1428
|
// counter), this effect pushes the stashed items into Static history.
|
|
@@ -1328,6 +1490,11 @@ export function App(props) {
|
|
|
1328
1490
|
else {
|
|
1329
1491
|
const truncated = trimmed.length > 100 ? trimmed.slice(0, 100) + "..." : trimmed;
|
|
1330
1492
|
log("INFO", "input", `User input: ${truncated}${inputImages.length > 0 ? ` (+${inputImages.length} image${inputImages.length > 1 ? "s" : ""})` : ""}`);
|
|
1493
|
+
// Re-detect on every user submit — cheap (fs stats only). Catches
|
|
1494
|
+
// external changes between turns and ensures non-writing prompts still
|
|
1495
|
+
// surface the badge when packs are newly applicable. No-op if the set
|
|
1496
|
+
// has not grown.
|
|
1497
|
+
void applyLanguageDetectionRef.current("input");
|
|
1331
1498
|
}
|
|
1332
1499
|
// Handle /model directly — open inline selector
|
|
1333
1500
|
if (trimmed === "/model" || trimmed === "/m") {
|
|
@@ -1359,7 +1526,7 @@ export function App(props) {
|
|
|
1359
1526
|
if (trimmed === "/clear") {
|
|
1360
1527
|
if (props.resetUI) {
|
|
1361
1528
|
void (async () => {
|
|
1362
|
-
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined);
|
|
1529
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined, undefined, injectedLanguagesRef.current);
|
|
1363
1530
|
props.resetUI?.({
|
|
1364
1531
|
wipeSession: true,
|
|
1365
1532
|
messages: [{ role: "system", content: newPrompt }],
|
|
@@ -1378,7 +1545,7 @@ export function App(props) {
|
|
|
1378
1545
|
planStepsRef.current = [];
|
|
1379
1546
|
setPlanSteps([]);
|
|
1380
1547
|
void (async () => {
|
|
1381
|
-
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined);
|
|
1548
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined, undefined, injectedLanguagesRef.current);
|
|
1382
1549
|
messagesRef.current = [{ role: "system", content: newPrompt }];
|
|
1383
1550
|
persistedIndexRef.current = messagesRef.current.length;
|
|
1384
1551
|
})();
|
|
@@ -1441,7 +1608,7 @@ export function App(props) {
|
|
|
1441
1608
|
setPlanSteps([]);
|
|
1442
1609
|
// Rebuild system prompt without the plan
|
|
1443
1610
|
void (async () => {
|
|
1444
|
-
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined);
|
|
1611
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined, undefined, injectedLanguagesRef.current);
|
|
1445
1612
|
if (messagesRef.current[0]?.role === "system") {
|
|
1446
1613
|
messagesRef.current[0] = { role: "system", content: newPrompt };
|
|
1447
1614
|
}
|
|
@@ -1823,6 +1990,13 @@ export function App(props) {
|
|
|
1823
1990
|
return (_jsx(UserMessage, { text: item.text, imageCount: item.imageCount, pasteInfo: item.pasteInfo }, item.id));
|
|
1824
1991
|
case "task":
|
|
1825
1992
|
return (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: theme.success, bold: true, children: "▶ " }), _jsx(Text, { color: theme.textDim, children: "Task: " }), _jsx(Text, { color: theme.success, children: item.title })] }) }, item.id));
|
|
1993
|
+
case "style_pack": {
|
|
1994
|
+
const names = item.added.map((id) => LANGUAGE_DISPLAY_NAMES[id]);
|
|
1995
|
+
const headerLabel = item.added.length > 1 ? "STYLE PACKS ACTIVE" : "STYLE PACK ACTIVE";
|
|
1996
|
+
return (_jsxs(Box, { marginTop: 1, flexShrink: 1, flexDirection: "column", borderStyle: "round", borderColor: theme.language, paddingX: 1, children: [_jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: theme.language, bold: true, children: "◆ " }), _jsx(Text, { color: theme.language, bold: true, children: headerLabel })] }), _jsx(Text, { color: theme.text, bold: true, wrap: "wrap", children: names.join(", ") }), item.showSetupHint && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: theme.textMuted, children: "Tip: run " }), _jsx(Text, { color: theme.language, bold: true, children: "/setup" }), _jsx(Text, { color: theme.textMuted, children: " to audit this project against the active pack(s)" })] }) }))] }, item.id));
|
|
1997
|
+
}
|
|
1998
|
+
case "setup_hint":
|
|
1999
|
+
return (_jsxs(Box, { marginTop: 1, flexShrink: 1, flexDirection: "column", borderStyle: "round", borderColor: theme.language, paddingX: 1, children: [_jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: theme.language, bold: true, children: "◆ " }), _jsx(Text, { color: theme.language, bold: true, children: "NO STYLE PACKS DETECTED" })] }), _jsx(Text, { color: theme.textMuted, wrap: "wrap", children: "This directory has no recognized language manifest at its root." }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: theme.textMuted, children: "Tip: run " }), _jsx(Text, { color: theme.language, bold: true, children: "/setup" }), _jsx(Text, { color: theme.textMuted, children: " to audit project hygiene or bootstrap a new project from scratch" })] }) })] }, item.id));
|
|
1826
2000
|
case "assistant":
|
|
1827
2001
|
return (_jsx(AssistantMessage, { text: item.text, thinking: item.thinking, thinkingMs: item.thinkingMs, showThinking: props.showThinking, planMode: item.planMode }, item.id));
|
|
1828
2002
|
case "tool_start":
|
|
@@ -1973,7 +2147,15 @@ export function App(props) {
|
|
|
1973
2147
|
if (props.rebuildToolsForCwd) {
|
|
1974
2148
|
setCurrentTools(props.rebuildToolsForCwd(prep.projectPath));
|
|
1975
2149
|
}
|
|
1976
|
-
|
|
2150
|
+
// Pixel-fix swaps the project root — reset injected packs so the
|
|
2151
|
+
// new project re-detects from scratch on the next tool call. Also
|
|
2152
|
+
// reset the setup-hint flag so the new project's first badge re-
|
|
2153
|
+
// surfaces the tip (different project, may need the reminder).
|
|
2154
|
+
injectedLanguagesRef.current = new Set();
|
|
2155
|
+
setupHintShownRef.current = false;
|
|
2156
|
+
const detectedForPixelFix = detectLanguages(prep.projectPath);
|
|
2157
|
+
injectedLanguagesRef.current = detectedForPixelFix;
|
|
2158
|
+
const newSystemPrompt = await buildSystemPrompt(prep.projectPath, props.skills, false, undefined, undefined, detectedForPixelFix);
|
|
1977
2159
|
// Now that the cwd swap is committed, reset chat. Doing this BEFORE
|
|
1978
2160
|
// the chdir would print a banner with the old cwd, then bumping
|
|
1979
2161
|
// staticKey would print a second banner with the new cwd — leaving
|
|
@@ -2115,7 +2297,7 @@ export function App(props) {
|
|
|
2115
2297
|
const planContent = await import("node:fs/promises").then(({ readFile }) => readFile(planPath, "utf-8"));
|
|
2116
2298
|
const steps = extractPlanSteps(planContent);
|
|
2117
2299
|
// Build the new system prompt with the approved plan baked in.
|
|
2118
|
-
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, false, planPath);
|
|
2300
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, false, planPath, undefined, injectedLanguagesRef.current);
|
|
2119
2301
|
// Create a new session file BEFORE remount so the new tree
|
|
2120
2302
|
// picks it up via sessionStore.sessionPath.
|
|
2121
2303
|
let newSessionPath;
|