sneakoscope 2.0.6 → 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 +6 -1
- 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 +32 -8
- package/dist/core/agents/agent-orchestrator.js +138 -3
- package/dist/core/agents/agent-patch-schema.js +16 -2
- package/dist/core/agents/agent-proof-evidence.js +3 -0
- package/dist/core/agents/native-cli-session-swarm.js +25 -4
- package/dist/core/agents/native-cli-worker.js +28 -1
- package/dist/core/codex-control/python-codex-sdk-adapter.js +28 -4
- package/dist/core/commands/naruto-command.js +39 -10
- 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/naruto/naruto-active-pool.js +35 -0
- package/dist/core/naruto/naruto-gpt-final-pack.js +2 -0
- package/dist/core/naruto/naruto-work-graph.js +16 -1
- 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-shadow-clone-swarm-check.js +9 -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/release-parallel-check.js +1 -1
- package/package.json +14 -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,15 @@ 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.
|
|
23
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.
|
|
24
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.
|
|
25
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.
|
|
@@ -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",
|
|
@@ -814,6 +827,13 @@
|
|
|
814
827
|
"scripts/flagship-proof-graph-v3-check.js",
|
|
815
828
|
"scripts/flagship-proof-graph-v4-check.js",
|
|
816
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",
|
|
817
837
|
"scripts/goal-mode-official-default-check.js",
|
|
818
838
|
"scripts/gpt-final-arbiter-check.js",
|
|
819
839
|
"scripts/gpt-final-arbiter-performance-check.js",
|
|
@@ -841,6 +861,7 @@
|
|
|
841
861
|
"scripts/legacy-upgrade-matrix-check.js",
|
|
842
862
|
"scripts/lib/codex-sdk-gate-lib.js",
|
|
843
863
|
"scripts/lib/ensure-dist-fresh.js",
|
|
864
|
+
"scripts/lib/git-worktree-fixture.js",
|
|
844
865
|
"scripts/lib/mad-sks-actual-executor-check-lib.js",
|
|
845
866
|
"scripts/lib/native-cli-session-swarm-check-lib.js",
|
|
846
867
|
"scripts/lib/real-codex-parallel-gate.js",
|
|
@@ -894,6 +915,9 @@
|
|
|
894
915
|
"scripts/naruto-shadow-clone-swarm-check.js",
|
|
895
916
|
"scripts/naruto-verification-pool-check.js",
|
|
896
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",
|
|
897
921
|
"scripts/naruto-zellij-massive-ui-check.js",
|
|
898
922
|
"scripts/non-recursive-pipeline-check.js",
|
|
899
923
|
"scripts/npm-publish-performance-check.js",
|
|
@@ -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');
|
|
@@ -253,6 +257,21 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
253
257
|
strategy_gate: strategyRef
|
|
254
258
|
};
|
|
255
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);
|
|
256
275
|
const nativeCliSwarm = createNativeCliSessionSwarmRecorder(ledgerRoot, {
|
|
257
276
|
missionId,
|
|
258
277
|
requestedAgents: Number(opts.agents || roster.agent_count || targetActiveSlots),
|
|
@@ -280,6 +299,17 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
280
299
|
goalModeRef,
|
|
281
300
|
launchSession: async ({ agent, workItem }) => {
|
|
282
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;
|
|
283
313
|
await openAgentSession(ledgerRoot, agent);
|
|
284
314
|
await heartbeatAgentSession(ledgerRoot, agent);
|
|
285
315
|
await appendAgentCodexCockpitHookEvent(dir, {
|
|
@@ -303,10 +333,21 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
303
333
|
generationIndex: agent.generation_index,
|
|
304
334
|
requireGeneration: true
|
|
305
335
|
});
|
|
306
|
-
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 } : {}) };
|
|
307
337
|
const result = opts.nativeCliSwarm === false
|
|
308
|
-
? await runAgentByBackend(backend,
|
|
309
|
-
: 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
|
+
});
|
|
310
351
|
const terminalClose = await closeAgentTerminalSession(ledgerRoot, agent, {
|
|
311
352
|
exitCode: result.status === 'done' ? 0 : 1,
|
|
312
353
|
status: result.status,
|
|
@@ -444,6 +485,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
444
485
|
...(nativeCliSessionProof.ok ? [] : nativeCliSessionProof.blockers),
|
|
445
486
|
...(noSubagentScalingPolicy.ok ? [] : noSubagentScalingPolicy.blockers),
|
|
446
487
|
...(fastModePropagation.ok ? [] : fastModePropagation.blockers),
|
|
488
|
+
...(gitWorktreeRuntime.required === true && gitWorktreeRuntime.ok === false ? gitWorktreeRuntime.blockers || ['git_worktree_runtime_not_ok'] : []),
|
|
447
489
|
...(localParticipated && gptFinalArbiter?.ok !== true ? gptFinalArbiter?.blockers || ['gpt_final_arbiter_not_ok'] : []),
|
|
448
490
|
...(localParticipated && finalGptPatchStage?.ok === false ? finalGptPatchStage.blockers || ['final_gpt_patch_stage_not_ok'] : []),
|
|
449
491
|
...(patchSwarm.ok ? [] : patchSwarm.blockers),
|
|
@@ -480,6 +522,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
480
522
|
noSubagentScalingPolicy,
|
|
481
523
|
fastModePolicy,
|
|
482
524
|
fastModePropagation,
|
|
525
|
+
gitWorktreeRuntime,
|
|
483
526
|
triwikiContext,
|
|
484
527
|
selectedCoreSkill,
|
|
485
528
|
localCollaborationPolicy,
|
|
@@ -524,6 +567,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
524
567
|
no_subagent_scaling_policy: noSubagentScalingPolicy,
|
|
525
568
|
fast_mode_policy: fastModePolicy,
|
|
526
569
|
fast_mode_propagation: fastModePropagation,
|
|
570
|
+
git_worktree_runtime: gitWorktreeRuntime,
|
|
527
571
|
local_collaboration_policy: localCollaborationPolicy,
|
|
528
572
|
gpt_final_arbiter: gptFinalArbiter,
|
|
529
573
|
final_gpt_patch_stage: finalGptPatchStage,
|
|
@@ -548,6 +592,97 @@ function withFinalGptPatchEnvelopes(results, patchEnvelopes = []) {
|
|
|
548
592
|
next[0] = { ...next[0], patch_envelopes: patchEnvelopes };
|
|
549
593
|
return next;
|
|
550
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
|
+
}
|
|
551
686
|
async function legacyCodexExecBlockedRun(input) {
|
|
552
687
|
const blockers = ['legacy_codex_exec_runtime_removed'];
|
|
553
688
|
const ledgerRoot = path.join(input.dir, 'agents');
|
|
@@ -27,6 +27,7 @@ export function normalizeAgentPatchEnvelope(input) {
|
|
|
27
27
|
...(input?.verification_node_id === undefined ? {} : { verification_node_id: String(input.verification_node_id) }),
|
|
28
28
|
...(input?.rollback_node_id === undefined ? {} : { rollback_node_id: String(input.rollback_node_id) }),
|
|
29
29
|
...(input?.lease_proof ? { lease_proof: normalizeLeaseProof(input.lease_proof) } : {}),
|
|
30
|
+
...(input?.git_worktree ? { git_worktree: normalizeGitWorktreeMetadata(input.git_worktree) } : {}),
|
|
30
31
|
...(input?.rationale ? { rationale: String(input.rationale) } : {}),
|
|
31
32
|
...(input?.verification_hint ? { verification_hint: normalizeHint(input.verification_hint) } : {}),
|
|
32
33
|
...(input?.rollback_hint ? { rollback_hint: normalizeHint(input.rollback_hint) } : {}),
|
|
@@ -49,12 +50,14 @@ export function validateAgentPatchEnvelope(envelope) {
|
|
|
49
50
|
violations.push('lease_id_missing');
|
|
50
51
|
if (!envelope.operations.length)
|
|
51
52
|
violations.push('operations_missing');
|
|
52
|
-
if (envelope.source && !['fixture', 'model_authored', 'process_generated', 'zellij_generated'].includes(envelope.source))
|
|
53
|
+
if (envelope.source && !['fixture', 'model_authored', 'process_generated', 'zellij_generated', 'git-worktree-diff'].includes(envelope.source))
|
|
53
54
|
violations.push('source_invalid');
|
|
54
55
|
if (envelope.source === 'model_authored' && !hasFiniteNumber(envelope.backend_child_process_id) && !envelope.backend_sdk_thread_id && !envelope.backend_ollama_request_id)
|
|
55
56
|
violations.push('model_authored_backend_proof_missing');
|
|
56
57
|
if (envelope.source === 'fixture' && envelope.backend_child_process_id !== undefined)
|
|
57
58
|
violations.push('fixture_backend_child_process_id_present');
|
|
59
|
+
if (envelope.source === 'git-worktree-diff' && !envelope.git_worktree?.worktree_path)
|
|
60
|
+
violations.push('git_worktree_metadata_missing');
|
|
58
61
|
for (const operation of envelope.operations) {
|
|
59
62
|
if (!operation.path || operation.path.includes('\0') || operation.path.startsWith('/') || operation.path.split(/[\\/]/).includes('..')) {
|
|
60
63
|
violations.push(`invalid_path:${operation.path || 'missing'}`);
|
|
@@ -74,7 +77,7 @@ export function validateAgentPatchEnvelope(envelope) {
|
|
|
74
77
|
}
|
|
75
78
|
function normalizeEnvelopeSource(value) {
|
|
76
79
|
const text = String(value || '');
|
|
77
|
-
return text === 'fixture' || text === 'model_authored' || text === 'process_generated' || text === 'zellij_generated' ? text : null;
|
|
80
|
+
return text === 'fixture' || text === 'model_authored' || text === 'process_generated' || text === 'zellij_generated' || text === 'git-worktree-diff' ? text : null;
|
|
78
81
|
}
|
|
79
82
|
function hasFiniteNumber(value) {
|
|
80
83
|
return value !== null && value !== undefined && value !== '' && Number.isFinite(Number(value));
|
|
@@ -104,6 +107,17 @@ function normalizeLeaseProof(input) {
|
|
|
104
107
|
...(input?.rollback_node_id === undefined ? {} : { rollback_node_id: String(input.rollback_node_id) })
|
|
105
108
|
};
|
|
106
109
|
}
|
|
110
|
+
function normalizeGitWorktreeMetadata(input) {
|
|
111
|
+
return {
|
|
112
|
+
main_repo_root: String(input?.main_repo_root || ''),
|
|
113
|
+
worktree_path: String(input?.worktree_path || ''),
|
|
114
|
+
branch: input?.branch == null ? null : String(input.branch),
|
|
115
|
+
base_head: input?.base_head == null ? null : String(input.base_head),
|
|
116
|
+
worktree_head: input?.worktree_head == null ? null : String(input.worktree_head),
|
|
117
|
+
changed_files: Array.isArray(input?.changed_files) ? input.changed_files.map(String) : [],
|
|
118
|
+
diff_bytes: Number(input?.diff_bytes || 0)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
107
121
|
function normalizeHint(input) {
|
|
108
122
|
return {
|
|
109
123
|
...(input?.command === undefined ? {} : { command: String(input.command) }),
|
|
@@ -21,6 +21,7 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
21
21
|
const scheduler = input.scheduler || await readJson(path.join(root, 'agent-scheduler-state.json'), null);
|
|
22
22
|
const taskGraph = input.partition?.task_graph || await readJson(path.join(root, 'agent-task-graph.json'), null);
|
|
23
23
|
const parallelWritePolicy = input.parallelWritePolicy || await readJson(path.join(root, 'agent-parallel-write-policy.json'), null);
|
|
24
|
+
const gitWorktreeRuntime = input.gitWorktreeRuntime || await readJson(path.join(root, 'agent-git-worktree-runtime.json'), null);
|
|
24
25
|
const patchQueue = await readJson(path.join(root, 'agent-patch-queue.json'), null);
|
|
25
26
|
const patchQueueEvents = await readTextSafe(path.join(root, 'agent-patch-queue-events.jsonl'));
|
|
26
27
|
const patchMerge = await readJson(path.join(root, 'agent-merge-coordinator-report.json'), null);
|
|
@@ -180,6 +181,7 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
180
181
|
...(noSubagentScalingPolicy?.ok === false ? noSubagentScalingPolicy.blockers || ['no_subagent_scaling_policy_not_ok'] : []),
|
|
181
182
|
...(fastModePropagation?.ok === false ? fastModePropagation.blockers || ['fast_mode_propagation_not_ok'] : []),
|
|
182
183
|
...(patchSwarm?.ok === false ? patchSwarm.blockers || ['patch_swarm_not_ok'] : []),
|
|
184
|
+
...(gitWorktreeRuntime?.required === true && gitWorktreeRuntime?.ok === false ? gitWorktreeRuntime.blockers || ['git_worktree_runtime_not_ok'] : []),
|
|
183
185
|
...(patchSwarm && !patchQueue ? ['patch_queue_missing'] : []),
|
|
184
186
|
...(patchSwarm && !patchMerge ? ['patch_merge_report_missing'] : []),
|
|
185
187
|
...(patchSwarm && !patchApplyResults ? ['patch_apply_results_missing'] : []),
|
|
@@ -217,6 +219,7 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
217
219
|
// Deployed Core Skill snapshot consulted at route start (read-only; never
|
|
218
220
|
// confers mutation rights). Null when no snapshot is deployed for this route.
|
|
219
221
|
selected_core_skill: input.selectedCoreSkill || null,
|
|
222
|
+
git_worktree_runtime: gitWorktreeRuntime,
|
|
220
223
|
route_blackbox_kind: input.routeBlackboxKind || (realRouteCommandUsed ? 'actual_route_command' : 'generic_agent_route_standin'),
|
|
221
224
|
real_route_command_used: realRouteCommandUsed,
|
|
222
225
|
native_cli_session_proof: nativeCliSessionProof ? 'native-cli-session-proof.json' : null,
|
|
@@ -26,6 +26,8 @@ class NativeCliSessionSwarmRecorder {
|
|
|
26
26
|
await this.persist();
|
|
27
27
|
}
|
|
28
28
|
async launchWorker(ctx) {
|
|
29
|
+
const worktree = normalizeWorkerWorktree(ctx.agent?.worktree || ctx.slice?.worktree || ctx.opts?.worktree || null);
|
|
30
|
+
const workerCwd = worktree?.path || ctx.opts.cwd || packageRoot();
|
|
29
31
|
const workerDirRel = path.join(ctx.agent.session_artifact_dir || path.join('sessions', ctx.agent.id), 'worker');
|
|
30
32
|
const workerDir = path.join(this.root, workerDirRel);
|
|
31
33
|
await ensureDir(workerDir);
|
|
@@ -45,6 +47,9 @@ class NativeCliSessionSwarmRecorder {
|
|
|
45
47
|
backend_explicit: this.input.backendExplicit === true,
|
|
46
48
|
no_ollama: this.input.noOllama === true || ctx.opts.noOllama === true,
|
|
47
49
|
agent_root: this.root,
|
|
50
|
+
main_repo_root: worktree?.main_repo_root || ctx.opts.cwd || packageRoot(),
|
|
51
|
+
cwd: workerCwd,
|
|
52
|
+
worktree,
|
|
48
53
|
agent: ctx.agent,
|
|
49
54
|
slice: ctx.slice,
|
|
50
55
|
worker_artifact_dir: workerDirRel,
|
|
@@ -89,6 +94,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
89
94
|
patch_envelope_path: patchRel,
|
|
90
95
|
fast_mode: this.input.fastModePolicy.fast_mode,
|
|
91
96
|
service_tier: this.input.fastModePolicy.service_tier,
|
|
97
|
+
cwd: workerCwd,
|
|
92
98
|
status: 'launching',
|
|
93
99
|
exit_code: null,
|
|
94
100
|
blockers: []
|
|
@@ -110,7 +116,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
110
116
|
});
|
|
111
117
|
}
|
|
112
118
|
const child = spawn(process.execPath, args, {
|
|
113
|
-
cwd:
|
|
119
|
+
cwd: workerCwd,
|
|
114
120
|
env: {
|
|
115
121
|
...process.env,
|
|
116
122
|
...(ctx.opts.env || {}),
|
|
@@ -179,6 +185,8 @@ class NativeCliSessionSwarmRecorder {
|
|
|
179
185
|
async launchWorkerInZellijPane(input) {
|
|
180
186
|
const sessionName = String(input.ctx.opts.zellijSessionName || (this.input.missionId ? `sks-${this.input.missionId}` : 'sks-agent-runtime'));
|
|
181
187
|
const slotId = String(input.ctx.agent.slot_id || input.ctx.agent.id || 'slot-001');
|
|
188
|
+
const worktree = normalizeWorkerWorktree(input.ctx.agent?.worktree || input.ctx.slice?.worktree || input.ctx.opts?.worktree || null);
|
|
189
|
+
const workerCwd = worktree?.path || input.ctx.opts.cwd || packageRoot();
|
|
182
190
|
const activeToken = this.nextPaneToken--;
|
|
183
191
|
this.active.add(activeToken);
|
|
184
192
|
this.maxObserved = Math.max(this.maxObserved, this.active.size);
|
|
@@ -222,9 +230,10 @@ class NativeCliSessionSwarmRecorder {
|
|
|
222
230
|
patchEnvelopePath: input.record.patch_envelope_path,
|
|
223
231
|
stdoutLog: input.stdoutRel,
|
|
224
232
|
stderrLog: input.stderrRel,
|
|
225
|
-
cwd:
|
|
233
|
+
cwd: workerCwd,
|
|
226
234
|
providerContext,
|
|
227
|
-
serviceTier: this.input.fastModePolicy.service_tier
|
|
235
|
+
serviceTier: this.input.fastModePolicy.service_tier,
|
|
236
|
+
worktree: worktree ? { id: worktree.id, path: worktree.path, branch: worktree.branch } : null
|
|
228
237
|
});
|
|
229
238
|
const launchBlockers = paneRecord.blockers || [];
|
|
230
239
|
input.record.command_line = ['zellij', '--session', sessionName, 'action', 'new-pane', '--direction', paneRecord.direction_applied, '--name', paneRecord.pane_name, '--', 'sh', '-lc', '<native-cli-worker-command>'];
|
|
@@ -239,6 +248,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
239
248
|
input.record.provider = paneRecord.provider;
|
|
240
249
|
input.record.service_tier = paneRecord.service_tier;
|
|
241
250
|
input.record.provider_context = paneRecord.provider_context;
|
|
251
|
+
input.record.worktree = worktree;
|
|
242
252
|
input.record.status = launchBlockers.length ? 'failed' : 'running';
|
|
243
253
|
input.record.blockers = launchBlockers;
|
|
244
254
|
await this.record(input.record);
|
|
@@ -323,7 +333,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
323
333
|
paneRecord = await closeWorkerPane({
|
|
324
334
|
root: this.root,
|
|
325
335
|
paneRecord,
|
|
326
|
-
cwd:
|
|
336
|
+
cwd: workerCwd,
|
|
327
337
|
status: input.record.status === 'closed' ? 'closed' : 'failed',
|
|
328
338
|
blockers: input.record.blockers,
|
|
329
339
|
sdkThreadId,
|
|
@@ -462,4 +472,15 @@ function redactWorkerArgs(args) {
|
|
|
462
472
|
function shellQuote(value) {
|
|
463
473
|
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
464
474
|
}
|
|
475
|
+
function normalizeWorkerWorktree(value) {
|
|
476
|
+
const pathValue = value?.path || value?.worktree_path;
|
|
477
|
+
if (!pathValue)
|
|
478
|
+
return null;
|
|
479
|
+
return {
|
|
480
|
+
id: String(value?.id || value?.worktree_id || value?.slot_id || 'worktree'),
|
|
481
|
+
path: String(pathValue),
|
|
482
|
+
branch: String(value?.branch || 'unknown'),
|
|
483
|
+
main_repo_root: value?.main_repo_root == null ? null : String(value.main_repo_root)
|
|
484
|
+
};
|
|
485
|
+
}
|
|
465
486
|
//# sourceMappingURL=native-cli-session-swarm.js.map
|
|
@@ -27,6 +27,8 @@ export async function runNativeCliWorker(input = {}) {
|
|
|
27
27
|
};
|
|
28
28
|
const slice = intake.slice || {};
|
|
29
29
|
const backend = String(input.backend || intake.backend || 'fake');
|
|
30
|
+
const workerCwd = path.resolve(String(input.cwd || intake.cwd || process.cwd()));
|
|
31
|
+
const worktree = normalizeWorkerWorktree(input.worktree || intake.worktree || null);
|
|
30
32
|
const policy = resolveFastModePolicy({
|
|
31
33
|
fastMode: intake.fast_mode ?? input.fastMode,
|
|
32
34
|
serviceTier: intake.service_tier ?? input.serviceTier
|
|
@@ -37,6 +39,10 @@ export async function runNativeCliWorker(input = {}) {
|
|
|
37
39
|
const heartbeatRel = String(input.heartbeatPath || intake.heartbeat_path || path.join(workerDirRel, 'worker-heartbeat.jsonl'));
|
|
38
40
|
const patchRel = String(input.patchEnvelopePath || intake.patch_envelope_path || path.join(workerDirRel, 'worker-patch-envelope.json'));
|
|
39
41
|
await ensureDir(workerDir);
|
|
42
|
+
try {
|
|
43
|
+
process.chdir(workerCwd);
|
|
44
|
+
}
|
|
45
|
+
catch { }
|
|
40
46
|
const recursion = scanAgentTextForRecursion(JSON.stringify({ agent, slice, backend }));
|
|
41
47
|
const guard = {
|
|
42
48
|
schema: 'sks.native-cli-worker-recursion-guard.v1',
|
|
@@ -56,6 +62,9 @@ export async function runNativeCliWorker(input = {}) {
|
|
|
56
62
|
persona_id: String(agent.persona_id || input.personaId || ''),
|
|
57
63
|
lease_id: String(intake.lease_id || input.leaseId || ''),
|
|
58
64
|
agent_root: agentRoot,
|
|
65
|
+
main_repo_root: String(input.mainRepoRoot || intake.main_repo_root || worktree?.main_repo_root || agentRoot),
|
|
66
|
+
cwd: workerCwd,
|
|
67
|
+
worktree,
|
|
59
68
|
worker_artifact_dir: workerDirRel,
|
|
60
69
|
result_path: resultRel,
|
|
61
70
|
heartbeat_path: heartbeatRel,
|
|
@@ -65,7 +74,9 @@ export async function runNativeCliWorker(input = {}) {
|
|
|
65
74
|
backend: backend === 'zellij' ? 'codex-sdk' : backend,
|
|
66
75
|
output_schema_id: 'sks.agent-worker-result.v1',
|
|
67
76
|
sandbox_policy: Array.isArray(slice.write_paths) && slice.write_paths.length > 0 ? 'workspace-write' : 'read-only',
|
|
68
|
-
thread_policy: 'new_thread_per_generation'
|
|
77
|
+
thread_policy: 'new_thread_per_generation',
|
|
78
|
+
worktree,
|
|
79
|
+
cwd: workerCwd
|
|
69
80
|
},
|
|
70
81
|
service_tier: policy.service_tier,
|
|
71
82
|
fast_mode: policy.fast_mode,
|
|
@@ -143,6 +154,8 @@ export async function runNativeCliWorker(input = {}) {
|
|
|
143
154
|
generated_at: nowIso(),
|
|
144
155
|
ok: guard.ok,
|
|
145
156
|
backend,
|
|
157
|
+
cwd: workerCwd,
|
|
158
|
+
worktree,
|
|
146
159
|
agent_id: agent.id,
|
|
147
160
|
session_id: agent.session_id,
|
|
148
161
|
slot_id: agent.slot_id || null,
|
|
@@ -221,6 +234,9 @@ export async function runNativeCliWorker(input = {}) {
|
|
|
221
234
|
slot_id: agent.slot_id || null,
|
|
222
235
|
generation_index: agent.generation_index || null,
|
|
223
236
|
process_id: process.pid,
|
|
237
|
+
main_repo_root: String(input.mainRepoRoot || intake.main_repo_root || worktree?.main_repo_root || agentRoot),
|
|
238
|
+
cwd: workerCwd,
|
|
239
|
+
worktree,
|
|
224
240
|
artifact_dir: workerDirRel,
|
|
225
241
|
patch_envelope: patchEnvelopes.length ? patchRel : null,
|
|
226
242
|
no_patch_reason: patchEnvelopes.length ? null : path.join(workerDirRel, 'worker-no-patch-reason.json'),
|
|
@@ -290,4 +306,15 @@ function redactCommandLine(argv) {
|
|
|
290
306
|
return part;
|
|
291
307
|
});
|
|
292
308
|
}
|
|
309
|
+
function normalizeWorkerWorktree(value) {
|
|
310
|
+
const pathValue = value?.path || value?.worktree_path;
|
|
311
|
+
if (!pathValue)
|
|
312
|
+
return null;
|
|
313
|
+
return {
|
|
314
|
+
id: String(value?.id || value?.worktree_id || value?.slot_id || 'worktree'),
|
|
315
|
+
path: String(pathValue),
|
|
316
|
+
branch: String(value?.branch || 'unknown'),
|
|
317
|
+
main_repo_root: value?.main_repo_root == null ? null : String(value.main_repo_root)
|
|
318
|
+
};
|
|
319
|
+
}
|
|
293
320
|
//# sourceMappingURL=native-cli-worker.js.map
|