@gajae-code/coding-agent 0.12.6 → 0.12.8
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 +22 -1
- package/dist/types/async/job-manager.d.ts +36 -1
- package/dist/types/commands/notify.d.ts +4 -0
- package/dist/types/config/file-lock.d.ts +3 -0
- package/dist/types/config/model-discovery-manager.d.ts +6 -1
- package/dist/types/config/model-registry.d.ts +2 -0
- package/dist/types/config/resolve-config-value.d.ts +2 -1
- package/dist/types/config/settings-schema.d.ts +17 -1
- package/dist/types/eval/backend.d.ts +2 -2
- package/dist/types/exec/bash-executor.d.ts +8 -10
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +0 -36
- package/dist/types/internal-urls/registry-helpers.d.ts +0 -18
- package/dist/types/main.d.ts +1 -0
- package/dist/types/modes/components/hook-selector.d.ts +20 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +53 -4
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +4 -2
- package/dist/types/sdk/broker/broker.d.ts +5 -1
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +1 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +11 -3
- package/dist/types/sdk/bus/config.d.ts +75 -113
- package/dist/types/sdk/bus/discord-live-provider.d.ts +8 -2
- package/dist/types/sdk/bus/discord-provider.d.ts +19 -0
- package/dist/types/sdk/bus/index.d.ts +1 -1
- package/dist/types/sdk/bus/notification-orchestration.d.ts +127 -18
- package/dist/types/sdk/bus/notification-service.d.ts +31 -4
- package/dist/types/sdk/bus/session-control.d.ts +8 -3
- package/dist/types/sdk/bus/slack-live-provider.d.ts +9 -2
- package/dist/types/sdk/bus/slack-provider.d.ts +22 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -4
- package/dist/types/sdk/client/discovery.d.ts +2 -1
- package/dist/types/sdk/host/host.d.ts +2 -23
- package/dist/types/sdk/host/query/handlers.d.ts +2 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +4 -7
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/providers.d.ts +22 -0
- package/dist/types/sdk/session-directory.d.ts +1 -1
- package/dist/types/session/artifacts.d.ts +5 -8
- package/dist/types/session/client-bridge.d.ts +0 -14
- package/dist/types/session/internal/managed-session-scope.d.ts +17 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +11 -4
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -0
- package/dist/types/session/internal/session-open-errors.d.ts +5 -0
- package/dist/types/session/messages.d.ts +1 -4
- package/dist/types/session/session-manager.d.ts +7 -6
- package/dist/types/session/session-storage.d.ts +2 -0
- package/dist/types/session/streaming-output.d.ts +0 -32
- package/dist/types/task/receipt.d.ts +1 -2
- package/dist/types/task/types.d.ts +43 -178
- package/dist/types/tools/bash.d.ts +1 -1
- package/dist/types/tools/fetch.d.ts +0 -3
- package/dist/types/tools/output-meta.d.ts +5 -37
- package/dist/types/tools/subagent.d.ts +15 -0
- package/dist/types/tools/todo-write.d.ts +3 -0
- package/dist/types/tools/tool-result.d.ts +0 -1
- package/package.json +10 -8
- package/scripts/build-sdk-package-smoke.ts +51 -0
- package/scripts/capture-notifications-settings-showcase.ts +1 -1
- package/src/async/job-manager.ts +430 -46
- package/src/cli/notify-cli.ts +204 -94
- package/src/commands/notify.ts +19 -8
- package/src/config/file-lock.ts +6 -0
- package/src/config/model-discovery-manager.ts +50 -8
- package/src/config/model-registry.ts +862 -75
- package/src/config/resolve-config-value.ts +10 -8
- package/src/config/settings-schema.ts +25 -15
- package/src/config/settings.ts +15 -15
- package/src/cursor.ts +13 -20
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +2 -3
- package/src/eval/backend.ts +2 -2
- package/src/exec/bash-executor.ts +151 -425
- package/src/gjc-runtime/session-state-sidecar.ts +12 -2
- package/src/gjc-runtime/ultragoal-runtime.ts +3 -280
- package/src/gjc-runtime/workflow-manifest.generated.json +1 -40
- package/src/gjc-runtime/workflow-manifest.ts +0 -12
- package/src/internal-urls/agent-protocol.ts +38 -98
- package/src/internal-urls/artifact-protocol.ts +17 -28
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/internal-urls/registry-helpers.ts +0 -62
- package/src/main.ts +43 -7
- package/src/modes/DESIGN.md +11 -11
- package/src/modes/acp/acp-agent.ts +0 -24
- package/src/modes/acp/acp-client-bridge.ts +11 -154
- package/src/modes/components/hook-selector.ts +155 -44
- package/src/modes/components/model-selector.ts +242 -49
- package/src/modes/components/notifications-settings-editor.ts +631 -85
- package/src/modes/controllers/extension-ui-controller.ts +114 -15
- package/src/modes/controllers/selector-controller.ts +464 -50
- package/src/prompts/tools/bash.md +2 -2
- package/src/sdk/acp/adapter.ts +9 -200
- package/src/sdk/broker/broker.ts +54 -10
- package/src/sdk/broker/lifecycle-ledger.ts +34 -1
- package/src/sdk/broker/lifecycle.ts +47 -50
- package/src/sdk/bus/chat-daemon-cli.ts +12 -5
- package/src/sdk/bus/chat-daemon-control.ts +35 -8
- package/src/sdk/bus/chat-daemon-runtime.ts +16 -2
- package/src/sdk/bus/config.ts +534 -286
- package/src/sdk/bus/discord-live-provider.ts +57 -2
- package/src/sdk/bus/discord-provider.ts +21 -0
- package/src/sdk/bus/index.ts +105 -359
- package/src/sdk/bus/notification-orchestration.ts +371 -68
- package/src/sdk/bus/notification-service.ts +431 -130
- package/src/sdk/bus/session-control.ts +119 -44
- package/src/sdk/bus/slack-live-provider.ts +78 -2
- package/src/sdk/bus/slack-provider.ts +24 -0
- package/src/sdk/bus/telegram-daemon-cli.ts +9 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -4
- package/src/sdk/bus/telegram-daemon-control.ts +3 -3
- package/src/sdk/bus/telegram-daemon.ts +23 -15
- package/src/sdk/client/discovery.ts +10 -4
- package/src/sdk/host/host.ts +9 -187
- package/src/sdk/host/query/handlers.ts +20 -1
- package/src/sdk/host/reverse-leases.ts +42 -249
- package/src/sdk/index.ts +1 -0
- package/src/sdk/protocol/operation-inventory.generated.json +18 -0
- package/src/sdk/protocol/operation-registry.ts +5 -2
- package/src/sdk/providers.ts +51 -0
- package/src/sdk/session-directory.ts +1 -0
- package/src/sdk/session.ts +10 -7
- package/src/session/agent-session.ts +59 -202
- package/src/session/artifacts.ts +74 -211
- package/src/session/client-bridge.ts +0 -15
- package/src/session/internal/managed-session-scope.ts +981 -450
- package/src/session/internal/managed-session-storage.ts +362 -124
- package/src/session/internal/native-publish-outcome.ts +3 -1
- package/src/session/internal/session-open-errors.ts +11 -0
- package/src/session/messages.ts +7 -32
- package/src/session/session-manager.ts +48 -15
- package/src/session/session-storage.ts +72 -5
- package/src/session/streaming-output.ts +40 -198
- package/src/slash-commands/builtin-registry.ts +82 -4
- package/src/task/index.ts +237 -65
- package/src/task/receipt.ts +2 -4
- package/src/task/render.ts +0 -30
- package/src/task/types.ts +10 -34
- package/src/tools/ask.ts +1 -1
- package/src/tools/bash.ts +239 -818
- package/src/tools/eval.ts +4 -99
- package/src/tools/fetch.ts +15 -77
- package/src/tools/find.ts +3 -7
- package/src/tools/output-meta.ts +114 -696
- package/src/tools/search.ts +4 -9
- package/src/tools/subagent.ts +97 -75
- package/src/tools/telegram-send.ts +4 -2
- package/src/tools/todo-write.ts +47 -0
- package/src/tools/tool-result.ts +0 -1
- package/dist/types/gjc-runtime/ultragoal-review-source.d.ts +0 -83
- package/dist/types/utils/artifact-id.d.ts +0 -2
- package/src/gjc-runtime/ultragoal-review-source.ts +0 -378
- package/src/utils/artifact-id.ts +0 -6
|
@@ -16,22 +16,24 @@ const commandInFlight = new Map<string, Promise<string | undefined>>();
|
|
|
16
16
|
* Resolve a config value (API key, header value, etc.) to an actual value.
|
|
17
17
|
* - If starts with "!", executes the rest as a shell command and uses stdout (cached)
|
|
18
18
|
* - Otherwise checks environment variable first, then treats as literal (not cached)
|
|
19
|
+
* - `cacheScope` isolates command-cache entries when a caller rotates its config
|
|
19
20
|
*/
|
|
20
|
-
export async function resolveConfigValue(config: string): Promise<string | undefined> {
|
|
21
|
+
export async function resolveConfigValue(config: string, cacheScope?: string): Promise<string | undefined> {
|
|
21
22
|
if (config.startsWith("!")) {
|
|
22
|
-
return await executeCommand(config);
|
|
23
|
+
return await executeCommand(config, cacheScope);
|
|
23
24
|
}
|
|
24
25
|
const envValue = process.env[config];
|
|
25
26
|
return envValue || config;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
async function executeCommand(commandConfig: string): Promise<string | undefined> {
|
|
29
|
-
const
|
|
29
|
+
async function executeCommand(commandConfig: string, cacheScope?: string): Promise<string | undefined> {
|
|
30
|
+
const cacheKey = cacheScope === undefined ? commandConfig : `${cacheScope}\u0000${commandConfig}`;
|
|
31
|
+
const cached = commandResultCache.get(cacheKey);
|
|
30
32
|
if (cached !== undefined) {
|
|
31
33
|
return cached;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
const existing = commandInFlight.get(
|
|
36
|
+
const existing = commandInFlight.get(cacheKey);
|
|
35
37
|
if (existing) {
|
|
36
38
|
return await existing;
|
|
37
39
|
}
|
|
@@ -40,15 +42,15 @@ async function executeCommand(commandConfig: string): Promise<string | undefined
|
|
|
40
42
|
const promise = runShellCommand(command, 10_000)
|
|
41
43
|
.then(result => {
|
|
42
44
|
if (result !== undefined) {
|
|
43
|
-
commandResultCache.set(
|
|
45
|
+
commandResultCache.set(cacheKey, result);
|
|
44
46
|
}
|
|
45
47
|
return result;
|
|
46
48
|
})
|
|
47
49
|
.finally(() => {
|
|
48
|
-
commandInFlight.delete(
|
|
50
|
+
commandInFlight.delete(cacheKey);
|
|
49
51
|
});
|
|
50
52
|
|
|
51
|
-
commandInFlight.set(
|
|
53
|
+
commandInFlight.set(cacheKey, promise);
|
|
52
54
|
return await promise;
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -149,7 +149,7 @@ export type AnyUiMetadata = UiBase & {
|
|
|
149
149
|
|
|
150
150
|
interface BooleanDef {
|
|
151
151
|
type: "boolean";
|
|
152
|
-
default
|
|
152
|
+
default?: boolean;
|
|
153
153
|
ui?: UiBoolean;
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -285,6 +285,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
285
285
|
|
|
286
286
|
// Notifications (shared daemon with Telegram/Discord/Slack presentation adapters)
|
|
287
287
|
"notifications.enabled": { type: "boolean", default: false },
|
|
288
|
+
"notifications.telegram.enabled": { type: "boolean" },
|
|
288
289
|
"notifications.telegram.botToken": {
|
|
289
290
|
type: "string",
|
|
290
291
|
default: undefined,
|
|
@@ -336,10 +337,12 @@ export const SETTINGS_SCHEMA = {
|
|
|
336
337
|
},
|
|
337
338
|
},
|
|
338
339
|
"notifications.telegram.topics.nameTemplate": { type: "string", default: undefined },
|
|
340
|
+
"notifications.discord.enabled": { type: "boolean" },
|
|
339
341
|
"notifications.discord.botToken": { type: "string", default: undefined },
|
|
340
342
|
"notifications.discord.applicationId": { type: "string", default: undefined },
|
|
341
343
|
"notifications.discord.guildId": { type: "string", default: undefined },
|
|
342
344
|
"notifications.discord.parentChannelId": { type: "string", default: undefined },
|
|
345
|
+
"notifications.slack.enabled": { type: "boolean" },
|
|
343
346
|
"notifications.slack.botToken": { type: "string", default: undefined },
|
|
344
347
|
"notifications.slack.appToken": { type: "string", default: undefined },
|
|
345
348
|
"notifications.slack.workspaceId": { type: "string", default: undefined },
|
|
@@ -3646,25 +3649,28 @@ type Schema = typeof SETTINGS_SCHEMA;
|
|
|
3646
3649
|
export type SettingPath = keyof Schema;
|
|
3647
3650
|
|
|
3648
3651
|
/** Infer the value type for a setting path */
|
|
3649
|
-
export type SettingValue<P extends SettingPath> = Schema[P] extends { type: "boolean" }
|
|
3652
|
+
export type SettingValue<P extends SettingPath> = Schema[P] extends { type: "boolean"; default: boolean }
|
|
3650
3653
|
? boolean
|
|
3651
|
-
: Schema[P] extends { type: "
|
|
3652
|
-
?
|
|
3653
|
-
: Schema[P] extends { type: "
|
|
3654
|
-
?
|
|
3655
|
-
: Schema[P] extends { type: "
|
|
3656
|
-
?
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
: Schema[P] extends { type: "
|
|
3654
|
+
: Schema[P] extends { type: "boolean" }
|
|
3655
|
+
? boolean | undefined
|
|
3656
|
+
: Schema[P] extends { type: "string" }
|
|
3657
|
+
? string | undefined
|
|
3658
|
+
: Schema[P] extends { type: "number" }
|
|
3659
|
+
? number
|
|
3660
|
+
: Schema[P] extends { type: "enum"; values: infer V }
|
|
3661
|
+
? V extends readonly string[]
|
|
3662
|
+
? V[number]
|
|
3663
|
+
: never
|
|
3664
|
+
: Schema[P] extends { type: "array"; default: infer D }
|
|
3662
3665
|
? D
|
|
3663
|
-
:
|
|
3666
|
+
: Schema[P] extends { type: "record"; default: infer D }
|
|
3667
|
+
? D
|
|
3668
|
+
: never;
|
|
3664
3669
|
|
|
3665
3670
|
/** Get the default value for a setting path */
|
|
3666
3671
|
export function getDefault<P extends SettingPath>(path: P): SettingValue<P> {
|
|
3667
|
-
|
|
3672
|
+
const definition = SETTINGS_SCHEMA[path];
|
|
3673
|
+
return ("default" in definition ? definition.default : undefined) as SettingValue<P>;
|
|
3668
3674
|
}
|
|
3669
3675
|
|
|
3670
3676
|
/** Check if a path has UI metadata (should appear in settings panel) */
|
|
@@ -3991,6 +3997,7 @@ export interface MemoryGuardSettings {
|
|
|
3991
3997
|
export interface NotificationsSettings {
|
|
3992
3998
|
enabled: boolean;
|
|
3993
3999
|
telegram: {
|
|
4000
|
+
enabled?: boolean;
|
|
3994
4001
|
botToken: string | undefined;
|
|
3995
4002
|
chatId: string | undefined;
|
|
3996
4003
|
sound: "all" | "important" | "none";
|
|
@@ -4014,16 +4021,19 @@ export interface NotificationsSettings {
|
|
|
4014
4021
|
};
|
|
4015
4022
|
};
|
|
4016
4023
|
discord: {
|
|
4024
|
+
enabled?: boolean;
|
|
4017
4025
|
botToken: string | undefined;
|
|
4018
4026
|
applicationId: string | undefined;
|
|
4019
4027
|
guildId: string | undefined;
|
|
4020
4028
|
parentChannelId: string | undefined;
|
|
4021
4029
|
};
|
|
4022
4030
|
slack: {
|
|
4031
|
+
enabled?: boolean;
|
|
4023
4032
|
botToken: string | undefined;
|
|
4024
4033
|
appToken: string | undefined;
|
|
4025
4034
|
workspaceId: string | undefined;
|
|
4026
4035
|
channelId: string | undefined;
|
|
4036
|
+
authorizedUserId: string | undefined;
|
|
4027
4037
|
};
|
|
4028
4038
|
redact: boolean;
|
|
4029
4039
|
verbosity: "lean" | "verbose";
|
package/src/config/settings.ts
CHANGED
|
@@ -98,7 +98,7 @@ type DurableBatchRevision = {
|
|
|
98
98
|
};
|
|
99
99
|
type NotificationValidationState = {
|
|
100
100
|
malformedConfigRoot: boolean;
|
|
101
|
-
|
|
101
|
+
invalidNotificationGlobal: boolean;
|
|
102
102
|
generation: number;
|
|
103
103
|
};
|
|
104
104
|
type NotificationValidationRestoreGuard = {
|
|
@@ -378,7 +378,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
378
378
|
#hasMalformedConfigRoot = false;
|
|
379
379
|
/** YAML syntax was unrecoverable, so the loaded defaults are read-only until config.yml is repaired. */
|
|
380
380
|
#hasRecoveredConfigSyntax = false;
|
|
381
|
-
#
|
|
381
|
+
#hasInvalidNotificationGlobal = false;
|
|
382
382
|
#notificationValidationGeneration = 0;
|
|
383
383
|
/** Notification subtree fingerprint from the last raw durable config read. */
|
|
384
384
|
#durableNotificationFingerprint: string | undefined;
|
|
@@ -513,7 +513,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
513
513
|
*/
|
|
514
514
|
getNotificationSettingsSnapshot(): NotificationSettingsSnapshot {
|
|
515
515
|
return parseNotificationSettingsSnapshot(
|
|
516
|
-
this.#hasMalformedConfigRoot || this.#
|
|
516
|
+
this.#hasMalformedConfigRoot || this.#hasInvalidNotificationGlobal ? null : this.#rawNotificationConfig,
|
|
517
517
|
);
|
|
518
518
|
}
|
|
519
519
|
|
|
@@ -895,7 +895,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
895
895
|
cloned.#futureSchemaVersion = this.#futureSchemaVersion;
|
|
896
896
|
cloned.#hasMalformedConfigRoot = this.#hasMalformedConfigRoot;
|
|
897
897
|
cloned.#hasRecoveredConfigSyntax = this.#hasRecoveredConfigSyntax;
|
|
898
|
-
cloned.#
|
|
898
|
+
cloned.#hasInvalidNotificationGlobal = this.#hasInvalidNotificationGlobal;
|
|
899
899
|
cloned.#notificationValidationGeneration = this.#notificationValidationGeneration;
|
|
900
900
|
cloned.#global = structuredClone(this.#global);
|
|
901
901
|
cloned.#rawNotificationConfig = structuredClone(this.#rawNotificationConfig);
|
|
@@ -1149,7 +1149,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1149
1149
|
#resetYamlLoadState(): void {
|
|
1150
1150
|
this.#hasMalformedConfigRoot = false;
|
|
1151
1151
|
this.#hasRecoveredConfigSyntax = false;
|
|
1152
|
-
this.#
|
|
1152
|
+
this.#hasInvalidNotificationGlobal = false;
|
|
1153
1153
|
this.#schemaReport = { issues: [], valid: true };
|
|
1154
1154
|
this.#schemaMigrationPending = false;
|
|
1155
1155
|
this.#futureSchemaVersion = false;
|
|
@@ -1211,7 +1211,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1211
1211
|
parseNotificationSettingsSnapshot(parsedRaw);
|
|
1212
1212
|
} catch (error) {
|
|
1213
1213
|
if (!(error instanceof Error) || error.message !== "gjc_notify_daemon_invalid_configuration") throw error;
|
|
1214
|
-
this.#
|
|
1214
|
+
this.#hasInvalidNotificationGlobal = true;
|
|
1215
1215
|
}
|
|
1216
1216
|
}
|
|
1217
1217
|
this.#futureSchemaVersion =
|
|
@@ -1875,7 +1875,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1875
1875
|
#notificationValidationState(): NotificationValidationState {
|
|
1876
1876
|
return {
|
|
1877
1877
|
malformedConfigRoot: this.#hasMalformedConfigRoot,
|
|
1878
|
-
|
|
1878
|
+
invalidNotificationGlobal: this.#hasInvalidNotificationGlobal,
|
|
1879
1879
|
generation: this.#notificationValidationGeneration,
|
|
1880
1880
|
};
|
|
1881
1881
|
}
|
|
@@ -1900,7 +1900,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1900
1900
|
}
|
|
1901
1901
|
#restoreNotificationValidationState(state: NotificationValidationState): void {
|
|
1902
1902
|
this.#hasMalformedConfigRoot = state.malformedConfigRoot;
|
|
1903
|
-
this.#
|
|
1903
|
+
this.#hasInvalidNotificationGlobal = state.invalidNotificationGlobal;
|
|
1904
1904
|
}
|
|
1905
1905
|
#rejectAtomicNotificationRepairForMalformedRoot(patches: readonly AtomicYamlPatch[], root: unknown): void {
|
|
1906
1906
|
if (
|
|
@@ -1951,17 +1951,17 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1951
1951
|
#recomputeNotificationValidationFromRaw(): void {
|
|
1952
1952
|
if (this.#rawNotificationConfig === undefined) {
|
|
1953
1953
|
this.#hasMalformedConfigRoot = true;
|
|
1954
|
-
this.#
|
|
1954
|
+
this.#hasInvalidNotificationGlobal = false;
|
|
1955
1955
|
return;
|
|
1956
1956
|
}
|
|
1957
1957
|
try {
|
|
1958
1958
|
parseNotificationSettingsSnapshot(this.#rawNotificationConfig);
|
|
1959
1959
|
this.#hasMalformedConfigRoot = false;
|
|
1960
|
-
this.#
|
|
1960
|
+
this.#hasInvalidNotificationGlobal = false;
|
|
1961
1961
|
} catch (error) {
|
|
1962
1962
|
if (error instanceof Error && error.message === "gjc_notify_daemon_invalid_configuration") {
|
|
1963
1963
|
this.#hasMalformedConfigRoot = false;
|
|
1964
|
-
this.#
|
|
1964
|
+
this.#hasInvalidNotificationGlobal = true;
|
|
1965
1965
|
return;
|
|
1966
1966
|
}
|
|
1967
1967
|
throw error;
|
|
@@ -1973,10 +1973,10 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1973
1973
|
try {
|
|
1974
1974
|
parseNotificationSettingsSnapshot(this.#rawNotificationConfig);
|
|
1975
1975
|
this.#hasMalformedConfigRoot = false;
|
|
1976
|
-
this.#
|
|
1976
|
+
this.#hasInvalidNotificationGlobal = false;
|
|
1977
1977
|
} catch (error) {
|
|
1978
1978
|
if (error instanceof Error && error.message === "gjc_notify_daemon_invalid_configuration") {
|
|
1979
|
-
this.#
|
|
1979
|
+
this.#hasInvalidNotificationGlobal = true;
|
|
1980
1980
|
return;
|
|
1981
1981
|
}
|
|
1982
1982
|
throw error;
|
|
@@ -2054,9 +2054,9 @@ export class Settings implements NotificationSettingsReader {
|
|
|
2054
2054
|
// Setting Hooks
|
|
2055
2055
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2056
2056
|
|
|
2057
|
-
type SettingHook
|
|
2057
|
+
type SettingHook = (value: unknown, prev: unknown) => void;
|
|
2058
2058
|
|
|
2059
|
-
const SETTING_HOOKS: Partial<Record<SettingPath, SettingHook
|
|
2059
|
+
const SETTING_HOOKS: Partial<Record<SettingPath, SettingHook>> = {
|
|
2060
2060
|
"theme.dark": value => {
|
|
2061
2061
|
if (typeof value === "string") {
|
|
2062
2062
|
setAutoThemeMapping("dark", value);
|
package/src/cursor.ts
CHANGED
|
@@ -14,7 +14,6 @@ import type {
|
|
|
14
14
|
ToolResultMessage,
|
|
15
15
|
} from "@gajae-code/ai";
|
|
16
16
|
import { sanitizeText } from "@gajae-code/utils";
|
|
17
|
-
import { finalizeToolResultForDelivery } from "./tools/output-meta";
|
|
18
17
|
import { resolveToCwd } from "./tools/path-utils";
|
|
19
18
|
|
|
20
19
|
interface CursorExecBridgeOptions {
|
|
@@ -49,14 +48,6 @@ function buildToolErrorResult(message: string): AgentToolResult<unknown> {
|
|
|
49
48
|
};
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
async function buildFinalToolErrorResult(
|
|
53
|
-
options: CursorExecBridgeOptions,
|
|
54
|
-
toolName: string,
|
|
55
|
-
message: string,
|
|
56
|
-
): Promise<AgentToolResult<unknown>> {
|
|
57
|
-
return finalizeToolResultForDelivery(buildToolErrorResult(message), toolName, options.getToolContext?.());
|
|
58
|
-
}
|
|
59
|
-
|
|
60
51
|
async function executeTool(
|
|
61
52
|
options: CursorExecBridgeOptions,
|
|
62
53
|
toolName: string,
|
|
@@ -65,12 +56,11 @@ async function executeTool(
|
|
|
65
56
|
): Promise<ToolResultMessage> {
|
|
66
57
|
const tool = options.tools.get(toolName);
|
|
67
58
|
if (!tool) {
|
|
68
|
-
const result =
|
|
59
|
+
const result = buildToolErrorResult(`Tool "${toolName}" not available`);
|
|
69
60
|
return createToolResultMessage(toolCallId, toolName, result, true);
|
|
70
61
|
}
|
|
71
62
|
|
|
72
63
|
options.emitEvent?.({ type: "tool_execution_start", toolCallId, toolName, args });
|
|
73
|
-
const context = options.getToolContext?.();
|
|
74
64
|
|
|
75
65
|
let result: AgentToolResult<unknown>;
|
|
76
66
|
let isError = false;
|
|
@@ -92,10 +82,16 @@ async function executeTool(
|
|
|
92
82
|
: undefined;
|
|
93
83
|
|
|
94
84
|
try {
|
|
95
|
-
result = await tool.execute(
|
|
85
|
+
result = await tool.execute(
|
|
86
|
+
toolCallId,
|
|
87
|
+
args as Record<string, unknown>,
|
|
88
|
+
undefined,
|
|
89
|
+
onUpdate,
|
|
90
|
+
options.getToolContext?.(),
|
|
91
|
+
);
|
|
96
92
|
} catch (error) {
|
|
97
93
|
const message = error instanceof Error ? error.message : String(error);
|
|
98
|
-
result =
|
|
94
|
+
result = buildToolErrorResult(message);
|
|
99
95
|
isError = true;
|
|
100
96
|
}
|
|
101
97
|
|
|
@@ -137,7 +133,6 @@ async function executeDelete(options: CursorExecBridgeOptions, pathArg: string,
|
|
|
137
133
|
result = buildToolErrorResult(message);
|
|
138
134
|
isError = true;
|
|
139
135
|
}
|
|
140
|
-
result = await finalizeToolResultForDelivery(result, toolName, options.getToolContext?.());
|
|
141
136
|
|
|
142
137
|
options.emitEvent?.({ type: "tool_execution_end", toolCallId, toolName, result, isError });
|
|
143
138
|
return createToolResultMessage(toolCallId, toolName, result, isError);
|
|
@@ -227,9 +222,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
227
222
|
const globPath = `${args.path || "."}/${args.glob}`;
|
|
228
223
|
return executeTool(this.#optionsForCall(), "find", toolCallId, { paths: [globPath] });
|
|
229
224
|
}
|
|
230
|
-
const result =
|
|
231
|
-
this.#optionsForCall(),
|
|
232
|
-
"search",
|
|
225
|
+
const result = buildToolErrorResult(
|
|
233
226
|
"Cursor grep request rejected: pattern must not be empty. Provide a non-empty search pattern.",
|
|
234
227
|
);
|
|
235
228
|
return createToolResultMessage(toolCallId, "search", result, true);
|
|
@@ -279,7 +272,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
279
272
|
const toolName = "bash";
|
|
280
273
|
const tool = options.tools.get(toolName);
|
|
281
274
|
if (!tool) {
|
|
282
|
-
const result =
|
|
275
|
+
const result = buildToolErrorResult(`Tool "${toolName}" not available`);
|
|
283
276
|
return createToolResultMessage(toolCallId, toolName, result, true);
|
|
284
277
|
}
|
|
285
278
|
|
|
@@ -338,7 +331,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
338
331
|
result = await tool.execute(toolCallId, toolArgs, undefined, onUpdate, options.getToolContext?.());
|
|
339
332
|
} catch (error) {
|
|
340
333
|
const message = error instanceof Error ? error.message : String(error);
|
|
341
|
-
result =
|
|
334
|
+
result = buildToolErrorResult(message);
|
|
342
335
|
isError = true;
|
|
343
336
|
}
|
|
344
337
|
|
|
@@ -388,7 +381,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
388
381
|
if (!tool) {
|
|
389
382
|
const availableTools = Array.from(options.tools.keys()).filter(name => name.startsWith("mcp__"));
|
|
390
383
|
const message = formatMcpToolErrorMessage(toolName, availableTools);
|
|
391
|
-
const result =
|
|
384
|
+
const result = buildToolErrorResult(message);
|
|
392
385
|
return createToolResultMessage(toolCallId, toolName, result, true);
|
|
393
386
|
}
|
|
394
387
|
|
|
@@ -295,8 +295,7 @@ The heavyweight gate runs **once per boundary generation**, not once per story a
|
|
|
295
295
|
One generation freezes the change set and reviews it exactly once:
|
|
296
296
|
|
|
297
297
|
1. Run implementation verification for the boundary's cumulative change set.
|
|
298
|
-
2. **Freeze the change set.**
|
|
299
|
-
|
|
298
|
+
2. **Freeze the change set.** Compute one immutable `sourceHash` over the reviewed source. Every lane in this generation inspects that same frozen snapshot; a lane verdict carrying a different `sourceHash` is rejected.
|
|
300
299
|
3. **Run the cohort lanes on the frozen snapshot** — at most one `cleaner`, one `architect`, and one `qa` lane per generation. They may run in parallel because they share the frozen source; a second architect or QA lane in the same generation is rejected. The `cleaner` lane is the internal ai-slop-cleaner skill fragment run over the frozen change set: a read-only detector that emits an `AI SLOP CLEANUP REPORT`, and it still runs and records a passed/no-op report when there are no relevant edits. Its BLOCKING findings join the cohort findings rather than starting their own fix loop; advisory findings are included in the gate report only and are not written to the Ultragoal ledger.
|
|
301
300
|
4. Delegate an `architect` review covering all three lanes:
|
|
302
301
|
- architecture-side: system boundaries, layering, data/control flow, operational risks.
|
|
@@ -310,7 +309,7 @@ One generation freezes the change set and reviews it exactly once:
|
|
|
310
309
|
- API/package surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `api`, `package`, `consumer`, `black-box`, or `test-report`; examples: `api-package-test-report`, `package-consumer-report`, `black-box-api-receipt`. Algorithm/math surfaces require a real artifact file or typed receipt whose artifact `kind` contains one of `property`, `boundary`, `edge`, `adversarial`, `failure`, `math`, `algorithm`, or `test-report`; examples: `property-test-report`, `algorithm-boundary-report`. Bare `inlineEvidence` text alone is not sufficient for any surface.
|
|
311
310
|
- The mandatory **computer-use** red-team suite (`kill-switch-bypass`, `suspended-enforcement`, `permission-revoked`, …) is conditional, not universal: require it only when computer/desktop control is genuinely part of the product surface being dogfooded. For every other product type, prove the change through the matching live surface instead — browser-use automation for web/GUI, bash/CLI live invocation or argv replay for CLI, and real artifacts or typed receipts for API/package/algorithm/math. Editing docs, prompts, or skills that merely mention computer-use does not by itself make the computer-use suite applicable; pick the red-team surface that matches what the change actually ships.
|
|
312
311
|
7. The executor QA/red-team lane must report a matrix using `executorQa.contractCoverage`, `executorQa.surfaceEvidence`, `executorQa.adversarialCases`, and `executorQa.artifactRefs`. Not-applicable rows are allowed only in `contractCoverage` and `surfaceEvidence`; each `status: "not_applicable"` row requires `contractRef` plus `reason`. `adversarialCases` rows cannot be not-applicable.
|
|
313
|
-
8. **Join before repairing.** Fold all three lane verdicts and the final code review into the strict gate under `iteration.reviewCohort` (`
|
|
312
|
+
8. **Join before repairing.** Fold all three lane verdicts and the final code review into the strict gate under `iteration.reviewCohort` (`reviewGeneration`, `sourceHash`, `joined: true`, and the three `lanes`). No lane may checkpoint on its own, and no fix work starts until the findings are joined. Clean means `architectReview.architectureStatus`, `architectReview.productStatus`, and `architectReview.codeStatus` are all `"CLEAR"`, `architectReview.recommendation` is `"APPROVE"`, executor QA statuses are `"passed"`, iteration is `"passed"` with `fullRerun: true`, the cohort is joined with every lane clean and hash-bound, every evidence field is non-empty, every required matrix row is present, and every blockers array is empty. `COMMENT`, `WATCH`, `REQUEST CHANGES`, `BLOCK`, missing evidence, missing or shallow matrix rows, plan/code mismatches, or non-empty blockers are non-clean.
|
|
314
313
|
9. If the joined findings contain any blocker, do **not** checkpoint `complete` and do **not** call `goal({"op":"complete"})`. Record **one consolidated blocker batch** for all findings from the whole cohort instead of one story per lane:
|
|
315
314
|
```sh
|
|
316
315
|
gjc ultragoal record-review-blockers --goal-id <id> --title "Resolve verification blockers" --objective "<blocker-resolution objective>" --evidence "<joined cohort findings>"
|
package/src/eval/backend.ts
CHANGED
|
@@ -11,8 +11,8 @@ export interface ExecutorBackendExecOptions {
|
|
|
11
11
|
session: ToolSession;
|
|
12
12
|
deadlineMs: number;
|
|
13
13
|
reset: boolean;
|
|
14
|
-
artifactPath
|
|
15
|
-
artifactId
|
|
14
|
+
artifactPath: string | undefined;
|
|
15
|
+
artifactId: string | undefined;
|
|
16
16
|
onChunk: (chunk: string) => void;
|
|
17
17
|
}
|
|
18
18
|
|