@kenkaiiii/ggcoder 5.78.0 → 5.79.1
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/app-sidecar/app-settings.d.ts +6 -2
- package/dist/app-sidecar/app-settings.js +39 -20
- package/dist/app-sidecar/app-settings.js.map +1 -1
- package/dist/app-sidecar/git-target.d.ts +17 -0
- package/dist/app-sidecar/git-target.js +31 -0
- package/dist/app-sidecar/git-target.js.map +1 -0
- package/dist/app-sidecar/goal-routes.d.ts +26 -0
- package/dist/app-sidecar/goal-routes.js +445 -0
- package/dist/app-sidecar/goal-routes.js.map +1 -0
- package/dist/app-sidecar/history-routes.d.ts +13 -0
- package/dist/app-sidecar/history-routes.js +36 -25
- package/dist/app-sidecar/history-routes.js.map +1 -1
- package/dist/app-sidecar/mcp-routes.js +1 -2
- package/dist/app-sidecar/mcp-routes.js.map +1 -1
- package/dist/app-sidecar/route-context.d.ts +12 -0
- package/dist/app-sidecar/run-control-routes.js +2 -1
- package/dist/app-sidecar/run-control-routes.js.map +1 -1
- package/dist/app-sidecar/session-routes.js +41 -0
- package/dist/app-sidecar/session-routes.js.map +1 -1
- package/dist/app-sidecar/session-types.d.ts +2 -0
- package/dist/app-sidecar/workspace-routes.js +13 -95
- package/dist/app-sidecar/workspace-routes.js.map +1 -1
- package/dist/app-sidecar.js +213 -60
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli/shared.js +1 -1
- package/dist/cli/shared.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/acceptance-checks.js +17 -4
- package/dist/core/acceptance-checks.js.map +1 -1
- package/dist/core/agent-notifications.d.ts +1 -1
- package/dist/core/agent-session.d.ts +76 -5
- package/dist/core/agent-session.js +118 -22
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/ask-user.d.ts +11 -0
- package/dist/core/ask-user.js +6 -1
- package/dist/core/ask-user.js.map +1 -1
- package/dist/core/auth-providers.d.ts +2 -80
- package/dist/core/auth-providers.js +4 -183
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/context-files.d.ts +8 -0
- package/dist/core/context-files.js +46 -0
- package/dist/core/context-files.js.map +1 -0
- package/dist/core/env-delta.d.ts +9 -1
- package/dist/core/env-delta.js +20 -0
- package/dist/core/env-delta.js.map +1 -1
- package/dist/core/goals-store.d.ts +208 -0
- package/dist/core/goals-store.js +520 -0
- package/dist/core/goals-store.js.map +1 -0
- package/dist/core/local-endpoint-store.js +15 -11
- package/dist/core/local-endpoint-store.js.map +1 -1
- package/dist/core/project-discovery.d.ts +7 -0
- package/dist/core/project-discovery.js +8 -2
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/radio.d.ts +2 -3
- package/dist/core/radio.js.map +1 -1
- package/dist/core/session-manager.d.ts +7 -1
- package/dist/core/session-manager.js +17 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-storage.d.ts +3 -0
- package/dist/core/session-storage.js +8 -2
- package/dist/core/session-storage.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +51 -0
- package/dist/core/subagent-manager.js +95 -15
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-store.js +2 -1
- package/dist/core/subagent-store.js.map +1 -1
- package/dist/goals-agent/goal-team.d.ts +2 -0
- package/dist/goals-agent/goal-team.js +82 -0
- package/dist/goals-agent/goal-team.js.map +1 -0
- package/dist/goals-agent/goals-agent.d.ts +90 -0
- package/dist/goals-agent/goals-agent.js +246 -0
- package/dist/goals-agent/goals-agent.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interactive.js +4 -3
- package/dist/interactive.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +12 -0
- package/dist/modes/subagent-worker-mode.js +22 -1
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/system-prompt.d.ts +8 -0
- package/dist/system-prompt.js +21 -9
- package/dist/system-prompt.js.map +1 -1
- package/dist/tools/bash-read-evidence.d.ts +13 -0
- package/dist/tools/bash-read-evidence.js +48 -1
- package/dist/tools/bash-read-evidence.js.map +1 -1
- package/dist/tools/index.d.ts +7 -1
- package/dist/tools/index.js +10 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/read-tracker.d.ts +6 -12
- package/dist/tools/read-tracker.js +21 -36
- package/dist/tools/read-tracker.js.map +1 -1
- package/dist/tools/read.js +2 -2
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/subagent-control.js +22 -3
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/write.js +110 -8
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/components/ActivityIndicator.d.ts +5 -5
- package/dist/ui/components/InputArea.d.ts +2 -2
- package/dist/ui/components/InputArea.js +3 -3
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/ToolExecution.d.ts +2 -2
- package/dist/utils/format.d.ts +0 -4
- package/dist/utils/format.js +0 -7
- package/dist/utils/format.js.map +1 -1
- package/package.json +4 -4
|
@@ -68,11 +68,24 @@ function verifyFileChanged(check, calls, cwd) {
|
|
|
68
68
|
}
|
|
69
69
|
return { check, status: "FAIL", reason: "the helper never wrote or edited it" };
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
/**
|
|
72
|
+
* A command without a leading `cd` into the helper's own folder: the helper's
|
|
73
|
+
* shell already starts there, so `cd <cwd> && npm test` and `npm test` are the
|
|
74
|
+
* same run. A `cd` anywhere else is kept, as it changes what ran.
|
|
75
|
+
*/
|
|
76
|
+
function inOwnFolder(command, cwd) {
|
|
77
|
+
const match = /^cd\s+("[^"]+"|'[^']+'|\S+)\s*&&\s*(.+)$/.exec(command);
|
|
78
|
+
if (!match?.[1] || !match[2])
|
|
79
|
+
return command;
|
|
80
|
+
const dir = match[1].replace(/^["']|["']$/g, "");
|
|
81
|
+
return path.resolve(cwd, dir) === path.resolve(cwd) ? match[2] : command;
|
|
82
|
+
}
|
|
83
|
+
function verifyCommandPassed(check, calls, cwd) {
|
|
84
|
+
const same = (command) => inOwnFolder(normalizeCommand(command), cwd);
|
|
85
|
+
const wanted = same(check.target);
|
|
73
86
|
let lastIndex = -1;
|
|
74
87
|
calls.forEach((call, index) => {
|
|
75
|
-
if (call.name === "bash" &&
|
|
88
|
+
if (call.name === "bash" && same(call.target) === wanted)
|
|
76
89
|
lastIndex = index;
|
|
77
90
|
});
|
|
78
91
|
const last = calls[lastIndex];
|
|
@@ -111,7 +124,7 @@ export function verifyAcceptanceChecks(checks, calls, cwd) {
|
|
|
111
124
|
case "file_changed":
|
|
112
125
|
return verifyFileChanged(check, calls, cwd);
|
|
113
126
|
case "command_passed":
|
|
114
|
-
return verifyCommandPassed(check, calls);
|
|
127
|
+
return verifyCommandPassed(check, calls, cwd);
|
|
115
128
|
}
|
|
116
129
|
});
|
|
117
130
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acceptance-checks.js","sourceRoot":"","sources":["../../src/core/acceptance-checks.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"acceptance-checks.js","sourceRoot":"","sources":["../../src/core/acceptance-checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;CACrE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC;KACnC,KAAK,CAAC,qBAAqB,CAAC;KAC5B,GAAG,CAAC,qBAAqB,CAAC;KAC1B,QAAQ,EAAE;KACV,QAAQ,CAAC,4BAA4B,CAAC,CAAC;AAY1C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,uEAAuE;AACvE,SAAS,gBAAgB,CAAC,OAAe;IACvC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/C,6EAA6E;IAC7E,oEAAoE;IACpE,SAAS,CAAC;QACR,MAAM,QAAQ,GAAG,IAAI;aAClB,OAAO,CAAC,kDAAkD,EAAE,EAAE,CAAC;aAC/D,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACnC,IAAI,GAAG,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAc,EAAE,GAAW;IACnD,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AACpE,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAsB,EACtB,KAA6B,EAC7B,GAAW;IAEX,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CACzB,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,MAAM,CACrF,CAAC;IACF,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC;IAC/E,CAAC;IACD,yEAAyE;IACzE,6CAA6C;IAC7C,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC;QAC/C,OAAO;YACL,KAAK;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,qEAAqE;SAC9E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;AAClF,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,OAAe,EAAE,GAAW;IAC/C,MAAM,KAAK,GAAG,0CAA0C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC3E,CAAC;AAED,SAAS,mBAAmB,CAC1B,KAAsB,EACtB,KAA6B,EAC7B,GAAW;IAEX,MAAM,IAAI,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;IACtF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,MAAM;YAAE,SAAS,GAAG,KAAK,CAAC;IAC9E,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACrF,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO;YACL,KAAK;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,+EAA+E;SACxF,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;IACnF,CAAC;IACD,MAAM,WAAW,GAAG,KAAK;SACtB,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;SACpB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;IAC1E,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,KAAK;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,wDAAwD;SACjE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;AACpE,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,sBAAsB,CACpC,MAAkC,EAClC,KAA6B,EAC7B,GAAW;IAEX,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBACnD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC;YAC1F,CAAC;YACD,KAAK,cAAc;gBACjB,OAAO,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;YAC9C,KAAK,gBAAgB;gBACnB,OAAO,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,qBAAqB,CAAC,OAA+B;IACnE,MAAM,KAAK,GAAG,CAAC,MAAmB,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACzF,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,SAAS,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7D,IAAI,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;IAC7E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,OAA+B;IAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QACtD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QACtF,OAAO,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,sBAAsB,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* queue would silently eat the context window it is meant to save.
|
|
16
16
|
*/
|
|
17
17
|
/** Notification source. Extended as new push producers are added. */
|
|
18
|
-
export type NotificationKind = "subagent" | "process";
|
|
18
|
+
export type NotificationKind = "subagent" | "process" | "goal";
|
|
19
19
|
export interface AgentNotification {
|
|
20
20
|
kind: NotificationKind;
|
|
21
21
|
/** Producer-scoped identity (agent id, process id). Dedupe key with `kind`. */
|
|
@@ -6,10 +6,12 @@ import { SlashCommandRegistry } from "./slash-commands.js";
|
|
|
6
6
|
import { type BranchInfo, type KenTurnPayload, type AutopilotMarkerPayload, type AppMarkerPayload, type RunOutcome, type TurnMetricPayload } from "./session-manager.js";
|
|
7
7
|
import { type Skill } from "./skills.js";
|
|
8
8
|
import type { BackgroundProcess } from "./process-manager.js";
|
|
9
|
+
import { type ChildModelPick, type SubAgentSnapshot } from "./subagent-manager.js";
|
|
9
10
|
import type { MCPElicitHandler } from "./mcp/index.js";
|
|
10
11
|
import { type ContextLimits } from "./context-limits.js";
|
|
11
12
|
import { type ImportForeignTranscriptResult } from "./foreign-session-import.js";
|
|
12
13
|
import { type CacheExpiryStatus } from "./cache-expiry.js";
|
|
14
|
+
import { type AgentDefinition } from "./agents.js";
|
|
13
15
|
import { type EnhanceResult } from "../utils/prompt-enhancer.js";
|
|
14
16
|
import type { VerificationEvidence } from "./verification-evidence.js";
|
|
15
17
|
/** A chat attachment (image / video / other file) prepared for the model. The
|
|
@@ -122,6 +124,45 @@ export interface AgentSessionOptions {
|
|
|
122
124
|
* UI. Omitted by callers that don't want plan mode (CLI wires its own).
|
|
123
125
|
*/
|
|
124
126
|
onEnterPlan?: (reason?: string) => void | Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Built-in tools to keep in the core set instead of the deferred
|
|
129
|
+
* tool_search catalog: for a specialist whose job is a deferred tool (GG
|
|
130
|
+
* Goals orchestrates with spawn_agent and friends). Fixed for the session.
|
|
131
|
+
*/
|
|
132
|
+
coreTools?: readonly string[];
|
|
133
|
+
/**
|
|
134
|
+
* Default provider/model for the workers this session spawns, when their
|
|
135
|
+
* agent names no model of its own. Read at spawn time.
|
|
136
|
+
*/
|
|
137
|
+
getChildModel?: () => ChildModelPick | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Wrap each built-in tool once, at registration. Must keep the tool's name,
|
|
140
|
+
* description and parameters (only `execute` may change), so the tool block
|
|
141
|
+
* stays prompt-cache stable. Used by GG Goals to gate its own editing.
|
|
142
|
+
*/
|
|
143
|
+
wrapTool?: (tool: AgentTool) => AgentTool;
|
|
144
|
+
/**
|
|
145
|
+
* Built-in tools this session never has, removed at registration (before
|
|
146
|
+
* tiering) and left out of the system prompt's Tools section. Unlike
|
|
147
|
+
* `allowedTools`, the rest of the tool set and its tiering are untouched.
|
|
148
|
+
* Fixed for the session, so the cached tool block never changes. Used by
|
|
149
|
+
* GG Goals, which never edits or runs anything itself.
|
|
150
|
+
*/
|
|
151
|
+
withoutTools?: readonly string[];
|
|
152
|
+
/**
|
|
153
|
+
* A fixed team of sub-agents, replacing agent discovery (project, global
|
|
154
|
+
* and bundled): the only agents spawn_agent and subagent can start. Used by
|
|
155
|
+
* GG Goals, whose workers follow their own rules (goals-agent/goal-team.ts).
|
|
156
|
+
*/
|
|
157
|
+
subAgents?: readonly AgentDefinition[];
|
|
158
|
+
/**
|
|
159
|
+
* Start every spawned child with this session's extra workspace roots too
|
|
160
|
+
* (less the folder it works in), so it can read and change all of them.
|
|
161
|
+
* GG Goals' workers work across all of a goal's attached folders.
|
|
162
|
+
*/
|
|
163
|
+
shareRootsWithSubAgents?: boolean;
|
|
164
|
+
/** The sub-agent a spawned child is when the spawn names none (one of `subAgents`). */
|
|
165
|
+
defaultSubAgent?: string;
|
|
125
166
|
onExitPlan?: (planPath: string) => Promise<ToolExecuteResult>;
|
|
126
167
|
/**
|
|
127
168
|
* If provided, the session's tool set is filtered to ONLY these tool names
|
|
@@ -324,6 +365,9 @@ export declare class AgentSession {
|
|
|
324
365
|
* for no benefit.
|
|
325
366
|
*/
|
|
326
367
|
private activeLanguages;
|
|
368
|
+
/** Languages the model has already been given guidance for, via the system
|
|
369
|
+
* prompt or an appended language update. */
|
|
370
|
+
private announcedLanguages;
|
|
327
371
|
/** Shared with the tool layer so plan-mode restrictions read live state. */
|
|
328
372
|
private planModeRef;
|
|
329
373
|
/** Path of the approved plan currently being implemented, or undefined. When
|
|
@@ -671,6 +715,15 @@ export declare class AgentSession {
|
|
|
671
715
|
/** Clear the queue, returning the combined text (to restore to the composer).
|
|
672
716
|
* Queued attachments are dropped on cancel — the composer only restores text. */
|
|
673
717
|
drainQueue(): string;
|
|
718
|
+
/**
|
|
719
|
+
* Tell the agent a new fact at its next turn, as a short hidden message
|
|
720
|
+
* appended after the cached prompt (the same channel as a finished worker),
|
|
721
|
+
* so a mid-session change reaches it without re-rendering the prompt. A
|
|
722
|
+
* later note with the same id replaces one not yet delivered.
|
|
723
|
+
*/
|
|
724
|
+
notify(id: string, text: string): void;
|
|
725
|
+
/** This session's sub-agents (workers), newest-state, including ones restored after a restart. */
|
|
726
|
+
listSubAgents(): SubAgentSnapshot[];
|
|
674
727
|
/** Snapshot of background processes (bash run_in_background), newest-state. */
|
|
675
728
|
listBackgroundProcesses(): BackgroundProcess[];
|
|
676
729
|
/** Stop a background process by id. Returns a human-readable status string. */
|
|
@@ -745,16 +798,34 @@ export declare class AgentSession {
|
|
|
745
798
|
* context, return contract and Environment), or the standard prompt.
|
|
746
799
|
*/
|
|
747
800
|
private buildBasePrompt;
|
|
748
|
-
/**
|
|
749
|
-
* Add newly detected project languages. Returns true when the set grew and
|
|
750
|
-
* the standard prompt therefore needs a rebuild. Custom and sub-agent
|
|
751
|
-
* prompts never render packs, so detection is skipped for them.
|
|
752
|
-
*/
|
|
753
801
|
/**
|
|
754
802
|
* Bring the system prompt to the exact state the next provider request will
|
|
755
803
|
* send. Shared by real runs and {@link prewarm} so both see one prefix.
|
|
804
|
+
*
|
|
805
|
+
* Languages are re-detected at each task boundary. Before the first reply
|
|
806
|
+
* nothing is cached worth keeping, so a new language simply rebuilds the
|
|
807
|
+
* prompt. After that the prompt is a cached prefix and is left alone: the
|
|
808
|
+
* new language is announced by {@link announceNewLanguages} instead.
|
|
756
809
|
*/
|
|
757
810
|
private prepareSystemPromptForRequest;
|
|
811
|
+
private hasReply;
|
|
812
|
+
/**
|
|
813
|
+
* Give the model style packs for languages that appeared after its prompt
|
|
814
|
+
* was cached (e.g. the previous task scaffolded a TypeScript project), as a
|
|
815
|
+
* hidden message appended to the history rather than a prompt re-render that
|
|
816
|
+
* would throw away the whole cache. Runs just before a new user message is
|
|
817
|
+
* added, so the user's request stays the last thing the model reads and the
|
|
818
|
+
* update is saved in order with the rest of the conversation.
|
|
819
|
+
*/
|
|
820
|
+
private announceNewLanguages;
|
|
821
|
+
/**
|
|
822
|
+
* Whether this session renders language packs: the standard prompt, and a
|
|
823
|
+
* code-writing child (a sub-agent prompt with project context). A verbatim
|
|
824
|
+
* custom prompt never does, nor do user-facing specialist agents (Motion,
|
|
825
|
+
* goals) or recon children without project context.
|
|
826
|
+
*/
|
|
827
|
+
private languagesApply;
|
|
828
|
+
/** Add newly detected project languages. Returns true when the set grew. */
|
|
758
829
|
private refreshActiveLanguages;
|
|
759
830
|
/** Rebuild messages[0] from current plan-mode + approved-plan state. */
|
|
760
831
|
private rebuildSystemPromptInPlace;
|
|
@@ -26,7 +26,7 @@ import { createTools, createWebSearchTool, } from "../tools/index.js";
|
|
|
26
26
|
import { partitionToolsByTier } from "../tools/tool-tiers.js";
|
|
27
27
|
import { buildProcessCompletionFollowUp } from "./process-gate.js";
|
|
28
28
|
import { PLAN_SUBMISSION_NUDGE, shouldNudgePlanSubmission } from "./plan-submission-gate.js";
|
|
29
|
-
import { buildSubAgentCompletionFollowUp } from "./subagent-manager.js";
|
|
29
|
+
import { buildSubAgentCompletionFollowUp, } from "./subagent-manager.js";
|
|
30
30
|
import { applyAsyncSubagentPolicy } from "./subagent-policy.js";
|
|
31
31
|
import { resolveResponsesLite, resolveStrictTools, } from "./codex-request-shape.js";
|
|
32
32
|
import { subAgentDescription } from "../tools/subagent.js";
|
|
@@ -52,7 +52,7 @@ import { detectLanguages, detectProjectStack } from "./language-detector.js";
|
|
|
52
52
|
import { buildLoopBreakMessage } from "./loop-breaker.js";
|
|
53
53
|
import { buildRegroundingMessage, requestTextForRegrounding } from "./regrounding.js";
|
|
54
54
|
import { buildSemanticLoopJudgePrompt, buildSemanticLoopMessage, parseSemanticLoopVerdict, SEMANTIC_LOOP_JUDGE_TIMEOUT_MS, withJudgeTimeout, } from "./semantic-loop-check.js";
|
|
55
|
-
import { buildEnvDeltaMessage } from "./env-delta.js";
|
|
55
|
+
import { buildEnvDeltaMessage, buildLanguageUpdateMessage } from "./env-delta.js";
|
|
56
56
|
import { wrapSteeringText, buildNotificationSteeringText, STEERING_PREFIX } from "./steering.js";
|
|
57
57
|
import { AgentNotificationQueue } from "./agent-notifications.js";
|
|
58
58
|
import { VerificationGate, VERIFICATION_STATE_KIND } from "./verification-gate.js";
|
|
@@ -217,6 +217,9 @@ export class AgentSession {
|
|
|
217
217
|
* for no benefit.
|
|
218
218
|
*/
|
|
219
219
|
activeLanguages = new Set();
|
|
220
|
+
/** Languages the model has already been given guidance for, via the system
|
|
221
|
+
* prompt or an appended language update. */
|
|
222
|
+
announcedLanguages = new Set();
|
|
220
223
|
/** Shared with the tool layer so plan-mode restrictions read live state. */
|
|
221
224
|
planModeRef = { current: false };
|
|
222
225
|
/** Path of the approved plan currently being implemented, or undefined. When
|
|
@@ -306,7 +309,10 @@ export class AgentSession {
|
|
|
306
309
|
// Session manager. Agent-specific roots keep chat and coder histories isolated.
|
|
307
310
|
this.sessionManager = new SessionManager(this.opts.sessionRootDir ?? paths.sessionsDir);
|
|
308
311
|
const projectCustomization = this.opts.projectCustomization !== false;
|
|
309
|
-
|
|
312
|
+
// A sub-agent worker never creates them: the session that owns the
|
|
313
|
+
// project does. GG Goals' workers work in the user's attached folders,
|
|
314
|
+
// which mustn't gain empty .gg folders as a side effect.
|
|
315
|
+
if (projectCustomization && !this.opts.subagentWorker) {
|
|
310
316
|
// Ensure project-local .gg directories exist.
|
|
311
317
|
const localGGDir = path.join(this.cwd, ".gg");
|
|
312
318
|
await fs.mkdir(path.join(localGGDir, "skills"), { recursive: true });
|
|
@@ -327,16 +333,20 @@ export class AgentSession {
|
|
|
327
333
|
}
|
|
328
334
|
// Discover agents and create tools (with sub-agent support). Chat sessions
|
|
329
335
|
// can retain bundled workers without loading project/global customization.
|
|
330
|
-
const agents =
|
|
331
|
-
?
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
:
|
|
336
|
+
const agents = this.opts.subAgents
|
|
337
|
+
? [...this.opts.subAgents]
|
|
338
|
+
: projectCustomization
|
|
339
|
+
? await discoverAgents({
|
|
340
|
+
globalAgentsDir: paths.agentsDir,
|
|
341
|
+
projectDir: this.cwd,
|
|
342
|
+
})
|
|
343
|
+
: this.opts.globalSubagents
|
|
344
|
+
? await discoverAgents({ globalAgentsDir: paths.agentsDir })
|
|
345
|
+
: [];
|
|
338
346
|
const { tools: builtInTools, processManager, rebuildReadTool, clearReadTracker, recordBashReads, lspManager, debugManager, subAgentManager, } = await createTools(this.cwd, {
|
|
339
347
|
agents,
|
|
348
|
+
shareWorkspaceRoots: this.opts.shareRootsWithSubAgents,
|
|
349
|
+
defaultSubAgent: this.opts.defaultSubAgent,
|
|
340
350
|
skills: this.skills,
|
|
341
351
|
contextLimits: this.contextLimits,
|
|
342
352
|
provider: this.provider,
|
|
@@ -378,6 +388,7 @@ export class AgentSession {
|
|
|
378
388
|
getBaseUrl: () => this.baseUrl,
|
|
379
389
|
getCacheKey: () => this.getPromptCacheKey(),
|
|
380
390
|
getMaxPerModel: () => this.settingsManager.get("subagentMaxPerModel"),
|
|
391
|
+
getChildModel: this.opts.getChildModel,
|
|
381
392
|
// A persistent child is already the single allowed fan-out level. Blocking
|
|
382
393
|
// `subagent` here created a timeout sandwich: the nested call could consume
|
|
383
394
|
// the child's entire 10-minute turn budget, discarding all nested results.
|
|
@@ -405,6 +416,16 @@ export class AgentSession {
|
|
|
405
416
|
// a hallucinated call can't mutate the repo — and buildSystemPrompt below is
|
|
406
417
|
// fed the same filtered names so the Tools section matches exactly.
|
|
407
418
|
this.tools = this.opts.allowedTools ? tools.filter((t) => this.isToolAllowed(t.name)) : tools;
|
|
419
|
+
const without = new Set(this.opts.withoutTools ?? []);
|
|
420
|
+
if (without.size > 0)
|
|
421
|
+
this.tools = this.tools.filter((t) => !without.has(t.name));
|
|
422
|
+
// A host may wrap built-ins (GG Goals holds back its own editing once a
|
|
423
|
+
// goal is underway). Same names and schemas, so the cached tool block and
|
|
424
|
+
// the system prompt's Tools section are unchanged.
|
|
425
|
+
if (this.opts.wrapTool) {
|
|
426
|
+
const wrap = this.opts.wrapTool;
|
|
427
|
+
this.tools = this.tools.map((t) => wrap(t));
|
|
428
|
+
}
|
|
408
429
|
// Both delegation tools carry the agent roster; when both survive the
|
|
409
430
|
// allow-list, `subagent` points at `spawn_agent`'s copy instead.
|
|
410
431
|
if (this.tools.some((t) => t.name === "spawn_agent")) {
|
|
@@ -419,7 +440,14 @@ export class AgentSession {
|
|
|
419
440
|
// catalog must hold the wrapped tool so a promoted spawn still loads
|
|
420
441
|
// wait_agent.
|
|
421
442
|
this.promoteFollowUpTools();
|
|
422
|
-
const
|
|
443
|
+
const partition = partitionToolsByTier(this.tools);
|
|
444
|
+
// A session can keep chosen built-ins in its core set (GG Goals
|
|
445
|
+
// orchestrates, so its agent tools are always at hand). Fixed for the
|
|
446
|
+
// session, so the cached tool block stays byte-stable.
|
|
447
|
+
const keep = new Set(this.opts.coreTools ?? []);
|
|
448
|
+
const deferred = partition.deferred.filter((t) => !keep.has(t.name));
|
|
449
|
+
// Everything not deferred, in the original relative order.
|
|
450
|
+
const core = keep.size > 0 ? this.tools.filter((t) => !deferred.includes(t)) : partition.core;
|
|
423
451
|
if (deferred.length > 0) {
|
|
424
452
|
// Append-only: `core` preserves the original relative order and
|
|
425
453
|
// tool_search is pushed after it, so the serialized tool block that
|
|
@@ -454,6 +482,9 @@ export class AgentSession {
|
|
|
454
482
|
else {
|
|
455
483
|
await this.connectMcpServers();
|
|
456
484
|
}
|
|
485
|
+
// Detect languages before the first render so the opening prompt already
|
|
486
|
+
// carries their packs and only a genuinely new language needs an update.
|
|
487
|
+
this.refreshActiveLanguages();
|
|
457
488
|
const basePrompt = await this.buildBasePrompt(false, undefined);
|
|
458
489
|
this.baseSystemPrompt = basePrompt;
|
|
459
490
|
this.messages = [{ role: "system", content: this.withSystemPromptTail(basePrompt) }];
|
|
@@ -788,6 +819,7 @@ export class AgentSession {
|
|
|
788
819
|
if (slash?.kind === "template") {
|
|
789
820
|
// Prompt templates remain human-originated: the user invoked the command.
|
|
790
821
|
const userMessage = { role: "user", content: slash.fullPrompt, provenance };
|
|
822
|
+
await this.announceNewLanguages();
|
|
791
823
|
this.messages.push(userMessage);
|
|
792
824
|
await this.persistMessage(userMessage);
|
|
793
825
|
this.lastPersistedIndex = this.messages.length;
|
|
@@ -804,6 +836,7 @@ export class AgentSession {
|
|
|
804
836
|
}
|
|
805
837
|
// Push user message
|
|
806
838
|
const userMessage = { role: "user", content, provenance };
|
|
839
|
+
await this.announceNewLanguages();
|
|
807
840
|
this.messages.push(userMessage);
|
|
808
841
|
await this.persistMessage(userMessage);
|
|
809
842
|
this.lastPersistedIndex = this.messages.length;
|
|
@@ -828,6 +861,7 @@ export class AgentSession {
|
|
|
828
861
|
content: parts,
|
|
829
862
|
provenance: { source: "human", kind: "prompt", visibility: "transcript" },
|
|
830
863
|
};
|
|
864
|
+
await this.announceNewLanguages();
|
|
831
865
|
this.messages.push(userMessage);
|
|
832
866
|
await this.persistMessage(userMessage);
|
|
833
867
|
this.lastPersistedIndex = this.messages.length;
|
|
@@ -2442,6 +2476,9 @@ export class AgentSession {
|
|
|
2442
2476
|
// new session's /history, and get re-persisted into the new file by the
|
|
2443
2477
|
// next compaction — the cross-session duplicate-marker propagation bug.
|
|
2444
2478
|
this.markers.clear();
|
|
2479
|
+
// Detect languages before the first render so the opening prompt already
|
|
2480
|
+
// carries their packs and only a genuinely new language needs an update.
|
|
2481
|
+
this.refreshActiveLanguages();
|
|
2445
2482
|
const basePrompt = await this.buildBasePrompt(false, undefined);
|
|
2446
2483
|
this.baseSystemPrompt = basePrompt;
|
|
2447
2484
|
this.messages = [{ role: "system", content: this.withSystemPromptTail(basePrompt) }];
|
|
@@ -2645,6 +2682,19 @@ export class AgentSession {
|
|
|
2645
2682
|
.map((m) => m.text)
|
|
2646
2683
|
.join("\n\n");
|
|
2647
2684
|
}
|
|
2685
|
+
/**
|
|
2686
|
+
* Tell the agent a new fact at its next turn, as a short hidden message
|
|
2687
|
+
* appended after the cached prompt (the same channel as a finished worker),
|
|
2688
|
+
* so a mid-session change reaches it without re-rendering the prompt. A
|
|
2689
|
+
* later note with the same id replaces one not yet delivered.
|
|
2690
|
+
*/
|
|
2691
|
+
notify(id, text) {
|
|
2692
|
+
this.notifications.enqueue("goal", id, text, { terminal: true });
|
|
2693
|
+
}
|
|
2694
|
+
/** This session's sub-agents (workers), newest-state, including ones restored after a restart. */
|
|
2695
|
+
listSubAgents() {
|
|
2696
|
+
return this.subAgentManager?.list() ?? [];
|
|
2697
|
+
}
|
|
2648
2698
|
/** Snapshot of background processes (bash run_in_background), newest-state. */
|
|
2649
2699
|
listBackgroundProcesses() {
|
|
2650
2700
|
return this.processManager?.list() ?? [];
|
|
@@ -2797,6 +2847,8 @@ export class AgentSession {
|
|
|
2797
2847
|
return this.customSystemPrompt;
|
|
2798
2848
|
const toolNames = this.tools.map((tool) => tool.name);
|
|
2799
2849
|
const deferredToolNames = this.deferredToolNamesForPrompt(toolNames);
|
|
2850
|
+
// Whatever is rendered now is what the model has been told.
|
|
2851
|
+
this.announcedLanguages = new Set(this.activeLanguages);
|
|
2800
2852
|
if (this.agentPrompt !== undefined) {
|
|
2801
2853
|
return buildSubAgentSystemPrompt(this.agentPrompt, {
|
|
2802
2854
|
cwd: this.cwd,
|
|
@@ -2806,29 +2858,73 @@ export class AgentSession {
|
|
|
2806
2858
|
role: this.opts.agentRole,
|
|
2807
2859
|
environment: this.recordRenderedEnvironment(),
|
|
2808
2860
|
contextLimits: this.contextLimits,
|
|
2861
|
+
...(this.languagesApply() ? { activeLanguages: this.activeLanguages } : {}),
|
|
2809
2862
|
});
|
|
2810
2863
|
}
|
|
2811
2864
|
return buildSystemPrompt(this.cwd, this.skills, planMode, approvedPlanPath, toolNames, this.activeLanguages, this.provider, this.recordRenderedEnvironment(), deferredToolNames, this.contextLimits);
|
|
2812
2865
|
}
|
|
2813
|
-
/**
|
|
2814
|
-
* Add newly detected project languages. Returns true when the set grew and
|
|
2815
|
-
* the standard prompt therefore needs a rebuild. Custom and sub-agent
|
|
2816
|
-
* prompts never render packs, so detection is skipped for them.
|
|
2817
|
-
*/
|
|
2818
2866
|
/**
|
|
2819
2867
|
* Bring the system prompt to the exact state the next provider request will
|
|
2820
2868
|
* send. Shared by real runs and {@link prewarm} so both see one prefix.
|
|
2869
|
+
*
|
|
2870
|
+
* Languages are re-detected at each task boundary. Before the first reply
|
|
2871
|
+
* nothing is cached worth keeping, so a new language simply rebuilds the
|
|
2872
|
+
* prompt. After that the prompt is a cached prefix and is left alone: the
|
|
2873
|
+
* new language is announced by {@link announceNewLanguages} instead.
|
|
2821
2874
|
*/
|
|
2822
2875
|
async prepareSystemPromptForRequest() {
|
|
2823
|
-
|
|
2824
|
-
// during the previous turn gets its packs; the prompt is rebuilt only when
|
|
2825
|
-
// the set grows, keeping the cached prefix stable otherwise.
|
|
2826
|
-
if (this.refreshActiveLanguages())
|
|
2876
|
+
if (this.refreshActiveLanguages() && !this.hasReply()) {
|
|
2827
2877
|
await this.rebuildSystemPromptInPlace();
|
|
2878
|
+
}
|
|
2828
2879
|
this.refreshSystemPromptTail();
|
|
2829
2880
|
}
|
|
2881
|
+
hasReply() {
|
|
2882
|
+
return this.messages.some((m) => m.role === "assistant");
|
|
2883
|
+
}
|
|
2884
|
+
/**
|
|
2885
|
+
* Give the model style packs for languages that appeared after its prompt
|
|
2886
|
+
* was cached (e.g. the previous task scaffolded a TypeScript project), as a
|
|
2887
|
+
* hidden message appended to the history rather than a prompt re-render that
|
|
2888
|
+
* would throw away the whole cache. Runs just before a new user message is
|
|
2889
|
+
* added, so the user's request stays the last thing the model reads and the
|
|
2890
|
+
* update is saved in order with the rest of the conversation.
|
|
2891
|
+
*/
|
|
2892
|
+
async announceNewLanguages() {
|
|
2893
|
+
if (!this.hasReply())
|
|
2894
|
+
return; // the next request rebuilds the prompt instead
|
|
2895
|
+
this.refreshActiveLanguages();
|
|
2896
|
+
const fresh = new Set([...this.activeLanguages].filter((id) => !this.announcedLanguages.has(id)));
|
|
2897
|
+
if (fresh.size === 0)
|
|
2898
|
+
return;
|
|
2899
|
+
for (const id of fresh)
|
|
2900
|
+
this.announcedLanguages.add(id);
|
|
2901
|
+
const update = buildLanguageUpdateMessage(fresh, this.cwd);
|
|
2902
|
+
if (!update)
|
|
2903
|
+
return;
|
|
2904
|
+
this.messages.push(update);
|
|
2905
|
+
await this.persistMessage(update);
|
|
2906
|
+
this.lastPersistedIndex = this.messages.length;
|
|
2907
|
+
log("INFO", "language", "Appended style packs for new languages", {
|
|
2908
|
+
added: [...fresh].join(","),
|
|
2909
|
+
});
|
|
2910
|
+
}
|
|
2911
|
+
/**
|
|
2912
|
+
* Whether this session renders language packs: the standard prompt, and a
|
|
2913
|
+
* code-writing child (a sub-agent prompt with project context). A verbatim
|
|
2914
|
+
* custom prompt never does, nor do user-facing specialist agents (Motion,
|
|
2915
|
+
* goals) or recon children without project context.
|
|
2916
|
+
*/
|
|
2917
|
+
languagesApply() {
|
|
2918
|
+
if (this.customSystemPrompt)
|
|
2919
|
+
return false;
|
|
2920
|
+
if (this.agentPrompt === undefined)
|
|
2921
|
+
return true;
|
|
2922
|
+
return ((this.opts.agentRole ?? "subagent") === "subagent" &&
|
|
2923
|
+
(this.opts.agentContext ?? "project") === "project");
|
|
2924
|
+
}
|
|
2925
|
+
/** Add newly detected project languages. Returns true when the set grew. */
|
|
2830
2926
|
refreshActiveLanguages() {
|
|
2831
|
-
if (this.
|
|
2927
|
+
if (!this.languagesApply())
|
|
2832
2928
|
return false;
|
|
2833
2929
|
let grew = false;
|
|
2834
2930
|
try {
|