sneakoscope 2.0.5 → 2.0.7
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 -4
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +37 -8
- package/dist/cli/install-helpers.js +23 -0
- package/dist/commands/codex-app.js +25 -3
- package/dist/commands/doctor.js +19 -4
- package/dist/commands/mad-sks.js +2 -2
- package/dist/core/agents/agent-orchestrator.js +160 -6
- package/dist/core/agents/agent-patch-schema.js +16 -2
- package/dist/core/agents/agent-proof-evidence.js +27 -2
- package/dist/core/agents/agent-worker-pipeline.js +9 -1
- package/dist/core/agents/native-cli-session-swarm.js +25 -4
- package/dist/core/agents/native-cli-worker.js +28 -1
- package/dist/core/agents/native-worker-backend-router.js +19 -1
- package/dist/core/codex-app.js +124 -2
- package/dist/core/codex-control/python-codex-sdk-adapter.js +28 -4
- package/dist/core/commands/naruto-command.js +48 -14
- package/dist/core/feature-registry.js +2 -0
- package/dist/core/fsx.js +1 -1
- package/dist/core/git/git-integration-worktree.js +15 -0
- package/dist/core/git/git-repo-detection.js +72 -0
- package/dist/core/git/git-worktree-cache-policy.js +36 -0
- package/dist/core/git/git-worktree-capability.js +54 -0
- package/dist/core/git/git-worktree-cleanup.js +51 -0
- package/dist/core/git/git-worktree-conflict-resolver.js +13 -0
- package/dist/core/git/git-worktree-diff.js +50 -0
- package/dist/core/git/git-worktree-manager.js +86 -0
- package/dist/core/git/git-worktree-merge-queue.js +55 -0
- package/dist/core/git/git-worktree-patch-envelope.js +35 -0
- package/dist/core/git/git-worktree-pool.js +23 -0
- package/dist/core/git/git-worktree-root.js +52 -0
- package/dist/core/git/git-worktree-runner.js +40 -0
- package/dist/core/hooks-runtime.js +2 -233
- package/dist/core/init.js +8 -8
- package/dist/core/naruto/naruto-active-pool.js +55 -4
- package/dist/core/naruto/naruto-gpt-final-pack.js +2 -0
- package/dist/core/naruto/naruto-work-graph.js +16 -1
- package/dist/core/pipeline-internals/runtime-core.js +1 -1
- package/dist/core/ppt.js +31 -8
- package/dist/core/product-design-app-server.js +410 -0
- package/dist/core/product-design-plugin.js +139 -0
- package/dist/core/routes.js +8 -8
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-naruto-dashboard.js +10 -1
- package/dist/core/zellij/zellij-worker-pane-manager.js +6 -4
- package/dist/scripts/git-worktree-cache-performance-check.js +25 -0
- package/dist/scripts/git-worktree-capability-check.js +27 -0
- package/dist/scripts/git-worktree-cleanup-check.js +27 -0
- package/dist/scripts/git-worktree-diff-export-check.js +43 -0
- package/dist/scripts/git-worktree-manager-check.js +37 -0
- package/dist/scripts/git-worktree-merge-queue-check.js +30 -0
- package/dist/scripts/git-worktree-pool-performance-check.js +20 -0
- package/dist/scripts/lib/git-worktree-fixture.js +33 -0
- package/dist/scripts/naruto-active-pool-check.js +13 -1
- package/dist/scripts/naruto-readonly-routing-check.js +116 -0
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +16 -5
- package/dist/scripts/naruto-worktree-coding-check.js +44 -0
- package/dist/scripts/naruto-worktree-gpt-final-check.js +45 -0
- package/dist/scripts/naruto-worktree-zellij-ui-check.js +28 -0
- package/dist/scripts/product-design-auto-install-check.js +119 -0
- package/dist/scripts/product-design-plugin-routing-check.js +101 -0
- package/dist/scripts/release-parallel-check.js +16 -2
- package/dist/scripts/release-provenance-check.js +21 -0
- package/package.json +17 -3
- package/schemas/git/git-worktree-capability.schema.json +19 -0
- package/schemas/git/git-worktree-manifest.schema.json +36 -0
package/README.md
CHANGED
|
@@ -16,10 +16,18 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
16
16
|
|
|
17
17
|
## Current Release
|
|
18
18
|
|
|
19
|
-
SKS **2.0.
|
|
19
|
+
SKS **2.0.7** adds Git worktree parallel coding foundations for Naruto/MAD-SKS-style high-throughput work. Write-capable Git missions can now declare `git-worktree` mode, allocate worker worktrees outside the main checkout by default, export full-index diffs into patch envelopes, apply them through an integration worktree queue, and retain dirty worktrees instead of deleting evidence. Non-Git projects degrade to patch-envelope-only without calling `git worktree`.
|
|
20
20
|
|
|
21
21
|
What changed:
|
|
22
22
|
|
|
23
|
+
- Git capability checks detect repo roots, Git dirs, worktree support, and safe cache roots while blocking in-repo worktree roots unless `SKS_ALLOW_IN_REPO_WORKTREES=1` is explicit.
|
|
24
|
+
- Worker worktree allocation creates isolated branches/paths under `$SKS_WORKTREE_ROOT`, `$XDG_CACHE_HOME/sks/worktrees`, or `~/.cache/sks/worktrees`; main checkouts stay untouched until integration.
|
|
25
|
+
- Worktree diff export records status, changed files, full-index binary diffs, and `git-worktree-diff` patch envelopes for parent-owned integration.
|
|
26
|
+
- Integration worktrees apply worker diffs with `git apply --3way`, while cleanup removes only clean worktrees and retains dirty ones with a lock artifact.
|
|
27
|
+
- Naruto work graphs, active-pool artifacts, Zellij dashboard titles, native worker intake, and GPT Final packs now carry worktree policy and WT/branch context.
|
|
28
|
+
- Product Design plugin readiness now checks both local and remote Codex App catalogs, auto-installs the remote plugin when needed, and records the installed/enabled skill surface.
|
|
29
|
+
- UI/design/PPT runtime routes prefer Product Design for research, ideation, audit, design QA, prototype, URL-to-code, image-to-code, share, and user-context steps.
|
|
30
|
+
- Naruto read-only runs force write mode off, propagate no-patch reasons through worker proof, and skip changed-file lease checks when no write-capable patch envelope exists.
|
|
23
31
|
- `codex-sdk` is the default native agent backend for Team, QA, Research, Naruto, MAD-SKS, and direct agent runs, with every runtime task entering through `runCodexTask`.
|
|
24
32
|
- Codex App UI snapshot, preservation, clobber guard, and doctor repair checks protect host-owned Fast UI/profile settings around `sks --mad`.
|
|
25
33
|
- Provider context resolves `openai`, `codex-lb`, and `codex-app` with badge/fallback surfaces while avoiding private Codex App UI mutation.
|
|
@@ -78,7 +86,7 @@ Broader release checks still live behind `npm run release:check`. Detailed relea
|
|
|
78
86
|
sks xai docs
|
|
79
87
|
```
|
|
80
88
|
|
|
81
|
-
- **
|
|
89
|
+
- **CLI-only SKS update notices.** Codex App hooks no longer stop normal work to ask for an SKS update. CLI launch surfaces such as `sks --mad` print a non-blocking latest-version notice, `sks update-check` / `sks update check` show the explicit status, and `sks doctor --fix` runs the guarded global SKS update path before repair.
|
|
82
90
|
|
|
83
91
|
## Retention And Cleanup
|
|
84
92
|
|
|
@@ -359,7 +367,7 @@ sks --mad --allow-package-install --allow-service-control --allow-network --yes
|
|
|
359
367
|
|
|
360
368
|
This syncs existing codex-lb provider auth, creates/uses the `sks-mad-high` xhigh maintenance profile, opens the MAD-SKS permission gate for that Zellij run, starts a same-mission read-only native agent swarm, and launches a Codex CLI layout whose right-side lanes read that MAD ledger. Bare `sks --mad` grants target-project file and shell scope only; add explicit `--allow-*` flags for packages, services, network, Computer Use, browser use, generated assets, file permissions, DB writes, or other high-risk scopes. MAD-SKS is not a DB-only unlock: it is explicit user authorization to widen approved target-project scopes. Catastrophic database wipe/all-row/project-management safeguards remain active, and the pipeline contract still forbids unrequested fallback implementation code.
|
|
361
369
|
|
|
362
|
-
Before launching, SKS checks npm for a newer `sneakoscope
|
|
370
|
+
Before launching, SKS checks npm for a newer `sneakoscope` and prints a non-blocking update notice when one is available; use `sks update now` or `sks doctor --fix` when you want SKS to update itself. Use `--yes` to approve missing dependency installs automatically. Tune MAD swarm startup with `--mad-agents <n>`, `--mad-swarm-work-items <n>`, and `--mad-swarm-backend <backend>`; `--no-mad-swarm` keeps only the cockpit UI if you need a temporary fallback.
|
|
363
371
|
|
|
364
372
|
### Team Missions
|
|
365
373
|
|
|
@@ -659,7 +667,7 @@ npm ls -g sneakoscope --depth=0
|
|
|
659
667
|
sks doctor --fix
|
|
660
668
|
```
|
|
661
669
|
|
|
662
|
-
|
|
670
|
+
CLI update checks compare npm latest against the effective installed version from source metadata, PATH `sks --version`, and global npm package metadata. Codex App hooks do not force update choices during ordinary work. `sks update now` installs through npm global mode instead of mutating the current project's dependencies, and `sks doctor --fix` runs that guarded global update path before setup/config repair. If a global update succeeded but an old shim remains earlier on PATH, `sks doctor --fix` can remove duplicate global installs and refresh the managed setup.
|
|
663
671
|
|
|
664
672
|
### Zellij is missing
|
|
665
673
|
|
|
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
|
|
|
4
4
|
fn main() {
|
|
5
5
|
let mut args = std::env::args().skip(1);
|
|
6
6
|
match args.next().as_deref() {
|
|
7
|
-
Some("--version") => println!("sks-rs 2.0.
|
|
7
|
+
Some("--version") => println!("sks-rs 2.0.7"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build-stamp.v1",
|
|
3
3
|
"package_name": "sneakoscope",
|
|
4
|
-
"package_version": "2.0.
|
|
5
|
-
"source_digest": "
|
|
6
|
-
"source_file_count":
|
|
7
|
-
"built_at_source_time":
|
|
4
|
+
"package_version": "2.0.7",
|
|
5
|
+
"source_digest": "fd9b0bc3d9a5a09bcd2b90988719b11e844448de39f28cf27e98c1b4cae82a0f",
|
|
6
|
+
"source_file_count": 1979,
|
|
7
|
+
"built_at_source_time": 1780686416915
|
|
8
8
|
}
|
package/dist/bin/sks.js
CHANGED
package/dist/build-manifest.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build.v2",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"package_version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
4
|
+
"package_version": "2.0.7",
|
|
5
5
|
"typescript": true,
|
|
6
6
|
"mjs_runtime_files": 0,
|
|
7
|
-
"compiled_file_count":
|
|
8
|
-
"compiled_js_count":
|
|
7
|
+
"compiled_file_count": 1043,
|
|
8
|
+
"compiled_js_count": 1043,
|
|
9
9
|
"compiled_dts_count": 0,
|
|
10
|
-
"source_digest": "
|
|
11
|
-
"source_file_count":
|
|
12
|
-
"source_files_hash": "
|
|
13
|
-
"source_list_hash": "
|
|
10
|
+
"source_digest": "fd9b0bc3d9a5a09bcd2b90988719b11e844448de39f28cf27e98c1b4cae82a0f",
|
|
11
|
+
"source_file_count": 1979,
|
|
12
|
+
"source_files_hash": "319ce7cd86fb58c825b14eb717a1d7b9c85be197206852aee9646fbfd5d356c6",
|
|
13
|
+
"source_list_hash": "319ce7cd86fb58c825b14eb717a1d7b9c85be197206852aee9646fbfd5d356c6",
|
|
14
14
|
"src_mjs_runtime_files": 0,
|
|
15
15
|
"dist_stamp_schema": "sks.dist-build-stamp.v1",
|
|
16
16
|
"files": [
|
|
@@ -342,6 +342,19 @@
|
|
|
342
342
|
"core/git-hygiene/shared-memory-security.js",
|
|
343
343
|
"core/git-hygiene/validators.js",
|
|
344
344
|
"core/git-simple.js",
|
|
345
|
+
"core/git/git-integration-worktree.js",
|
|
346
|
+
"core/git/git-repo-detection.js",
|
|
347
|
+
"core/git/git-worktree-cache-policy.js",
|
|
348
|
+
"core/git/git-worktree-capability.js",
|
|
349
|
+
"core/git/git-worktree-cleanup.js",
|
|
350
|
+
"core/git/git-worktree-conflict-resolver.js",
|
|
351
|
+
"core/git/git-worktree-diff.js",
|
|
352
|
+
"core/git/git-worktree-manager.js",
|
|
353
|
+
"core/git/git-worktree-merge-queue.js",
|
|
354
|
+
"core/git/git-worktree-patch-envelope.js",
|
|
355
|
+
"core/git/git-worktree-pool.js",
|
|
356
|
+
"core/git/git-worktree-root.js",
|
|
357
|
+
"core/git/git-worktree-runner.js",
|
|
345
358
|
"core/goal-workflow.js",
|
|
346
359
|
"core/gx-renderer.js",
|
|
347
360
|
"core/harness-conflicts.js",
|
|
@@ -473,6 +486,8 @@
|
|
|
473
486
|
"core/ppt-review/slide-issue-extraction.js",
|
|
474
487
|
"core/ppt.js",
|
|
475
488
|
"core/preflight/parallel-preflight-engine.js",
|
|
489
|
+
"core/product-design-app-server.js",
|
|
490
|
+
"core/product-design-plugin.js",
|
|
476
491
|
"core/prompt-context-builder.js",
|
|
477
492
|
"core/prompt/prompt-placeholder-guard.js",
|
|
478
493
|
"core/proof-field.js",
|
|
@@ -812,6 +827,13 @@
|
|
|
812
827
|
"scripts/flagship-proof-graph-v3-check.js",
|
|
813
828
|
"scripts/flagship-proof-graph-v4-check.js",
|
|
814
829
|
"scripts/git-precommit-fixture-check.js",
|
|
830
|
+
"scripts/git-worktree-cache-performance-check.js",
|
|
831
|
+
"scripts/git-worktree-capability-check.js",
|
|
832
|
+
"scripts/git-worktree-cleanup-check.js",
|
|
833
|
+
"scripts/git-worktree-diff-export-check.js",
|
|
834
|
+
"scripts/git-worktree-manager-check.js",
|
|
835
|
+
"scripts/git-worktree-merge-queue-check.js",
|
|
836
|
+
"scripts/git-worktree-pool-performance-check.js",
|
|
815
837
|
"scripts/goal-mode-official-default-check.js",
|
|
816
838
|
"scripts/gpt-final-arbiter-check.js",
|
|
817
839
|
"scripts/gpt-final-arbiter-performance-check.js",
|
|
@@ -839,6 +861,7 @@
|
|
|
839
861
|
"scripts/legacy-upgrade-matrix-check.js",
|
|
840
862
|
"scripts/lib/codex-sdk-gate-lib.js",
|
|
841
863
|
"scripts/lib/ensure-dist-fresh.js",
|
|
864
|
+
"scripts/lib/git-worktree-fixture.js",
|
|
842
865
|
"scripts/lib/mad-sks-actual-executor-check-lib.js",
|
|
843
866
|
"scripts/lib/native-cli-session-swarm-check-lib.js",
|
|
844
867
|
"scripts/lib/real-codex-parallel-gate.js",
|
|
@@ -886,11 +909,15 @@
|
|
|
886
909
|
"scripts/naruto-concurrency-governor-check.js",
|
|
887
910
|
"scripts/naruto-gpt-final-pack-check.js",
|
|
888
911
|
"scripts/naruto-parallel-patch-apply-check.js",
|
|
912
|
+
"scripts/naruto-readonly-routing-check.js",
|
|
889
913
|
"scripts/naruto-real-local-gpt-final-smoke.js",
|
|
890
914
|
"scripts/naruto-role-distribution-check.js",
|
|
891
915
|
"scripts/naruto-shadow-clone-swarm-check.js",
|
|
892
916
|
"scripts/naruto-verification-pool-check.js",
|
|
893
917
|
"scripts/naruto-work-graph-check.js",
|
|
918
|
+
"scripts/naruto-worktree-coding-check.js",
|
|
919
|
+
"scripts/naruto-worktree-gpt-final-check.js",
|
|
920
|
+
"scripts/naruto-worktree-zellij-ui-check.js",
|
|
894
921
|
"scripts/naruto-zellij-massive-ui-check.js",
|
|
895
922
|
"scripts/non-recursive-pipeline-check.js",
|
|
896
923
|
"scripts/npm-publish-performance-check.js",
|
|
@@ -916,6 +943,8 @@
|
|
|
916
943
|
"scripts/prepublish-fast-check.js",
|
|
917
944
|
"scripts/prepublish-release-check-or-fast.js",
|
|
918
945
|
"scripts/priority-full-closure-check.js",
|
|
946
|
+
"scripts/product-design-auto-install-check.js",
|
|
947
|
+
"scripts/product-design-plugin-routing-check.js",
|
|
919
948
|
"scripts/prompt-placeholder-guard-check.js",
|
|
920
949
|
"scripts/provider-badge-context-check.js",
|
|
921
950
|
"scripts/provider-context-config-toml-check.js",
|
|
@@ -13,6 +13,7 @@ import { context7ConfigToml, DOLLAR_SKILL_NAMES, GETDESIGN_REFERENCE, hasContext
|
|
|
13
13
|
import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
|
|
14
14
|
import { reconcileCodexAppUpgradeProcesses } from '../core/codex-app.js';
|
|
15
15
|
import { recordCodexLbHealthEvent } from '../core/codex-lb-circuit.js';
|
|
16
|
+
import { runSksUpdateCheck, runSksUpdateNow } from '../core/update-check.js';
|
|
16
17
|
import { loadCodexLbEnv, writeCodexLbKeychain, codexLbMetadataPath } from '../core/codex-lb/codex-lb-env.js';
|
|
17
18
|
import { buildCodexLbSetupPlan, codexLbPersistenceSummary, installCodexLbShellProfileSnippet, selectedCodexLbPersistenceModes } from '../core/codex-lb/codex-lb-setup.js';
|
|
18
19
|
const DEFAULT_CODEX_APP_PLUGINS = [
|
|
@@ -2231,6 +2232,28 @@ export async function maybePromptCodexUpdateForLaunch(args = [], opts = {}) {
|
|
|
2231
2232
|
return { status: 'skipped_by_user', latest: latest.version || null, current, command, bin: codex.bin || null };
|
|
2232
2233
|
return installCodexLatest(command, latest.version, current);
|
|
2233
2234
|
}
|
|
2235
|
+
export async function maybePromptSksUpdateForLaunch(args = [], opts = {}) {
|
|
2236
|
+
if (hasFlag(args, '--json') || hasFlag(args, '--skip-sks-update') || process.env.SKS_SKIP_SKS_UPDATE === '1')
|
|
2237
|
+
return { status: 'skipped' };
|
|
2238
|
+
const label = opts.label || 'SKS launch';
|
|
2239
|
+
const check = await runSksUpdateCheck({ timeoutMs: 5000 }).catch((err) => ({
|
|
2240
|
+
ok: false,
|
|
2241
|
+
update_available: false,
|
|
2242
|
+
latest: null,
|
|
2243
|
+
current: PACKAGE_VERSION,
|
|
2244
|
+
command: null,
|
|
2245
|
+
error: err?.message || String(err)
|
|
2246
|
+
}));
|
|
2247
|
+
if (!check.update_available) {
|
|
2248
|
+
return { status: check.error ? 'unavailable' : 'current', latest: check.latest || null, current: check.current || PACKAGE_VERSION, error: check.error || null };
|
|
2249
|
+
}
|
|
2250
|
+
const command = check.command || `sks update now --version ${check.latest}`;
|
|
2251
|
+
if (shouldAutoApproveInstall(args)) {
|
|
2252
|
+
return runSksUpdateNow({ version: check.latest, timeoutMs: 10 * 60 * 1000, maxOutputBytes: 128 * 1024 });
|
|
2253
|
+
}
|
|
2254
|
+
console.log(`SKS update available before ${label}: ${check.current} -> ${check.latest}. Run when ready: ${command}`);
|
|
2255
|
+
return { status: 'available', latest: check.latest || null, current: check.current || PACKAGE_VERSION, command };
|
|
2256
|
+
}
|
|
2234
2257
|
export function shouldAutoApproveInstall(args = [], env = process.env) {
|
|
2235
2258
|
if (hasFlag(args, '--from-postinstall') && env.SKS_POSTINSTALL_AUTO_INSTALL_CLI_TOOLS !== '1')
|
|
2236
2259
|
return false;
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { flag } from '../cli/args.js';
|
|
2
2
|
import { printJson } from '../cli/output.js';
|
|
3
|
-
import { codexAccessTokenStatus, codexAppIntegrationStatus, codexChromeExtensionStatus, formatCodexAppStatus } from '../core/codex-app.js';
|
|
3
|
+
import { codexAccessTokenStatus, codexAppIntegrationStatus, codexChromeExtensionStatus, codexProductDesignPluginStatus, formatCodexAppStatus, formatCodexProductDesignPluginStatus } from '../core/codex-app.js';
|
|
4
4
|
import { codexAppRemoteControlCommand } from '../cli/codex-app-command.js';
|
|
5
5
|
export async function run(_command, args = []) {
|
|
6
6
|
const action = args[0] || 'check';
|
|
7
7
|
if (action === 'remote-control' || action === 'remote')
|
|
8
8
|
return codexAppRemoteControlCommand(args.slice(1));
|
|
9
|
+
if (action === 'product-design' || action === 'design-product' || action === 'ensure-product-design') {
|
|
10
|
+
const checkOnly = flag(args, '--check-only') || flag(args, '--no-install');
|
|
11
|
+
const status = await codexProductDesignPluginStatus({
|
|
12
|
+
autoInstallProductDesign: !checkOnly && (action === 'product-design'
|
|
13
|
+
|| action === 'design-product'
|
|
14
|
+
|| action === 'ensure-product-design'
|
|
15
|
+
|| flag(args, '--install')
|
|
16
|
+
|| flag(args, '--auto-install'))
|
|
17
|
+
});
|
|
18
|
+
if (flag(args, '--json')) {
|
|
19
|
+
printJson(status);
|
|
20
|
+
if (!status.ok)
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.log(formatCodexProductDesignPluginStatus(status));
|
|
25
|
+
if (!status.ok)
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
9
29
|
if (action === 'chrome-extension' || action === 'chrome') {
|
|
10
30
|
const status = await codexChromeExtensionStatus();
|
|
11
31
|
if (flag(args, '--json')) {
|
|
@@ -32,7 +52,9 @@ export async function run(_command, args = []) {
|
|
|
32
52
|
return;
|
|
33
53
|
}
|
|
34
54
|
if (action === 'check' || action === 'status') {
|
|
35
|
-
const status = await codexAppIntegrationStatus(
|
|
55
|
+
const status = await codexAppIntegrationStatus({
|
|
56
|
+
autoInstallProductDesign: flag(args, '--install-product-design') || flag(args, '--auto-install-product-design')
|
|
57
|
+
});
|
|
36
58
|
if (flag(args, '--json')) {
|
|
37
59
|
printJson(status);
|
|
38
60
|
if (!status.ok)
|
|
@@ -44,7 +66,7 @@ export async function run(_command, args = []) {
|
|
|
44
66
|
process.exitCode = 1;
|
|
45
67
|
return;
|
|
46
68
|
}
|
|
47
|
-
console.error('Usage: sks codex-app check|status|chrome-extension|pat status|remote-control [--json]');
|
|
69
|
+
console.error('Usage: sks codex-app check|status|product-design [--check-only]|ensure-product-design|chrome-extension|pat status|remote-control [--json]');
|
|
48
70
|
process.exitCode = 1;
|
|
49
71
|
}
|
|
50
72
|
//# sourceMappingURL=codex-app.js.map
|
package/dist/commands/doctor.js
CHANGED
|
@@ -18,10 +18,23 @@ import { appendMigrationEvents, hashConfigText } from '../core/migration/migrati
|
|
|
18
18
|
import { repairCodexAppFastUi } from '../core/codex-app/codex-app-fast-ui-repair.js';
|
|
19
19
|
import { resolveProviderContext } from '../core/provider/provider-context.js';
|
|
20
20
|
import { readLocalModelConfig } from '../core/agents/ollama-worker-config.js';
|
|
21
|
+
import { runSksUpdateNow } from '../core/update-check.js';
|
|
21
22
|
export async function run(_command, args = []) {
|
|
23
|
+
const doctorFix = flag(args, '--fix');
|
|
22
24
|
let setupRepair = null;
|
|
25
|
+
const sksUpdate = doctorFix
|
|
26
|
+
? await runSksUpdateNow({
|
|
27
|
+
timeoutMs: 10 * 60 * 1000,
|
|
28
|
+
maxOutputBytes: 128 * 1024
|
|
29
|
+
}).catch((err) => ({
|
|
30
|
+
schema: 'sks.update-now.v1',
|
|
31
|
+
ok: false,
|
|
32
|
+
status: 'failed',
|
|
33
|
+
error: err?.message || String(err)
|
|
34
|
+
}))
|
|
35
|
+
: null;
|
|
23
36
|
let migrationPreFix = null;
|
|
24
|
-
if (
|
|
37
|
+
if (doctorFix) {
|
|
25
38
|
// Snapshot config content before ANY mutation so the migration journal can
|
|
26
39
|
// record real before/after hashes for the whole --fix transaction.
|
|
27
40
|
migrationPreFix = await captureCodexConfigSnapshot();
|
|
@@ -97,7 +110,6 @@ export async function run(_command, args = []) {
|
|
|
97
110
|
model_provider: null
|
|
98
111
|
}
|
|
99
112
|
}));
|
|
100
|
-
const doctorFix = flag(args, '--fix');
|
|
101
113
|
const explicitCodexAppUiRepair = flag(args, '--repair-codex-app-ui') || flag(args, '--yes');
|
|
102
114
|
const codexAppUiPlan = await repairCodexAppFastUi(root, {
|
|
103
115
|
apply: false,
|
|
@@ -165,7 +177,7 @@ export async function run(_command, args = []) {
|
|
|
165
177
|
const zellijReadiness = buildZellijReadiness(root, zellij, ready);
|
|
166
178
|
const result = {
|
|
167
179
|
schema: 'sks.doctor-status.v1',
|
|
168
|
-
ok: ready.ready,
|
|
180
|
+
ok: ready.ready && (!sksUpdate || sksUpdate.ok !== false),
|
|
169
181
|
root,
|
|
170
182
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
171
183
|
codex,
|
|
@@ -189,7 +201,7 @@ export async function run(_command, args = []) {
|
|
|
189
201
|
ready,
|
|
190
202
|
sneakoscope: { ok: await exists(`${root}/.sneakoscope`) },
|
|
191
203
|
package: { bytes: pkgBytes, human: formatBytes(pkgBytes) },
|
|
192
|
-
repair: { setup: setupRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup }
|
|
204
|
+
repair: { sks_update: sksUpdate, setup: setupRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup }
|
|
193
205
|
};
|
|
194
206
|
if (flag(args, '--json')) {
|
|
195
207
|
printJson(result);
|
|
@@ -265,6 +277,9 @@ export async function run(_command, args = []) {
|
|
|
265
277
|
if (migrationJournal?.journal_path) {
|
|
266
278
|
console.log(`Migration journal: ${migrationJournal.journal_path} (${migrationJournal.event_count} events, ${migrationJournal.mutations_without_rollback} without rollback)`);
|
|
267
279
|
}
|
|
280
|
+
if (sksUpdate) {
|
|
281
|
+
console.log(`SKS update: ${sksUpdate.status}${sksUpdate.latest ? ` latest ${sksUpdate.latest}` : ''}${sksUpdate.error ? ` (${sksUpdate.error})` : ''}`);
|
|
282
|
+
}
|
|
268
283
|
if (globalSksInstallCleanup) {
|
|
269
284
|
console.log(`Global SKS installs: kept ${globalSksInstallCleanup.kept?.length ?? 0}, removed ${globalSksInstallCleanup.removed?.filter((entry) => entry.ok).length ?? 0}, source repo exempt ${globalSksInstallCleanup.candidates?.filter((entry) => entry.source_repo_exempt).length ?? 0}`);
|
|
270
285
|
}
|
package/dist/commands/mad-sks.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { madHighCommand } from '../core/commands/mad-sks-command.js';
|
|
2
|
-
import { ensureMadLaunchDependencies, formatMadLaunchDependencyAction, maybePromptCodexUpdateForLaunch, maybePromptCodexLbSetupForLaunch } from '../cli/install-helpers.js';
|
|
2
|
+
import { ensureMadLaunchDependencies, formatMadLaunchDependencyAction, maybePromptCodexUpdateForLaunch, maybePromptCodexLbSetupForLaunch, maybePromptSksUpdateForLaunch } from '../cli/install-helpers.js';
|
|
3
3
|
import { PACKAGE_VERSION } from '../core/fsx.js';
|
|
4
4
|
export async function run(_command, args = []) {
|
|
5
5
|
return madHighCommand(['--mad-sks', ...args], {
|
|
6
|
-
maybePromptSksUpdateForLaunch
|
|
6
|
+
maybePromptSksUpdateForLaunch,
|
|
7
7
|
maybePromptCodexUpdateForLaunch,
|
|
8
8
|
ensureMadLaunchDependencies,
|
|
9
9
|
printDepsInstallAction: (action) => console.error(formatMadLaunchDependencyAction(action)),
|
|
@@ -52,6 +52,10 @@ import { CODEX_AGENT_WORKER_RESULT_SCHEMA_ID, codexAgentWorkerResultSchema } fro
|
|
|
52
52
|
import { resolveLocalCollaborationPolicy, localCollaborationParticipated } from '../local-llm/local-collaboration-policy.js';
|
|
53
53
|
import { runFinalGptReviewStage } from '../pipeline/final-gpt-review-stage.js';
|
|
54
54
|
import { selectFinalGptPatchSource } from '../pipeline/final-gpt-patch-stage.js';
|
|
55
|
+
import { allocateWorkerWorktree } from '../git/git-worktree-manager.js';
|
|
56
|
+
import { exportGitWorktreeDiff } from '../git/git-worktree-diff.js';
|
|
57
|
+
import { buildGitWorktreePatchEnvelope } from '../git/git-worktree-patch-envelope.js';
|
|
58
|
+
import { cleanupGitWorktree } from '../git/git-worktree-cleanup.js';
|
|
55
59
|
export async function runNativeAgentOrchestrator(opts = {}) {
|
|
56
60
|
const root = path.resolve(opts.root || process.cwd());
|
|
57
61
|
const prompt = String(opts.prompt || 'Native agent run');
|
|
@@ -117,6 +121,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
117
121
|
const strategyCompiled = compileStrategy({
|
|
118
122
|
prompt,
|
|
119
123
|
route,
|
|
124
|
+
...(writeCapable ? {} : { writeTargets: [] }),
|
|
120
125
|
agentCount: roster.agent_count,
|
|
121
126
|
visualRequired
|
|
122
127
|
});
|
|
@@ -235,12 +240,13 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
235
240
|
rate_limit_delay_ms: backend === 'codex-sdk' ? 250 : 0,
|
|
236
241
|
resource_pressure_warnings: roster.agent_count > roster.concurrency ? ['agents_exceed_concurrency_batches'] : []
|
|
237
242
|
});
|
|
243
|
+
const effectiveWriteMode = writeCapable ? opts.writeMode || 'off' : 'off';
|
|
238
244
|
const parallelWritePolicy = {
|
|
239
245
|
schema: 'sks.agent-parallel-write-policy.v1',
|
|
240
246
|
generated_at: nowIso(),
|
|
241
247
|
route,
|
|
242
248
|
route_command: routeCommand,
|
|
243
|
-
write_mode:
|
|
249
|
+
write_mode: effectiveWriteMode,
|
|
244
250
|
apply_patches: opts.applyPatches === true,
|
|
245
251
|
dry_run_patches: opts.dryRunPatches === true,
|
|
246
252
|
max_write_agents: Number(opts.maxWriteAgents || 0),
|
|
@@ -251,6 +257,21 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
251
257
|
strategy_gate: strategyRef
|
|
252
258
|
};
|
|
253
259
|
await writeJsonAtomic(path.join(ledgerRoot, 'agent-parallel-write-policy.json'), parallelWritePolicy);
|
|
260
|
+
const gitWorktreePolicy = opts.gitWorktreePolicy || null;
|
|
261
|
+
const gitWorktreeRuntime = {
|
|
262
|
+
schema: 'sks.agent-git-worktree-runtime.v1',
|
|
263
|
+
generated_at: nowIso(),
|
|
264
|
+
ok: true,
|
|
265
|
+
mode: gitWorktreePolicy?.mode || 'patch-envelope-only',
|
|
266
|
+
required: gitWorktreePolicy?.required === true,
|
|
267
|
+
main_repo_root: gitWorktreePolicy?.main_repo_root || root,
|
|
268
|
+
worktree_root: gitWorktreePolicy?.worktree_root || null,
|
|
269
|
+
allocations: [],
|
|
270
|
+
diffs: [],
|
|
271
|
+
cleanup: [],
|
|
272
|
+
blockers: []
|
|
273
|
+
};
|
|
274
|
+
await writeJsonAtomic(path.join(ledgerRoot, 'agent-git-worktree-runtime.json'), gitWorktreeRuntime);
|
|
254
275
|
const nativeCliSwarm = createNativeCliSessionSwarmRecorder(ledgerRoot, {
|
|
255
276
|
missionId,
|
|
256
277
|
requestedAgents: Number(opts.agents || roster.agent_count || targetActiveSlots),
|
|
@@ -278,6 +299,17 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
278
299
|
goalModeRef,
|
|
279
300
|
launchSession: async ({ agent, workItem }) => {
|
|
280
301
|
const slice = workItem.slice || { id: workItem.id, description: workItem.description || prompt };
|
|
302
|
+
const workerWorktree = await prepareWorkerGitWorktree({
|
|
303
|
+
root,
|
|
304
|
+
ledgerRoot,
|
|
305
|
+
missionId,
|
|
306
|
+
agent,
|
|
307
|
+
slice,
|
|
308
|
+
policy: gitWorktreePolicy,
|
|
309
|
+
runtime: gitWorktreeRuntime
|
|
310
|
+
});
|
|
311
|
+
const runtimeAgent = workerWorktree ? { ...agent, worktree: workerWorktree.context } : agent;
|
|
312
|
+
const runtimeSlice = workerWorktree ? { ...slice, worktree: workerWorktree.context } : slice;
|
|
281
313
|
await openAgentSession(ledgerRoot, agent);
|
|
282
314
|
await heartbeatAgentSession(ledgerRoot, agent);
|
|
283
315
|
await appendAgentCodexCockpitHookEvent(dir, {
|
|
@@ -301,10 +333,21 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
301
333
|
generationIndex: agent.generation_index,
|
|
302
334
|
requireGeneration: true
|
|
303
335
|
});
|
|
304
|
-
const backendOpts = { ...opts, missionId, agentRoot: ledgerRoot, cwd: root, route, prompt, fastMode: fastModePolicy.fast_mode, serviceTier: fastModePolicy.service_tier };
|
|
336
|
+
const backendOpts = { ...opts, missionId, agentRoot: ledgerRoot, cwd: workerWorktree?.context.path || root, route, prompt, fastMode: fastModePolicy.fast_mode, serviceTier: fastModePolicy.service_tier, ...(workerWorktree ? { worktree: workerWorktree.context } : {}) };
|
|
305
337
|
const result = opts.nativeCliSwarm === false
|
|
306
|
-
? await runAgentByBackend(backend,
|
|
307
|
-
: await nativeCliSwarm.launchWorker({ agent, slice, opts: backendOpts });
|
|
338
|
+
? await runAgentByBackend(backend, runtimeAgent, runtimeSlice, backendOpts)
|
|
339
|
+
: await nativeCliSwarm.launchWorker({ agent: runtimeAgent, slice: runtimeSlice, opts: backendOpts });
|
|
340
|
+
if (workerWorktree)
|
|
341
|
+
await finalizeWorkerGitWorktree({
|
|
342
|
+
root,
|
|
343
|
+
ledgerRoot,
|
|
344
|
+
missionId,
|
|
345
|
+
agent: runtimeAgent,
|
|
346
|
+
slice: runtimeSlice,
|
|
347
|
+
result,
|
|
348
|
+
workerWorktree,
|
|
349
|
+
runtime: gitWorktreeRuntime
|
|
350
|
+
});
|
|
308
351
|
const terminalClose = await closeAgentTerminalSession(ledgerRoot, agent, {
|
|
309
352
|
exitCode: result.status === 'done' ? 0 : 1,
|
|
310
353
|
status: result.status,
|
|
@@ -442,6 +485,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
442
485
|
...(nativeCliSessionProof.ok ? [] : nativeCliSessionProof.blockers),
|
|
443
486
|
...(noSubagentScalingPolicy.ok ? [] : noSubagentScalingPolicy.blockers),
|
|
444
487
|
...(fastModePropagation.ok ? [] : fastModePropagation.blockers),
|
|
488
|
+
...(gitWorktreeRuntime.required === true && gitWorktreeRuntime.ok === false ? gitWorktreeRuntime.blockers || ['git_worktree_runtime_not_ok'] : []),
|
|
445
489
|
...(localParticipated && gptFinalArbiter?.ok !== true ? gptFinalArbiter?.blockers || ['gpt_final_arbiter_not_ok'] : []),
|
|
446
490
|
...(localParticipated && finalGptPatchStage?.ok === false ? finalGptPatchStage.blockers || ['final_gpt_patch_stage_not_ok'] : []),
|
|
447
491
|
...(patchSwarm.ok ? [] : patchSwarm.blockers),
|
|
@@ -478,6 +522,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
478
522
|
noSubagentScalingPolicy,
|
|
479
523
|
fastModePolicy,
|
|
480
524
|
fastModePropagation,
|
|
525
|
+
gitWorktreeRuntime,
|
|
481
526
|
triwikiContext,
|
|
482
527
|
selectedCoreSkill,
|
|
483
528
|
localCollaborationPolicy,
|
|
@@ -522,6 +567,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
522
567
|
no_subagent_scaling_policy: noSubagentScalingPolicy,
|
|
523
568
|
fast_mode_policy: fastModePolicy,
|
|
524
569
|
fast_mode_propagation: fastModePropagation,
|
|
570
|
+
git_worktree_runtime: gitWorktreeRuntime,
|
|
525
571
|
local_collaboration_policy: localCollaborationPolicy,
|
|
526
572
|
gpt_final_arbiter: gptFinalArbiter,
|
|
527
573
|
final_gpt_patch_stage: finalGptPatchStage,
|
|
@@ -546,6 +592,97 @@ function withFinalGptPatchEnvelopes(results, patchEnvelopes = []) {
|
|
|
546
592
|
next[0] = { ...next[0], patch_envelopes: patchEnvelopes };
|
|
547
593
|
return next;
|
|
548
594
|
}
|
|
595
|
+
async function prepareWorkerGitWorktree(input) {
|
|
596
|
+
if (input.policy?.mode !== 'git-worktree')
|
|
597
|
+
return null;
|
|
598
|
+
const sliceHasWritePaths = Array.isArray(input.slice.write_paths) && input.slice.write_paths.length > 0;
|
|
599
|
+
const agentWriteCapable = input.agent.write_allowed === true || /write|lease|required/i.test(String(input.agent.write_policy || ''));
|
|
600
|
+
if (!sliceHasWritePaths && !agentWriteCapable)
|
|
601
|
+
return null;
|
|
602
|
+
const generationIndex = Math.max(1, Math.floor(Number(input.agent.generation_index || 1)));
|
|
603
|
+
const allocation = await allocateWorkerWorktree({
|
|
604
|
+
repoRoot: input.policy.main_repo_root || input.root,
|
|
605
|
+
missionId: input.missionId,
|
|
606
|
+
workerId: String(input.agent.id || input.slice.id || 'worker'),
|
|
607
|
+
slotId: String(input.agent.slot_id || input.agent.id || 'slot-001'),
|
|
608
|
+
generationIndex
|
|
609
|
+
});
|
|
610
|
+
const artifactDir = path.join(input.ledgerRoot, input.agent.session_artifact_dir || path.join('sessions', input.agent.id || input.slice.id || 'worker'), 'worker');
|
|
611
|
+
await writeJsonAtomic(path.join(artifactDir, 'git-worktree-allocation.json'), allocation);
|
|
612
|
+
input.runtime.allocations.push({
|
|
613
|
+
agent_id: input.agent.id,
|
|
614
|
+
slice_id: input.slice.id,
|
|
615
|
+
ok: allocation.ok,
|
|
616
|
+
worktree_path: allocation.worktree_path,
|
|
617
|
+
branch: allocation.branch,
|
|
618
|
+
blockers: allocation.blockers
|
|
619
|
+
});
|
|
620
|
+
input.runtime.blockers.push(...allocation.blockers);
|
|
621
|
+
input.runtime.ok = input.runtime.blockers.length === 0;
|
|
622
|
+
await writeJsonAtomic(path.join(input.ledgerRoot, 'agent-git-worktree-runtime.json'), input.runtime);
|
|
623
|
+
if (!allocation.ok)
|
|
624
|
+
return null;
|
|
625
|
+
return {
|
|
626
|
+
allocation,
|
|
627
|
+
artifactDir,
|
|
628
|
+
context: {
|
|
629
|
+
id: `${allocation.slot_id}-gen-${allocation.generation_index}`,
|
|
630
|
+
path: allocation.worktree_path,
|
|
631
|
+
branch: allocation.branch,
|
|
632
|
+
main_repo_root: allocation.main_repo_root
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
async function finalizeWorkerGitWorktree(input) {
|
|
637
|
+
const allocation = input.workerWorktree.allocation;
|
|
638
|
+
const diff = await exportGitWorktreeDiff({
|
|
639
|
+
mainRepoRoot: allocation.main_repo_root || input.root,
|
|
640
|
+
worktreePath: allocation.worktree_path,
|
|
641
|
+
missionId: input.missionId,
|
|
642
|
+
workerId: String(input.agent.id || input.slice.id || 'worker')
|
|
643
|
+
});
|
|
644
|
+
await writeJsonAtomic(path.join(input.workerWorktree.artifactDir, 'git-worktree-diff.json'), diff);
|
|
645
|
+
input.runtime.diffs.push({
|
|
646
|
+
agent_id: input.agent.id,
|
|
647
|
+
slice_id: input.slice.id,
|
|
648
|
+
ok: diff.ok,
|
|
649
|
+
clean: diff.clean,
|
|
650
|
+
changed_files: diff.changed_files,
|
|
651
|
+
diff_bytes: diff.diff_bytes,
|
|
652
|
+
blockers: diff.blockers
|
|
653
|
+
});
|
|
654
|
+
if (!diff.clean && diff.ok) {
|
|
655
|
+
const envelope = buildGitWorktreePatchEnvelope({
|
|
656
|
+
diff,
|
|
657
|
+
agentId: String(input.agent.id || 'agent'),
|
|
658
|
+
sessionId: String(input.agent.session_id || ''),
|
|
659
|
+
slotId: String(input.agent.slot_id || ''),
|
|
660
|
+
generationIndex: Math.max(1, Math.floor(Number(input.agent.generation_index || 1)))
|
|
661
|
+
});
|
|
662
|
+
input.result.patch_envelopes = [...(Array.isArray(input.result.patch_envelopes) ? input.result.patch_envelopes : []), envelope];
|
|
663
|
+
input.result.changed_files = [...new Set([...(input.result.changed_files || []), ...diff.changed_files])];
|
|
664
|
+
input.result.artifacts = [...new Set([...(input.result.artifacts || []), path.relative(input.ledgerRoot, path.join(input.workerWorktree.artifactDir, 'git-worktree-diff.json'))])];
|
|
665
|
+
input.result.git_worktree_diff = diff;
|
|
666
|
+
}
|
|
667
|
+
const cleanup = await cleanupGitWorktree({
|
|
668
|
+
repoRoot: allocation.main_repo_root || input.root,
|
|
669
|
+
worktreePath: allocation.worktree_path,
|
|
670
|
+
branch: allocation.branch,
|
|
671
|
+
deleteBranch: diff.clean
|
|
672
|
+
});
|
|
673
|
+
await writeJsonAtomic(path.join(input.workerWorktree.artifactDir, 'git-worktree-cleanup.json'), cleanup);
|
|
674
|
+
input.runtime.cleanup.push({
|
|
675
|
+
agent_id: input.agent.id,
|
|
676
|
+
slice_id: input.slice.id,
|
|
677
|
+
action: cleanup.action,
|
|
678
|
+
clean: cleanup.clean,
|
|
679
|
+
retention_lock_path: cleanup.retention_lock_path,
|
|
680
|
+
blockers: cleanup.blockers
|
|
681
|
+
});
|
|
682
|
+
input.runtime.blockers.push(...diff.blockers, ...cleanup.blockers);
|
|
683
|
+
input.runtime.ok = input.runtime.blockers.length === 0;
|
|
684
|
+
await writeJsonAtomic(path.join(input.ledgerRoot, 'agent-git-worktree-runtime.json'), input.runtime);
|
|
685
|
+
}
|
|
549
686
|
async function legacyCodexExecBlockedRun(input) {
|
|
550
687
|
const blockers = ['legacy_codex_exec_runtime_removed'];
|
|
551
688
|
const ledgerRoot = path.join(input.dir, 'agents');
|
|
@@ -779,7 +916,7 @@ async function runAgentPatchSwarmRuntime(root, ledgerRoot, input) {
|
|
|
779
916
|
await queueStore.persistSnapshot();
|
|
780
917
|
const journalSummary = await queueStore.journal.writeSummary();
|
|
781
918
|
const proof = buildAgentPatchProof({ ...proofInput, transactionJournal: journalSummary });
|
|
782
|
-
const zeroPatchBlockers = input.writeCapable && input.parallelWritePolicy?.write_mode === 'parallel' && pendingEntries.length === 0 && input.parallelWritePolicy?.dry_run_patches !== true
|
|
919
|
+
const zeroPatchBlockers = input.writeCapable && input.parallelWritePolicy?.write_mode === 'parallel' && pendingEntries.length === 0 && input.dryRun !== true && input.parallelWritePolicy?.dry_run_patches !== true
|
|
783
920
|
? ['write_mode_parallel_zero_patch_envelopes']
|
|
784
921
|
: [];
|
|
785
922
|
const blockers = [
|
|
@@ -870,6 +1007,8 @@ function normalizeVisualLaneCount(value, fallback, maxAgentCount) {
|
|
|
870
1007
|
return Math.max(1, Math.min(maxAgentCount, Math.floor(raw)));
|
|
871
1008
|
}
|
|
872
1009
|
function isWriteCapableRun(opts) {
|
|
1010
|
+
if (opts.readonly === true)
|
|
1011
|
+
return false;
|
|
873
1012
|
return opts.applyPatches === true || opts.dryRunPatches === true || (opts.writeMode !== undefined && opts.writeMode !== 'off');
|
|
874
1013
|
}
|
|
875
1014
|
function defaultRouteCommand(route) {
|
|
@@ -991,6 +1130,7 @@ async function runAgentByBackend(backend, agent, slice, opts) {
|
|
|
991
1130
|
...sdkWorkerResult,
|
|
992
1131
|
backend: 'codex-sdk',
|
|
993
1132
|
patch_envelopes: patchEnvelopes,
|
|
1133
|
+
...(patchEnvelopes.length ? {} : { no_patch_reason: buildDirectNoPatchReason(slice, opts) }),
|
|
994
1134
|
codex_child_report: sdkReport,
|
|
995
1135
|
codex_sdk_thread: sdkReport,
|
|
996
1136
|
model_authored_patch_envelopes: patchEnvelopes.length > 0,
|
|
@@ -1027,10 +1167,24 @@ function buildDirectSdkWorkerPrompt(slice) {
|
|
|
1027
1167
|
'',
|
|
1028
1168
|
write.length
|
|
1029
1169
|
? `Write-capable slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; include patch_envelopes for write_paths=${JSON.stringify(write)}. Each patch envelope must include schema, source "model_authored", agent_id, session_id, slot_id, generation_index, task_slice_id, lease_id, allowed_paths, operations, and rationale. Each operation must include op, path, search, replace, content, and diff; use empty strings for operation fields that do not apply.`
|
|
1030
|
-
: `Read-only slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}.`,
|
|
1170
|
+
: `Read-only slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; do not report pre-existing repository dirtiness as changed_files.`,
|
|
1031
1171
|
'Required JSON fields: status, summary, findings, changed_files, patch_envelopes, verification, rollback_notes, blockers.'
|
|
1032
1172
|
].join('\n');
|
|
1033
1173
|
}
|
|
1174
|
+
function buildDirectNoPatchReason(slice, opts) {
|
|
1175
|
+
const writePathCount = sdkWritePaths(slice, opts).length;
|
|
1176
|
+
return {
|
|
1177
|
+
schema: 'sks.native-cli-worker-no-patch-reason.v1',
|
|
1178
|
+
generated_at: nowIso(),
|
|
1179
|
+
ok: writePathCount === 0,
|
|
1180
|
+
reason: writePathCount ? 'write_capable_task_without_backend_patch_envelope' : 'read_only_or_no_write_paths',
|
|
1181
|
+
route_justification: writePathCount ? 'backend returned no patch envelopes for a write-capable task' : 'task has no write paths',
|
|
1182
|
+
read_only_or_noop_evidence: writePathCount === 0,
|
|
1183
|
+
task_slice_id: slice?.id || null,
|
|
1184
|
+
backend: 'codex-sdk',
|
|
1185
|
+
blockers: writePathCount ? ['write_capable_no_patch_envelope'] : []
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1034
1188
|
function sdkWritePaths(slice, opts) {
|
|
1035
1189
|
return [
|
|
1036
1190
|
...(Array.isArray(slice?.write_paths) ? slice.write_paths : []),
|