johns-harness 2026.9.12 → 2026.9.14
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/README.md +12 -5
- package/dist/auth-profiles-5CHn7vq1.js +38 -3
- package/dist/commands-registry-C78-tPS3.js +14 -0
- package/dist/commands-registry-D0Jkz-Sn.js +14 -0
- package/dist/commands-registry-DJWLO-6B.js +14 -0
- package/dist/commands-registry-l51VuG0m.js +14 -0
- package/dist/compact-B247y5Qt.js +29 -3
- package/dist/config-koj5M_EO.js +76 -4
- package/dist/daemon-cli.js +76 -4
- package/dist/image-generate.js +269 -0
- package/dist/manifest-registry-BMEqbkWA.js +48 -1
- package/dist/manifest-registry-Ba187z7Z.js +48 -1
- package/dist/model-selection-BGlGpPgM.js +86 -4
- package/dist/model-selection-BU6wl1le.js +86 -4
- package/dist/model-selection-L7RMwsG-.js +38 -3
- package/dist/pi-embedded-C6ITuRXf.js +29 -3
- package/dist/pi-embedded-DoQsYfIY.js +29 -3
- package/dist/pi-embedded-helpers-CkWXaNFn.js +9 -0
- package/dist/pi-embedded-helpers-DLLQ3MsR.js +9 -0
- package/dist/plugin-sdk/bluebubbles.js +12 -0
- package/dist/plugin-sdk/commands-registry-B4ZP4Y1B.js +14 -0
- package/dist/plugin-sdk/commands-registry-B8Og-fWU.js +14 -0
- package/dist/plugin-sdk/commands-registry-BoAXxFpH.js +14 -0
- package/dist/plugin-sdk/commands-registry-Ca1h6XvV.js +14 -0
- package/dist/plugin-sdk/commands-registry-Do-Y2EhN.js +14 -0
- package/dist/plugin-sdk/commands-registry-DpRs-E_M.js +14 -0
- package/dist/plugin-sdk/config-4Fgm-yEH.js +86 -4
- package/dist/plugin-sdk/config-Di-lyCdh.js +86 -4
- package/dist/plugin-sdk/discord.js +76 -4
- package/dist/plugin-sdk/dispatch-BP0viZiL.js +29 -3
- package/dist/plugin-sdk/dispatch-CQsjmw7g.js +29 -3
- package/dist/plugin-sdk/dispatch-Cerq29sy.js +29 -3
- package/dist/plugin-sdk/dispatch-Cndjtt0g.js +29 -3
- package/dist/plugin-sdk/dispatch-UogiJYul.js +29 -3
- package/dist/plugin-sdk/feishu.js +12 -0
- package/dist/plugin-sdk/googlechat.js +12 -0
- package/dist/plugin-sdk/imessage.js +12 -0
- package/dist/plugin-sdk/mattermost.js +14 -0
- package/dist/plugin-sdk/model-auth-CX9cPHdC.js +86 -4
- package/dist/plugin-sdk/model-auth-Ciehz0x5.js +86 -4
- package/dist/plugin-sdk/model-auth-DVyo6JSX.js +86 -4
- package/dist/plugin-sdk/model-auth-kiHYHGrs.js +86 -4
- package/dist/plugin-sdk/model-selection-Dbj4jDYM.js +86 -4
- package/dist/plugin-sdk/pi-embedded-helpers-B89Z8pGU.js +9 -0
- package/dist/plugin-sdk/pi-embedded-helpers-BDFUaaiY.js +9 -0
- package/dist/plugin-sdk/pi-embedded-helpers-BnFhV3or.js +9 -0
- package/dist/plugin-sdk/pi-embedded-helpers-CRUVFL1T.js +9 -0
- package/dist/plugin-sdk/pi-embedded-helpers-CY7PsNpl.js +9 -0
- package/dist/plugin-sdk/pi-embedded-helpers-Dira0ZRW.js +9 -0
- package/dist/plugin-sdk/reply-DbZnH8-h.js +29 -3
- package/dist/plugin-sdk/signal.js +12 -0
- package/dist/plugin-sdk/slack.js +12 -0
- package/dist/plugin-sdk/telegram.js +12 -0
- package/dist/plugin-sdk/tlon.js +12 -0
- package/dist/plugin-sdk/twitch.js +12 -0
- package/dist/plugin-sdk/zalo.js +12 -0
- package/dist/plugin-sdk/zalouser.js +12 -0
- package/dist/redact-snapshot-CjeFvdcl.js +5 -0
- package/dist/redact-snapshot-DuqfRMA9.js +5 -0
- package/dist/reply-C5LKjXcC.js +29 -3
- package/dist/runtime-path.js +58 -0
- package/dist/tool-catalog-CFg6jrp9.js +9 -0
- package/dist/tool-catalog-DE9Q8xiB.js +9 -0
- package/dist/update-cli-Cm_l3W29.js +1 -1
- package/dist/update-command.js +276 -0
- package/docs/PATCHES.md +31 -0
- package/extensions/mr-memory/johnness.plugin.json +1 -0
- package/package.json +1 -1
- package/skills/openai-image-gen/SKILL.md +3 -3
- package/skills/openai-image-gen/scripts/gen.py +1 -1
- package/vendor/patched-deps/@mariozechner/pi-ai/dist/models.generated.js +279 -0
- package/vendor/patched-deps/@mariozechner/pi-ai/dist/models.js +5 -0
- package/skills/nano-banana-pro/SKILL.md +0 -65
- package/skills/nano-banana-pro/scripts/generate_image.py +0 -235
- package/skills/nano-banana-pro/scripts/test_generate_image.py +0 -36
package/README.md
CHANGED
|
@@ -53,6 +53,13 @@ Enable "Device code authorization for Codex" once in chatgpt.com > Settings > Se
|
|
|
53
53
|
For headless installs, run `johnness models auth login --device`; no browser or localhost callback needed.
|
|
54
54
|
Expired ChatGPT credentials trigger an owner notice with the `/login` recovery command.
|
|
55
55
|
|
|
56
|
+
<!-- JOHNNESS_PATCH_DEFAULTS_61 -->
|
|
57
|
+
### Batteries included
|
|
58
|
+
The harness ships the current model catalog and the short aliases `opus`, `sonnet`, `fable`, `astra`, `sol`, `luna`, `terra`, and `gpt`, so `/model opus` works on a fresh install with no `models.providers` block. Channels you configure load without a `plugins.allow` list; only an explicit `enabled: false` or `plugins.deny` turns one off. Updating the harness updates the catalog and aliases for every agent. Image generation and editing use GPT Image 2 through the `image_generate` tool: `openai-codex/gpt-image-2` on the ChatGPT subscription first, `openai/gpt-image-2` on the API key second (`agents.defaults.imageGenerationModel`).
|
|
59
|
+
|
|
60
|
+
### Updating from chat
|
|
61
|
+
Send `/update` to install the newest `johns-harness` on the machine the gateway runs on and restart into it; `/update 2026.9.14` pins an exact version. Owner only. The reply names the current and target versions, a second `/update` while one is running is refused, and the first message after the restart confirms the running version. On a writable host the package is reinstalled into the existing global prefix. On an immutable image with a persistent volume (Fly), it is installed into `$JOHNNESS_STATE_DIR/runtime/johnness` and the entrypoint prefers that runtime when it is newer than the image: `exec node "$(node /opt/johnness/lib/node_modules/johns-harness/dist/runtime-path.js)" gateway run`. `JOHNNESS_UPDATE_PREFIX` overrides the target. On failure the reply carries the last lines of npm output and the one command that fixes it.
|
|
62
|
+
|
|
56
63
|
### From source
|
|
57
64
|
|
|
58
65
|
```bash
|
|
@@ -64,8 +71,8 @@ node johnness.mjs --help
|
|
|
64
71
|
### Verify
|
|
65
72
|
|
|
66
73
|
```bash
|
|
67
|
-
npm test #
|
|
68
|
-
bash scripts/verify-patches.sh #
|
|
74
|
+
npm test # 767 tests against the installed dependency tree
|
|
75
|
+
bash scripts/verify-patches.sh # 360 checks across every patch family
|
|
69
76
|
```
|
|
70
77
|
|
|
71
78
|
## Launch a swarm with one command
|
|
@@ -111,7 +118,7 @@ Coding agents today run as isolated processes. Two agents on the same repository
|
|
|
111
118
|
- **Memory built for production.** Tiered recall that traces from consolidated reflections down to the verbatim record, surviving compaction and shared across the swarm. Installed and enabled by default.
|
|
112
119
|
- **Production authority per commit.** Promotion is granted to an exact SHA, never to a branch name, so one worker's authorization never covers another worker's commits.
|
|
113
120
|
- **An append-only action log.** Agents record every consequential action to `ACTION_LOG.md` and read it before acting.
|
|
114
|
-
- **A fixed runtime surface.** The core does not grow on a schedule. New mechanisms enter only to solve a demonstrated production failure, one narrow, tested, reversible patch at a time:
|
|
121
|
+
- **A fixed runtime surface.** The core does not grow on a schedule. New mechanisms enter only to solve a demonstrated production failure, one narrow, tested, reversible patch at a time: 62 patch families, each with a regression test and a rollback path.
|
|
115
122
|
- **Reliability with a definition.** Bounded retries, explicit failure states, exact-once continuation, context-pressure recovery, durable delivery, and supervised gateway recovery.
|
|
116
123
|
- **Coding first, phone optional.** Direct the work at a high level from a chat channel while agents plan, implement, test, coordinate, and stage releases unattended.
|
|
117
124
|
- **Local voice.** Optional native Whisper transcription of inbound audio, entirely on your machine. Off by default. [Setup](docs/NATIVE-WHISPER-MUSE.md).
|
|
@@ -178,7 +185,7 @@ The log is a [`RULES.md`](RULES.md) workspace convention enforced through the ac
|
|
|
178
185
|
|
|
179
186
|
## Patch families
|
|
180
187
|
|
|
181
|
-
The runtime carries
|
|
188
|
+
The runtime carries 62 patch families. Each is a production fix applied at the source with a regression test, a durable patch marker, and a rollback path. A verifier runs 360 checks against the package tree and installed dependencies, and 767 tests run against the installed dependency tree.
|
|
182
189
|
|
|
183
190
|
Every family follows the same six steps: reproduce the failure, trace the exact runtime path, make the smallest source-level change that restores the invariant, add a regression test and a patch marker, run the verifier, and retain rollback artifacts. The full index: [`docs/PATCHES.md`](docs/PATCHES.md).
|
|
184
191
|
|
|
@@ -195,7 +202,7 @@ Every family follows the same six steps: reproduce the failure, trace the exact
|
|
|
195
202
|
## Documentation
|
|
196
203
|
|
|
197
204
|
- [`docs/index.md`](docs/index.md): runtime docs, from gateway and channels to plugins, nodes, and CLI reference.
|
|
198
|
-
- [`docs/PATCHES.md`](docs/PATCHES.md): the
|
|
205
|
+
- [`docs/PATCHES.md`](docs/PATCHES.md): the 62 patch families, one record each.
|
|
199
206
|
- [`docs/NATIVE-WHISPER-MUSE.md`](docs/NATIVE-WHISPER-MUSE.md): local Whisper transcription setup.
|
|
200
207
|
- [`RULES.md`](RULES.md): the default operating rules, including Rule Zero on production authorization.
|
|
201
208
|
|
|
@@ -3536,6 +3536,9 @@ async function resolveImplicitBedrockProvider(params) {
|
|
|
3536
3536
|
//#region src/agents/model-selection.ts
|
|
3537
3537
|
const log$1 = createSubsystemLogger("model-selection");
|
|
3538
3538
|
const ANTHROPIC_MODEL_ALIASES = {
|
|
3539
|
+
"opus-5": "claude-opus-5", // JOHNNESS_PATCH_DEFAULTS_61
|
|
3540
|
+
"sonnet-5": "claude-sonnet-5",
|
|
3541
|
+
"fable-5.1": "claude-fable-5-1",
|
|
3539
3542
|
"opus-4.6": "claude-opus-4-6",
|
|
3540
3543
|
"opus-4.5": "claude-opus-4-5",
|
|
3541
3544
|
"sonnet-4.6": "claude-sonnet-4-6",
|
|
@@ -3683,6 +3686,16 @@ function resolveModelRefFromString(params) {
|
|
|
3683
3686
|
ref: aliasMatch.ref,
|
|
3684
3687
|
alias: aliasMatch.alias
|
|
3685
3688
|
};
|
|
3689
|
+
// JOHNNESS_PATCH_DEFAULTS_61: fall back to the shipped aliases (opus, sonnet, fable,
|
|
3690
|
+
// astra, sol, luna, terra, gpt) when the user config defines none.
|
|
3691
|
+
const builtinTarget = DEFAULT_MODEL_ALIASES[aliasKey];
|
|
3692
|
+
if (builtinTarget) {
|
|
3693
|
+
const builtinRef = parseModelRef(builtinTarget, params.defaultProvider);
|
|
3694
|
+
if (builtinRef) return {
|
|
3695
|
+
ref: builtinRef,
|
|
3696
|
+
alias: aliasKey
|
|
3697
|
+
};
|
|
3698
|
+
}
|
|
3686
3699
|
}
|
|
3687
3700
|
const parsed = parseModelRef(model, params.defaultProvider);
|
|
3688
3701
|
if (!parsed) return null;
|
|
@@ -5081,9 +5094,18 @@ let defaultWarnState = { warned: false };
|
|
|
5081
5094
|
const DEFAULT_MODEL_ALIASES = {
|
|
5082
5095
|
muse: "meta/muse-spark-1.3", // JOHNNESS_PATCH_MUSE_SPARK
|
|
5083
5096
|
"muse-spark": "meta/muse-spark-1.3",
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5097
|
+
// JOHNNESS_PATCH_DEFAULTS_61: current model aliases ship with the harness; user config
|
|
5098
|
+
// aliases (agents.defaults.models[*].alias) still take precedence.
|
|
5099
|
+
opus: "anthropic/claude-opus-5",
|
|
5100
|
+
sonnet: "anthropic/claude-sonnet-5",
|
|
5101
|
+
opus46: "anthropic/claude-opus-4-6",
|
|
5102
|
+
sonnet46: "anthropic/claude-sonnet-4-6",
|
|
5103
|
+
fable: "anthropic/claude-fable-5-1",
|
|
5104
|
+
astra: "openai-codex/gpt-6-astra",
|
|
5105
|
+
sol: "openai-codex/gpt-5.6-sol",
|
|
5106
|
+
luna: "openai-codex/gpt-5.6-luna",
|
|
5107
|
+
terra: "openai-codex/gpt-5.6-terra",
|
|
5108
|
+
gpt: "openai-codex/gpt-5.5",
|
|
5087
5109
|
"gpt-mini": "openai/gpt-5-mini",
|
|
5088
5110
|
gemini: "google/gemini-3.1-pro-preview",
|
|
5089
5111
|
"gemini-flash": "google/gemini-3-flash-preview",
|
|
@@ -6421,6 +6443,17 @@ function applyLegacyAudioTranscriptionModel(params) {
|
|
|
6421
6443
|
params.changes.push(params.alreadySetMessage);
|
|
6422
6444
|
}
|
|
6423
6445
|
const LEGACY_CONFIG_MIGRATIONS_PART_2 = [
|
|
6446
|
+
{
|
|
6447
|
+
id: "agent.image-generation-model-v1",
|
|
6448
|
+
describe: "Migrate agents.defaults.imageGenerationModel string to primary/fallbacks",
|
|
6449
|
+
apply: (raw, changes) => {
|
|
6450
|
+
const defaults = getRecord(getRecord(raw.agents)?.defaults);
|
|
6451
|
+
if (!defaults || typeof defaults.imageGenerationModel !== "string") return;
|
|
6452
|
+
const primary = defaults.imageGenerationModel.trim();
|
|
6453
|
+
defaults.imageGenerationModel = primary ? { primary, fallbacks: [] } : void 0;
|
|
6454
|
+
changes.push("Migrated agents.defaults.imageGenerationModel string to primary/fallbacks");
|
|
6455
|
+
}
|
|
6456
|
+
}, // JOHNNESS_PATCH_GPT_IMAGE_62
|
|
6424
6457
|
{
|
|
6425
6458
|
id: "agent.model-config-v2",
|
|
6426
6459
|
describe: "Migrate legacy agent.model/allowedModels/modelAliases/modelFallbacks/imageModelFallbacks to agent.models + model lists",
|
|
@@ -10854,6 +10887,7 @@ function isValidNonNegativeByteSizeString(value) {
|
|
|
10854
10887
|
const AgentDefaultsSchema = z.object({
|
|
10855
10888
|
model: AgentModelSchema.optional(),
|
|
10856
10889
|
imageModel: AgentModelSchema.optional(),
|
|
10890
|
+
imageGenerationModel: AgentModelSchema.optional(), // JOHNNESS_PATCH_GPT_IMAGE_62
|
|
10857
10891
|
pdfModel: AgentModelSchema.optional(),
|
|
10858
10892
|
pdfMaxBytesMb: z.number().positive().optional(),
|
|
10859
10893
|
pdfMaxPages: z.number().int().positive().optional(),
|
|
@@ -13762,6 +13796,7 @@ function validateConfigObjectWithPluginsBase(raw, opts) {
|
|
|
13762
13796
|
workspaceDir: resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)) ?? void 0
|
|
13763
13797
|
});
|
|
13764
13798
|
for (const diag of registry.diagnostics) {
|
|
13799
|
+
if (diag.level === "info") continue; // JOHNNESS_PATCH_DEFAULTS_61
|
|
13765
13800
|
let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
|
|
13766
13801
|
if (!diag.pluginId && diag.message.includes("plugin path not found")) path = "plugins.load.paths";
|
|
13767
13802
|
const message = `${diag.pluginId ? `plugin ${diag.pluginId}` : "plugin"}: ${diag.message}`;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// JOHNNESS_PATCH_UPDATE_COMMAND_62
|
|
1
2
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60
|
|
2
3
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60B
|
|
3
4
|
import { l as escapeRegExp } from "./utils-DC4zYvW0.js";
|
|
@@ -181,6 +182,19 @@ function buildChatCommands() {
|
|
|
181
182
|
captureRemaining: true
|
|
182
183
|
}]
|
|
183
184
|
}),
|
|
185
|
+
defineChatCommand({
|
|
186
|
+
key: "update",
|
|
187
|
+
nativeName: "update",
|
|
188
|
+
description: "Install the newest johns-harness and restart (owner only).",
|
|
189
|
+
textAlias: "/update",
|
|
190
|
+
category: "management",
|
|
191
|
+
args: [{
|
|
192
|
+
name: "version",
|
|
193
|
+
description: "Exact version to install (default latest)",
|
|
194
|
+
type: "string",
|
|
195
|
+
required: false
|
|
196
|
+
}]
|
|
197
|
+
}),
|
|
184
198
|
defineChatCommand({
|
|
185
199
|
key: "login",
|
|
186
200
|
nativeName: "login",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// JOHNNESS_PATCH_UPDATE_COMMAND_62
|
|
1
2
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60
|
|
2
3
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60B
|
|
3
4
|
import { D as isPlainObject, u as escapeRegExp } from "./logger-Bj0Xl6pn.js";
|
|
@@ -218,6 +219,19 @@ function buildChatCommands() {
|
|
|
218
219
|
captureRemaining: true
|
|
219
220
|
}]
|
|
220
221
|
}),
|
|
222
|
+
defineChatCommand({
|
|
223
|
+
key: "update",
|
|
224
|
+
nativeName: "update",
|
|
225
|
+
description: "Install the newest johns-harness and restart (owner only).",
|
|
226
|
+
textAlias: "/update",
|
|
227
|
+
category: "management",
|
|
228
|
+
args: [{
|
|
229
|
+
name: "version",
|
|
230
|
+
description: "Exact version to install (default latest)",
|
|
231
|
+
type: "string",
|
|
232
|
+
required: false
|
|
233
|
+
}]
|
|
234
|
+
}),
|
|
221
235
|
defineChatCommand({
|
|
222
236
|
key: "login",
|
|
223
237
|
nativeName: "login",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// JOHNNESS_PATCH_UPDATE_COMMAND_62
|
|
1
2
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60
|
|
2
3
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60B
|
|
3
4
|
import { D as isPlainObject, u as escapeRegExp } from "./logger-BW8uLq6f.js";
|
|
@@ -218,6 +219,19 @@ function buildChatCommands() {
|
|
|
218
219
|
captureRemaining: true
|
|
219
220
|
}]
|
|
220
221
|
}),
|
|
222
|
+
defineChatCommand({
|
|
223
|
+
key: "update",
|
|
224
|
+
nativeName: "update",
|
|
225
|
+
description: "Install the newest johns-harness and restart (owner only).",
|
|
226
|
+
textAlias: "/update",
|
|
227
|
+
category: "management",
|
|
228
|
+
args: [{
|
|
229
|
+
name: "version",
|
|
230
|
+
description: "Exact version to install (default latest)",
|
|
231
|
+
type: "string",
|
|
232
|
+
required: false
|
|
233
|
+
}]
|
|
234
|
+
}),
|
|
221
235
|
defineChatCommand({
|
|
222
236
|
key: "login",
|
|
223
237
|
nativeName: "login",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// JOHNNESS_PATCH_UPDATE_COMMAND_62
|
|
1
2
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60
|
|
2
3
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60B
|
|
3
4
|
import { Bi as DEFAULT_PROVIDER, Or as resolveConfiguredModelRef, zi as DEFAULT_MODEL } from "./auth-profiles-5CHn7vq1.js";
|
|
@@ -181,6 +182,19 @@ function buildChatCommands() {
|
|
|
181
182
|
captureRemaining: true
|
|
182
183
|
}]
|
|
183
184
|
}),
|
|
185
|
+
defineChatCommand({
|
|
186
|
+
key: "update",
|
|
187
|
+
nativeName: "update",
|
|
188
|
+
description: "Install the newest johns-harness and restart (owner only).",
|
|
189
|
+
textAlias: "/update",
|
|
190
|
+
category: "management",
|
|
191
|
+
args: [{
|
|
192
|
+
name: "version",
|
|
193
|
+
description: "Exact version to install (default latest)",
|
|
194
|
+
type: "string",
|
|
195
|
+
required: false
|
|
196
|
+
}]
|
|
197
|
+
}),
|
|
184
198
|
defineChatCommand({
|
|
185
199
|
key: "login",
|
|
186
200
|
nativeName: "login",
|
package/dist/compact-B247y5Qt.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createImageGenerateTool } from "./image-generate.js";
|
|
2
|
+
import { handleUpdateCommand } from "./update-command.js";
|
|
1
3
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60
|
|
2
4
|
// JOHNNESS_PATCH_DEVICE_LOGIN_60B
|
|
3
5
|
import { handleDeviceLoginCommand } from "./codex-oauth-device.js";
|
|
@@ -11283,6 +11285,7 @@ const TRUSTED_TOOL_RESULT_MEDIA = new Set([
|
|
|
11283
11285
|
"exec",
|
|
11284
11286
|
"gateway",
|
|
11285
11287
|
"image",
|
|
11288
|
+
"image_generate",
|
|
11286
11289
|
"memory_get",
|
|
11287
11290
|
"memory_search",
|
|
11288
11291
|
"message",
|
|
@@ -15583,7 +15586,8 @@ function buildAgentSystemPrompt(params) {
|
|
|
15583
15586
|
sessions_spawn: acpSpawnRuntimeEnabled ? "Spawn an isolated sub-agent or ACP coding session (runtime=\"acp\" requires `agentId` unless `acp.defaultAgent` is configured; ACP harness ids follow acp.allowedAgents, not agents_list)" : "Spawn an isolated sub-agent session",
|
|
15584
15587
|
subagents: "List, steer, or kill sub-agent runs for this requester session",
|
|
15585
15588
|
session_status: "Show a /status-equivalent status card (usage + time + Reasoning/Verbose/Elevated); use for model-use questions (📊 session_status); optional per-session model override",
|
|
15586
|
-
image: "Analyze an image with the configured image model"
|
|
15589
|
+
image: "Analyze an image with the configured image model",
|
|
15590
|
+
image_generate: "Generate or edit images with GPT Image 2 (subscription first, API key second)"
|
|
15587
15591
|
};
|
|
15588
15592
|
const toolOrder = [
|
|
15589
15593
|
"read",
|
|
@@ -15610,7 +15614,8 @@ function buildAgentSystemPrompt(params) {
|
|
|
15610
15614
|
"sessions_send",
|
|
15611
15615
|
"subagents",
|
|
15612
15616
|
"session_status",
|
|
15613
|
-
"image"
|
|
15617
|
+
"image",
|
|
15618
|
+
"image_generate"
|
|
15614
15619
|
];
|
|
15615
15620
|
const canonicalToolNames = (params.toolNames ?? []).map((tool) => tool.trim()).filter(Boolean);
|
|
15616
15621
|
const canonicalByNormalized = /* @__PURE__ */ new Map();
|
|
@@ -40979,6 +40984,8 @@ function resolveSessionEntryForHookSessionKey(sessionStore, sessionKey) {
|
|
|
40979
40984
|
async function handleCommands(params) {
|
|
40980
40985
|
const deviceLoginReply = await handleDeviceLoginCommand(params, shouldHandleTextCommands({ cfg: params.cfg, surface: params.command.surface, commandSource: params.ctx.CommandSource }), { routeReply, callGateway });
|
|
40981
40986
|
if (deviceLoginReply) return deviceLoginReply;
|
|
40987
|
+
const updateReply = await handleUpdateCommand(params, shouldHandleTextCommands({ cfg: params.cfg, surface: params.command.surface, commandSource: params.ctx.CommandSource }), { routeReply, callGateway, writeRestartSentinel, extractDeliveryInfo, restart: () => scheduleGatewaySigusr1Restart({ reason: "/update" }) }); // JOHNNESS_PATCH_UPDATE_COMMAND_62
|
|
40988
|
+
if (updateReply) return updateReply;
|
|
40982
40989
|
if (HANDLERS === null) HANDLERS = [
|
|
40983
40990
|
handlePluginCommand,
|
|
40984
40991
|
handleBashCommand,
|
|
@@ -55646,6 +55653,16 @@ function createJohnnessTools(options) {
|
|
|
55646
55653
|
fsPolicy: options?.fsPolicy,
|
|
55647
55654
|
modelHasVision: options?.modelHasVision
|
|
55648
55655
|
}) : null;
|
|
55656
|
+
const imageGenerateTool = options?.agentDir?.trim() ? createImageGenerateTool({
|
|
55657
|
+
config: options?.config,
|
|
55658
|
+
agentDir: options.agentDir,
|
|
55659
|
+
workspaceDir,
|
|
55660
|
+
sandbox: options?.sandboxRoot && options?.sandboxFsBridge ? { root: options.sandboxRoot, bridge: options.sandboxFsBridge } : void 0
|
|
55661
|
+
}, {
|
|
55662
|
+
resolveApiKeyForProvider,
|
|
55663
|
+
loadWebMedia,
|
|
55664
|
+
localRoots: resolveMediaToolLocalRoots(workspaceDir, { workspaceOnly: options?.fsPolicy?.workspaceOnly === true })
|
|
55665
|
+
}) : null; // JOHNNESS_PATCH_GPT_IMAGE_62
|
|
55649
55666
|
const pdfTool = options?.agentDir?.trim() ? createPdfTool({
|
|
55650
55667
|
config: options?.config,
|
|
55651
55668
|
agentDir: options.agentDir,
|
|
@@ -55765,6 +55782,7 @@ function createJohnnessTools(options) {
|
|
|
55765
55782
|
...webSearchTool ? [webSearchTool] : [],
|
|
55766
55783
|
...webFetchTool ? [webFetchTool] : [],
|
|
55767
55784
|
...imageTool ? [imageTool] : [],
|
|
55785
|
+
...imageGenerateTool ? [imageGenerateTool] : [],
|
|
55768
55786
|
...pdfTool ? [pdfTool] : []
|
|
55769
55787
|
];
|
|
55770
55788
|
const pluginTools = resolvePluginTools({
|
|
@@ -92632,7 +92650,10 @@ function isTrackedByProvenance(params) {
|
|
|
92632
92650
|
function warnWhenAllowlistIsOpen(params) {
|
|
92633
92651
|
if (!params.pluginsEnabled) return;
|
|
92634
92652
|
if (params.allow.length > 0) return;
|
|
92635
|
-
|
|
92653
|
+
// JOHNNESS_PATCH_DEFAULTS_61: plugins the config already implies (memory slot, enabled
|
|
92654
|
+
// entries, install records) are trusted by construction and never warned about.
|
|
92655
|
+
const implied = params.impliedIds ?? new Set();
|
|
92656
|
+
const nonBundled = params.discoverablePlugins.filter((entry) => entry.origin !== "bundled" && !implied.has(entry.id));
|
|
92636
92657
|
if (nonBundled.length === 0) return;
|
|
92637
92658
|
const preview = nonBundled.slice(0, 6).map((entry) => `${entry.id} (${entry.source})`).join(", ");
|
|
92638
92659
|
const extra = nonBundled.length > 6 ? ` (+${nonBundled.length - 6} more)` : "";
|
|
@@ -92730,6 +92751,11 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
92730
92751
|
logger,
|
|
92731
92752
|
pluginsEnabled: normalized.enabled,
|
|
92732
92753
|
allow: normalized.allow,
|
|
92754
|
+
impliedIds: new Set([
|
|
92755
|
+
...typeof normalized.slots.memory === "string" ? [normalized.slots.memory] : [],
|
|
92756
|
+
...Object.entries(normalized.entries).filter(([, entry]) => entry?.enabled === true).map(([id]) => id),
|
|
92757
|
+
...Object.keys(cfg.plugins?.installs ?? {})
|
|
92758
|
+
]), // JOHNNESS_PATCH_DEFAULTS_61
|
|
92733
92759
|
discoverablePlugins: manifestRegistry.plugins.map((plugin) => ({
|
|
92734
92760
|
id: plugin.id,
|
|
92735
92761
|
source: plugin.source,
|
package/dist/config-koj5M_EO.js
CHANGED
|
@@ -1573,6 +1573,9 @@ function normalizeGoogleModelId(id) {
|
|
|
1573
1573
|
}
|
|
1574
1574
|
createSubsystemLogger("model-selection");
|
|
1575
1575
|
const ANTHROPIC_MODEL_ALIASES = {
|
|
1576
|
+
"opus-5": "claude-opus-5", // JOHNNESS_PATCH_DEFAULTS_61
|
|
1577
|
+
"sonnet-5": "claude-sonnet-5",
|
|
1578
|
+
"fable-5.1": "claude-fable-5-1",
|
|
1576
1579
|
"opus-4.6": "claude-opus-4-6",
|
|
1577
1580
|
"opus-4.5": "claude-opus-4-5",
|
|
1578
1581
|
"sonnet-4.6": "claude-sonnet-4-6",
|
|
@@ -1788,9 +1791,18 @@ let defaultWarnState = { warned: false };
|
|
|
1788
1791
|
const DEFAULT_MODEL_ALIASES = {
|
|
1789
1792
|
muse: "meta/muse-spark-1.3", // JOHNNESS_PATCH_MUSE_SPARK
|
|
1790
1793
|
"muse-spark": "meta/muse-spark-1.3",
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
+
// JOHNNESS_PATCH_DEFAULTS_61: current model aliases ship with the harness; user config
|
|
1795
|
+
// aliases (agents.defaults.models[*].alias) still take precedence.
|
|
1796
|
+
opus: "anthropic/claude-opus-5",
|
|
1797
|
+
sonnet: "anthropic/claude-sonnet-5",
|
|
1798
|
+
opus46: "anthropic/claude-opus-4-6",
|
|
1799
|
+
sonnet46: "anthropic/claude-sonnet-4-6",
|
|
1800
|
+
fable: "anthropic/claude-fable-5-1",
|
|
1801
|
+
astra: "openai-codex/gpt-6-astra",
|
|
1802
|
+
sol: "openai-codex/gpt-5.6-sol",
|
|
1803
|
+
luna: "openai-codex/gpt-5.6-luna",
|
|
1804
|
+
terra: "openai-codex/gpt-5.6-terra",
|
|
1805
|
+
gpt: "openai-codex/gpt-5.5",
|
|
1794
1806
|
"gpt-mini": "openai/gpt-5-mini",
|
|
1795
1807
|
gemini: "google/gemini-3.1-pro-preview",
|
|
1796
1808
|
"gemini-flash": "google/gemini-3-flash-preview",
|
|
@@ -3120,6 +3132,17 @@ function applyLegacyAudioTranscriptionModel(params) {
|
|
|
3120
3132
|
params.changes.push(params.alreadySetMessage);
|
|
3121
3133
|
}
|
|
3122
3134
|
const LEGACY_CONFIG_MIGRATIONS_PART_2 = [
|
|
3135
|
+
{
|
|
3136
|
+
id: "agent.image-generation-model-v1",
|
|
3137
|
+
describe: "Migrate agents.defaults.imageGenerationModel string to primary/fallbacks",
|
|
3138
|
+
apply: (raw, changes) => {
|
|
3139
|
+
const defaults = getRecord(getRecord(raw.agents)?.defaults);
|
|
3140
|
+
if (!defaults || typeof defaults.imageGenerationModel !== "string") return;
|
|
3141
|
+
const primary = defaults.imageGenerationModel.trim();
|
|
3142
|
+
defaults.imageGenerationModel = primary ? { primary, fallbacks: [] } : void 0;
|
|
3143
|
+
changes.push("Migrated agents.defaults.imageGenerationModel string to primary/fallbacks");
|
|
3144
|
+
}
|
|
3145
|
+
}, // JOHNNESS_PATCH_GPT_IMAGE_62
|
|
3123
3146
|
{
|
|
3124
3147
|
id: "agent.model-config-v2",
|
|
3125
3148
|
describe: "Migrate legacy agent.model/allowedModels/modelAliases/modelFallbacks/imageModelFallbacks to agent.models + model lists",
|
|
@@ -4407,7 +4430,9 @@ function isBundledChannelEnabledByChannelConfig(cfg, pluginId) {
|
|
|
4407
4430
|
if (!channelId) return false;
|
|
4408
4431
|
const entry = cfg.channels?.[channelId];
|
|
4409
4432
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
4410
|
-
|
|
4433
|
+
// JOHNNESS_PATCH_DEFAULTS_61: a configured channel block implies the bundled channel
|
|
4434
|
+
// plugin. Only an explicit enabled:false opts out; no plugins.allow needed.
|
|
4435
|
+
return entry.enabled !== false;
|
|
4411
4436
|
}
|
|
4412
4437
|
function resolveEffectiveEnableState(params) {
|
|
4413
4438
|
const base = resolveEnableState(params.id, params.origin, params.config);
|
|
@@ -5091,6 +5116,18 @@ function safeStatMtimeMs(filePath) {
|
|
|
5091
5116
|
return null;
|
|
5092
5117
|
}
|
|
5093
5118
|
}
|
|
5119
|
+
// JOHNNESS_PATCH_DEFAULTS_61: loose semver compare for bundled-vs-installed plugin dedupe.
|
|
5120
|
+
function compareJohnnessPluginVersions(a, b) {
|
|
5121
|
+
const parse = (value) => String(value ?? "").trim().replace(/^v/i, "").split(/[-+]/)[0].split(".").map((part) => Number.parseInt(part, 10)).map((part) => Number.isFinite(part) ? part : 0);
|
|
5122
|
+
const left = parse(a);
|
|
5123
|
+
const right = parse(b);
|
|
5124
|
+
const len = Math.max(left.length, right.length, 1);
|
|
5125
|
+
for (let i = 0; i < len; i += 1) {
|
|
5126
|
+
const diff = (left[i] ?? 0) - (right[i] ?? 0);
|
|
5127
|
+
if (diff !== 0) return diff > 0 ? 1 : -1;
|
|
5128
|
+
}
|
|
5129
|
+
return 0;
|
|
5130
|
+
}
|
|
5094
5131
|
function normalizeManifestLabel(raw) {
|
|
5095
5132
|
const trimmed = raw?.trim();
|
|
5096
5133
|
return trimmed ? trimmed : void 0;
|
|
@@ -5187,6 +5224,39 @@ function loadPluginManifestRegistry(params) {
|
|
|
5187
5224
|
}
|
|
5188
5225
|
continue;
|
|
5189
5226
|
}
|
|
5227
|
+
// JOHNNESS_PATCH_DEFAULTS_61: the same plugin id bundled with the harness and installed
|
|
5228
|
+
// under the state dir is the normal shape (mr-memory). The installed copy stays
|
|
5229
|
+
// authoritative (family 59) with no warning; when the bundled copy is newer by
|
|
5230
|
+
// package version, one info line suggests updating. Two non-bundled copies
|
|
5231
|
+
// still warn as before.
|
|
5232
|
+
const existingBundled = existing.candidate.origin === "bundled";
|
|
5233
|
+
const candidateBundled = candidate.origin === "bundled";
|
|
5234
|
+
if (existingBundled !== candidateBundled) {
|
|
5235
|
+
const existingRecord = records[existing.recordIndex];
|
|
5236
|
+
const candidateVersion = normalizeManifestLabel(manifest.version) ?? candidate.packageVersion;
|
|
5237
|
+
const bundledVersion = existingBundled ? existingRecord?.version : candidateVersion;
|
|
5238
|
+
const installedVersion = existingBundled ? candidateVersion : existingRecord?.version;
|
|
5239
|
+
if (existingBundled) {
|
|
5240
|
+
records[existing.recordIndex] = buildRecord({
|
|
5241
|
+
manifest,
|
|
5242
|
+
candidate,
|
|
5243
|
+
manifestPath: manifestRes.manifestPath,
|
|
5244
|
+
schemaCacheKey,
|
|
5245
|
+
configSchema
|
|
5246
|
+
});
|
|
5247
|
+
seenIds.set(manifest.id, {
|
|
5248
|
+
candidate,
|
|
5249
|
+
recordIndex: existing.recordIndex
|
|
5250
|
+
});
|
|
5251
|
+
}
|
|
5252
|
+
if (compareJohnnessPluginVersions(bundledVersion, installedVersion) > 0) diagnostics.push({
|
|
5253
|
+
level: "info",
|
|
5254
|
+
pluginId: manifest.id,
|
|
5255
|
+
source: candidate.source,
|
|
5256
|
+
message: `installed copy ${installedVersion ?? "?"} is older than the bundled ${bundledVersion ?? "?"}; run "johnness plugins update ${manifest.id}" to upgrade`
|
|
5257
|
+
});
|
|
5258
|
+
continue;
|
|
5259
|
+
}
|
|
5190
5260
|
diagnostics.push({
|
|
5191
5261
|
level: "warn",
|
|
5192
5262
|
pluginId: manifest.id,
|
|
@@ -6703,6 +6773,7 @@ function isValidNonNegativeByteSizeString(value) {
|
|
|
6703
6773
|
const AgentDefaultsSchema = z.object({
|
|
6704
6774
|
model: AgentModelSchema.optional(),
|
|
6705
6775
|
imageModel: AgentModelSchema.optional(),
|
|
6776
|
+
imageGenerationModel: AgentModelSchema.optional(), // JOHNNESS_PATCH_GPT_IMAGE_62
|
|
6706
6777
|
pdfModel: AgentModelSchema.optional(),
|
|
6707
6778
|
pdfMaxBytesMb: z.number().positive().optional(),
|
|
6708
6779
|
pdfMaxPages: z.number().int().positive().optional(),
|
|
@@ -9576,6 +9647,7 @@ function validateConfigObjectWithPluginsBase(raw, opts) {
|
|
|
9576
9647
|
workspaceDir: resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)) ?? void 0
|
|
9577
9648
|
});
|
|
9578
9649
|
for (const diag of registry.diagnostics) {
|
|
9650
|
+
if (diag.level === "info") continue; // JOHNNESS_PATCH_DEFAULTS_61
|
|
9579
9651
|
let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
|
|
9580
9652
|
if (!diag.pluginId && diag.message.includes("plugin path not found")) path = "plugins.load.paths";
|
|
9581
9653
|
const message = `${diag.pluginId ? `plugin ${diag.pluginId}` : "plugin"}: ${diag.message}`;
|
package/dist/daemon-cli.js
CHANGED
|
@@ -4724,6 +4724,9 @@ function normalizeGoogleModelId(id) {
|
|
|
4724
4724
|
}
|
|
4725
4725
|
createSubsystemLogger("model-selection");
|
|
4726
4726
|
const ANTHROPIC_MODEL_ALIASES = {
|
|
4727
|
+
"opus-5": "claude-opus-5", // JOHNNESS_PATCH_DEFAULTS_61
|
|
4728
|
+
"sonnet-5": "claude-sonnet-5",
|
|
4729
|
+
"fable-5.1": "claude-fable-5-1",
|
|
4727
4730
|
"opus-4.6": "claude-opus-4-6",
|
|
4728
4731
|
"opus-4.5": "claude-opus-4-5",
|
|
4729
4732
|
"sonnet-4.6": "claude-sonnet-4-6",
|
|
@@ -4939,9 +4942,18 @@ let defaultWarnState = { warned: false };
|
|
|
4939
4942
|
const DEFAULT_MODEL_ALIASES = {
|
|
4940
4943
|
muse: "meta/muse-spark-1.3", // JOHNNESS_PATCH_MUSE_SPARK
|
|
4941
4944
|
"muse-spark": "meta/muse-spark-1.3",
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
+
// JOHNNESS_PATCH_DEFAULTS_61: current model aliases ship with the harness; user config
|
|
4946
|
+
// aliases (agents.defaults.models[*].alias) still take precedence.
|
|
4947
|
+
opus: "anthropic/claude-opus-5",
|
|
4948
|
+
sonnet: "anthropic/claude-sonnet-5",
|
|
4949
|
+
opus46: "anthropic/claude-opus-4-6",
|
|
4950
|
+
sonnet46: "anthropic/claude-sonnet-4-6",
|
|
4951
|
+
fable: "anthropic/claude-fable-5-1",
|
|
4952
|
+
astra: "openai-codex/gpt-6-astra",
|
|
4953
|
+
sol: "openai-codex/gpt-5.6-sol",
|
|
4954
|
+
luna: "openai-codex/gpt-5.6-luna",
|
|
4955
|
+
terra: "openai-codex/gpt-5.6-terra",
|
|
4956
|
+
gpt: "openai-codex/gpt-5.5",
|
|
4945
4957
|
"gpt-mini": "openai/gpt-5-mini",
|
|
4946
4958
|
gemini: "google/gemini-3.1-pro-preview",
|
|
4947
4959
|
"gemini-flash": "google/gemini-3-flash-preview",
|
|
@@ -6100,6 +6112,17 @@ function applyLegacyAudioTranscriptionModel(params) {
|
|
|
6100
6112
|
params.changes.push(params.alreadySetMessage);
|
|
6101
6113
|
}
|
|
6102
6114
|
const LEGACY_CONFIG_MIGRATIONS_PART_2 = [
|
|
6115
|
+
{
|
|
6116
|
+
id: "agent.image-generation-model-v1",
|
|
6117
|
+
describe: "Migrate agents.defaults.imageGenerationModel string to primary/fallbacks",
|
|
6118
|
+
apply: (raw, changes) => {
|
|
6119
|
+
const defaults = getRecord(getRecord(raw.agents)?.defaults);
|
|
6120
|
+
if (!defaults || typeof defaults.imageGenerationModel !== "string") return;
|
|
6121
|
+
const primary = defaults.imageGenerationModel.trim();
|
|
6122
|
+
defaults.imageGenerationModel = primary ? { primary, fallbacks: [] } : void 0;
|
|
6123
|
+
changes.push("Migrated agents.defaults.imageGenerationModel string to primary/fallbacks");
|
|
6124
|
+
}
|
|
6125
|
+
}, // JOHNNESS_PATCH_GPT_IMAGE_62
|
|
6103
6126
|
{
|
|
6104
6127
|
id: "agent.model-config-v2",
|
|
6105
6128
|
describe: "Migrate legacy agent.model/allowedModels/modelAliases/modelFallbacks/imageModelFallbacks to agent.models + model lists",
|
|
@@ -7371,7 +7394,9 @@ function isBundledChannelEnabledByChannelConfig(cfg, pluginId) {
|
|
|
7371
7394
|
if (!channelId) return false;
|
|
7372
7395
|
const entry = cfg.channels?.[channelId];
|
|
7373
7396
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
7374
|
-
|
|
7397
|
+
// JOHNNESS_PATCH_DEFAULTS_61: a configured channel block implies the bundled channel
|
|
7398
|
+
// plugin. Only an explicit enabled:false opts out; no plugins.allow needed.
|
|
7399
|
+
return entry.enabled !== false;
|
|
7375
7400
|
}
|
|
7376
7401
|
function resolveEffectiveEnableState(params) {
|
|
7377
7402
|
const base = resolveEnableState(params.id, params.origin, params.config);
|
|
@@ -8055,6 +8080,18 @@ function safeStatMtimeMs(filePath) {
|
|
|
8055
8080
|
return null;
|
|
8056
8081
|
}
|
|
8057
8082
|
}
|
|
8083
|
+
// JOHNNESS_PATCH_DEFAULTS_61: loose semver compare for bundled-vs-installed plugin dedupe.
|
|
8084
|
+
function compareJohnnessPluginVersions(a, b) {
|
|
8085
|
+
const parse = (value) => String(value ?? "").trim().replace(/^v/i, "").split(/[-+]/)[0].split(".").map((part) => Number.parseInt(part, 10)).map((part) => Number.isFinite(part) ? part : 0);
|
|
8086
|
+
const left = parse(a);
|
|
8087
|
+
const right = parse(b);
|
|
8088
|
+
const len = Math.max(left.length, right.length, 1);
|
|
8089
|
+
for (let i = 0; i < len; i += 1) {
|
|
8090
|
+
const diff = (left[i] ?? 0) - (right[i] ?? 0);
|
|
8091
|
+
if (diff !== 0) return diff > 0 ? 1 : -1;
|
|
8092
|
+
}
|
|
8093
|
+
return 0;
|
|
8094
|
+
}
|
|
8058
8095
|
function normalizeManifestLabel(raw) {
|
|
8059
8096
|
const trimmed = raw?.trim();
|
|
8060
8097
|
return trimmed ? trimmed : void 0;
|
|
@@ -8151,6 +8188,39 @@ function loadPluginManifestRegistry(params) {
|
|
|
8151
8188
|
}
|
|
8152
8189
|
continue;
|
|
8153
8190
|
}
|
|
8191
|
+
// JOHNNESS_PATCH_DEFAULTS_61: the same plugin id bundled with the harness and installed
|
|
8192
|
+
// under the state dir is the normal shape (mr-memory). The installed copy stays
|
|
8193
|
+
// authoritative (family 59) with no warning; when the bundled copy is newer by
|
|
8194
|
+
// package version, one info line suggests updating. Two non-bundled copies
|
|
8195
|
+
// still warn as before.
|
|
8196
|
+
const existingBundled = existing.candidate.origin === "bundled";
|
|
8197
|
+
const candidateBundled = candidate.origin === "bundled";
|
|
8198
|
+
if (existingBundled !== candidateBundled) {
|
|
8199
|
+
const existingRecord = records[existing.recordIndex];
|
|
8200
|
+
const candidateVersion = normalizeManifestLabel(manifest.version) ?? candidate.packageVersion;
|
|
8201
|
+
const bundledVersion = existingBundled ? existingRecord?.version : candidateVersion;
|
|
8202
|
+
const installedVersion = existingBundled ? candidateVersion : existingRecord?.version;
|
|
8203
|
+
if (existingBundled) {
|
|
8204
|
+
records[existing.recordIndex] = buildRecord({
|
|
8205
|
+
manifest,
|
|
8206
|
+
candidate,
|
|
8207
|
+
manifestPath: manifestRes.manifestPath,
|
|
8208
|
+
schemaCacheKey,
|
|
8209
|
+
configSchema
|
|
8210
|
+
});
|
|
8211
|
+
seenIds.set(manifest.id, {
|
|
8212
|
+
candidate,
|
|
8213
|
+
recordIndex: existing.recordIndex
|
|
8214
|
+
});
|
|
8215
|
+
}
|
|
8216
|
+
if (compareJohnnessPluginVersions(bundledVersion, installedVersion) > 0) diagnostics.push({
|
|
8217
|
+
level: "info",
|
|
8218
|
+
pluginId: manifest.id,
|
|
8219
|
+
source: candidate.source,
|
|
8220
|
+
message: `installed copy ${installedVersion ?? "?"} is older than the bundled ${bundledVersion ?? "?"}; run "johnness plugins update ${manifest.id}" to upgrade`
|
|
8221
|
+
});
|
|
8222
|
+
continue;
|
|
8223
|
+
}
|
|
8154
8224
|
diagnostics.push({
|
|
8155
8225
|
level: "warn",
|
|
8156
8226
|
pluginId: manifest.id,
|
|
@@ -9635,6 +9705,7 @@ function isValidNonNegativeByteSizeString(value) {
|
|
|
9635
9705
|
const AgentDefaultsSchema = z.object({
|
|
9636
9706
|
model: AgentModelSchema.optional(),
|
|
9637
9707
|
imageModel: AgentModelSchema.optional(),
|
|
9708
|
+
imageGenerationModel: AgentModelSchema.optional(), // JOHNNESS_PATCH_GPT_IMAGE_62
|
|
9638
9709
|
pdfModel: AgentModelSchema.optional(),
|
|
9639
9710
|
pdfMaxBytesMb: z.number().positive().optional(),
|
|
9640
9711
|
pdfMaxPages: z.number().int().positive().optional(),
|
|
@@ -12481,6 +12552,7 @@ function validateConfigObjectWithPluginsBase(raw, opts) {
|
|
|
12481
12552
|
workspaceDir: resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)) ?? void 0
|
|
12482
12553
|
});
|
|
12483
12554
|
for (const diag of registry.diagnostics) {
|
|
12555
|
+
if (diag.level === "info") continue; // JOHNNESS_PATCH_DEFAULTS_61
|
|
12484
12556
|
let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
|
|
12485
12557
|
if (!diag.pluginId && diag.message.includes("plugin path not found")) path = "plugins.load.paths";
|
|
12486
12558
|
const message = `${diag.pluginId ? `plugin ${diag.pluginId}` : "plugin"}: ${diag.message}`;
|