@wrongstack/core 0.8.6 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/defaults/index.d.ts +1 -1
- package/dist/defaults/index.js +17 -4
- package/dist/defaults/index.js.map +1 -1
- package/dist/{index-BvZld4Dr.d.ts → index-Dl3PaD7f.d.ts} +9 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +110 -53
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.d.ts +1 -1
- package/dist/{plan-templates-Cqdy6rtM.d.ts → plan-templates-Cc-04Z8o.d.ts} +8 -3
- package/dist/storage/index.d.ts +5 -2
- package/dist/storage/index.js +32 -10
- package/dist/storage/index.js.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -115,6 +115,15 @@ declare class WorktreeManager {
|
|
|
115
115
|
private detectBaseBranch;
|
|
116
116
|
private makeSlug;
|
|
117
117
|
private collectStats;
|
|
118
|
+
/**
|
|
119
|
+
* `git -c user.*` fallback so commits succeed on machines and CI runners
|
|
120
|
+
* that have no global git identity configured. Returns `[]` when both
|
|
121
|
+
* `user.name` and `user.email` are already set (the common case), so a real
|
|
122
|
+
* user's identity is never overridden. The worktree branch commits are
|
|
123
|
+
* squashed away on merge, so the fallback identity never reaches the base
|
|
124
|
+
* branch history.
|
|
125
|
+
*/
|
|
126
|
+
private identityArgs;
|
|
118
127
|
private unmergedFiles;
|
|
119
128
|
private emitCommitted;
|
|
120
129
|
private fail;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { S as SystemPromptBuilder, c as ModelCapabilities, a as BuildContext, C
|
|
|
2
2
|
export { B as BindOptions, D as Decorator, F as Factory, M as Middleware, b as MiddlewareHandler, N as NextFn, P as Pipeline, d as PipelineOptions, e as Renderer, T as Token } from './system-prompt-CWA6ml-d.js';
|
|
3
3
|
import { E as EventBus, c as EventName, L as Listener } from './events-yCpJD4wa.js';
|
|
4
4
|
export { a as EventLogger, b as EventMap, S as ScopedEventBus } from './events-yCpJD4wa.js';
|
|
5
|
-
import { d as WorktreeManager } from './index-
|
|
6
|
-
export { A as AllocateOpts, M as MergeOpts, a as MergeResult, R as RunController, b as RunControllerOptions, T as TOKENS, W as WorktreeHandle, e as WorktreeManagerOptions, c as WorktreeRunResult, f as WorktreeStatus, g as assertSafePath } from './index-
|
|
5
|
+
import { d as WorktreeManager } from './index-Dl3PaD7f.js';
|
|
6
|
+
export { A as AllocateOpts, M as MergeOpts, a as MergeResult, R as RunController, b as RunControllerOptions, T as TOKENS, W as WorktreeHandle, e as WorktreeManagerOptions, c as WorktreeRunResult, f as WorktreeStatus, g as assertSafePath } from './index-Dl3PaD7f.js';
|
|
7
7
|
import { d as Context, m as Provider, Q as Tool, c as ContentBlock, T as TextBlock } from './context-z2x5gv_V.js';
|
|
8
8
|
export { A as AgentError, a as Capabilities, b as ConfigError, e as ContextInit, f as ConversationState, E as ERROR_CODES, g as ErrorCode, h as ErrorSeverity, i as ErrorSubsystem, F as FileSnapshot, j as FsError, I as ImageBlock, J as JSONSchema, M as Message, k as MessageRole, P as Permission, l as PluginError, n as ProviderError, o as ProviderErrorBody, R as ReadonlyConversationState, p as Request, q as Response, r as ResumedSession, s as RiskTier, t as RunEnv, u as RunOptions, S as SessionData, v as SessionError, w as SessionEvent, x as SessionMetadata, y as SessionStore, z as SessionSummary, B as SessionWriter, D as StateChange, G as StateChangeHandler, H as StopReason, K as StreamEvent, L as ThinkingBlock, N as TodoItem, O as TokenCounter, U as ToolCallContext, V as ToolError, W as ToolFinalEvent, X as ToolProgressEvent, Y as ToolResultBlock, Z as ToolStreamEvent, _ as ToolUseBlock, $ as Usage, a0 as WrongStackError, a1 as asBlocks, a2 as asText, a3 as extractRunEnv, a4 as isAgentError, a5 as isConfigError, a6 as isFsError, a7 as isImageBlock, a8 as isPluginError, a9 as isSessionError, aa as isTextBlock, ab as isThinkingBlock, ac as isToolError, ad as isToolResultBlock, ae as isToolUseBlock, af as isWrongStackError, ag as toWrongStackError, ah as wrapAsState } from './context-z2x5gv_V.js';
|
|
9
9
|
export { P as ProviderRunner, R as RunProviderOptions } from './provider-runner-C4ouU7--.js';
|
|
@@ -36,7 +36,7 @@ export { C as CriticalPathResult, D as DEFAULT_SPEC_TEMPLATE, S as SpecAnalysis,
|
|
|
36
36
|
export { A as AggregateHealth, H as HealthCheck, a as HealthCheckResult, b as HealthRegistry, c as HealthStatus, M as MetricLabels, d as MetricSeries, e as MetricsSink, f as MetricsSnapshot, S as Span, T as Tracer } from './observability-BhnVLBLS.js';
|
|
37
37
|
export { AtomicWriteOptions, BuildChildEnvOptions, CompileFail, CompileResult, MessageRepairReport, MessageRepairResult, NewlineStyle, RequestTokenBreakdown, SafeParseResult, ToolOutputSerializerOptions, UnifiedDiffOptions, ValidationError, ValidationResult, atomicWrite, buildChildEnv, color, compileGlob, compileUserRegex, createToolOutputSerializer, detectNewlineStyle, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, formatTodosList, matchAny, matchGlob, normalizeToLf, repairToolUseAdjacency, safeParse, safeStringify, sanitizeJsonString, stripAnsi, toStyle, unifiedDiff, validateAgainstSchema } from './utils/index.js';
|
|
38
38
|
export { W as WstackPathOptions, a as WstackPaths, p as projectHash, r as resolveWstackPaths } from './wstack-paths-CJYrjQU8.js';
|
|
39
|
-
export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, M as MemoryStoreOptions, j as MigrationContext, k as MigrationResult, P as PersistedQueueItem, l as PlanFile, m as PlanItem, n as PlanTemplate, Q as QueueStore, R as RecoveryLock, o as RecoveryLockOptions, S as SessionAnalyzer, p as SessionStoreOptions, T as TodosCheckpointFile, q as addPlanItem, r as attachPlanCheckpoint, s as attachTodosCheckpoint, t as clearPlan, u as deriveTodosFromPlanItem, v as emptyPlan, w as formatPlan, x as formatPlanTemplates, y as getPlanTemplate, z as listPlanTemplates, B as loadPlan, E as loadTodosCheckpoint, F as removePlanItem, G as runConfigMigrations, H as savePlan, I as saveTodosCheckpoint, J as setPlanItemStatus } from './plan-templates-
|
|
39
|
+
export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, M as MemoryStoreOptions, j as MigrationContext, k as MigrationResult, P as PersistedQueueItem, l as PlanFile, m as PlanItem, n as PlanTemplate, Q as QueueStore, R as RecoveryLock, o as RecoveryLockOptions, S as SessionAnalyzer, p as SessionStoreOptions, T as TodosCheckpointFile, q as addPlanItem, r as attachPlanCheckpoint, s as attachTodosCheckpoint, t as clearPlan, u as deriveTodosFromPlanItem, v as emptyPlan, w as formatPlan, x as formatPlanTemplates, y as getPlanTemplate, z as listPlanTemplates, B as loadPlan, E as loadTodosCheckpoint, F as removePlanItem, G as runConfigMigrations, H as savePlan, I as saveTodosCheckpoint, J as setPlanItemStatus } from './plan-templates-Cc-04Z8o.js';
|
|
40
40
|
export { D as DirectorStateCheckpoint, a as DirectorStateSnapshot, b as DirectorSubagentState, c as DirectorTaskState, l as loadDirectorState } from './director-state-BmYi3DGA.js';
|
|
41
41
|
export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from './permission-policy-BBa1M1xc.js';
|
|
42
42
|
export { AutoCompactionMiddleware, AutonomousRunner, AutonomousRunnerOptions, AutonomyPromptContributorOptions, DefaultSkillLoader, DoneCheckResult, DoneConditionChecker, EternalAutonomyEngine, EternalAutonomyOptions, EternalEngineState, IntelligentCompactor, IntelligentCompactorOptions, ParallelEngineState, ParallelEternalEngine, ParallelEternalOptions, SelectiveCompactor, SelectiveCompactorOptions, SkillLoaderOptions, buildGoalPreamble, makeAutonomyPromptContributor } from './execution/index.js';
|
package/dist/index.js
CHANGED
|
@@ -93,7 +93,7 @@ async function renameWithRetry(from, to) {
|
|
|
93
93
|
if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
|
|
94
94
|
throw err;
|
|
95
95
|
}
|
|
96
|
-
await new Promise((
|
|
96
|
+
await new Promise((resolve9) => setTimeout(resolve9, delays[i]));
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
throw lastErr;
|
|
@@ -2694,7 +2694,7 @@ var InMemoryAgentBridge = class {
|
|
|
2694
2694
|
);
|
|
2695
2695
|
}
|
|
2696
2696
|
this.inflightGuards.add(correlationId);
|
|
2697
|
-
return new Promise((
|
|
2697
|
+
return new Promise((resolve9, reject) => {
|
|
2698
2698
|
const timer = setTimeout(() => {
|
|
2699
2699
|
this.inflightGuards.delete(correlationId);
|
|
2700
2700
|
this.pendingRequests.delete(correlationId);
|
|
@@ -2706,7 +2706,7 @@ var InMemoryAgentBridge = class {
|
|
|
2706
2706
|
return;
|
|
2707
2707
|
}
|
|
2708
2708
|
this.pendingRequests.set(correlationId, {
|
|
2709
|
-
resolve:
|
|
2709
|
+
resolve: resolve9,
|
|
2710
2710
|
reject,
|
|
2711
2711
|
timer
|
|
2712
2712
|
});
|
|
@@ -3990,7 +3990,9 @@ function looksSecret(name) {
|
|
|
3990
3990
|
}
|
|
3991
3991
|
function buildChildEnv(optsOrSessionId) {
|
|
3992
3992
|
const opts = typeof optsOrSessionId === "string" ? { sessionId: optsOrSessionId } : optsOrSessionId ?? {};
|
|
3993
|
-
const
|
|
3993
|
+
const hasOwn = Object.prototype.hasOwnProperty.call(process.env, "WRONGSTACK_CHILD_ENV_PASSTHROUGH");
|
|
3994
|
+
const legacyHasOwn = Object.prototype.hasOwnProperty.call(process.env, "WRONGSTACK_BASH_ENV_PASSTHROUGH");
|
|
3995
|
+
const passthrough = hasOwn && process.env["WRONGSTACK_CHILD_ENV_PASSTHROUGH"] === "1" || legacyHasOwn && process.env["WRONGSTACK_BASH_ENV_PASSTHROUGH"] === "1";
|
|
3994
3996
|
if (passthrough && !process.env["CI"]) {
|
|
3995
3997
|
console.warn(
|
|
3996
3998
|
"[WrongStack] WARNING: WRONGSTACK_*_ENV_PASSTHROUGH=1 is active \u2014\n all parent env vars (including API keys) forwarded to child processes.\n Do not use on shared or multi-tenant systems."
|
|
@@ -5369,9 +5371,14 @@ var RecoveryLock = class {
|
|
|
5369
5371
|
};
|
|
5370
5372
|
}
|
|
5371
5373
|
/**
|
|
5372
|
-
* Claim the lock for the given session.
|
|
5373
|
-
*
|
|
5374
|
-
* `checkAbandoned`
|
|
5374
|
+
* Claim the lock for the given session. Uses exclusive-create (`O_EXCL`)
|
|
5375
|
+
* to detect whether another process acquired the lock between our
|
|
5376
|
+
* `checkAbandoned()` call and now. If the file already exists, it means
|
|
5377
|
+
* another process won the race and we throw instead of silently
|
|
5378
|
+
* overwriting their recovery record.
|
|
5379
|
+
*
|
|
5380
|
+
* The caller MUST have already called `checkAbandoned()` and handled its
|
|
5381
|
+
* null return before calling this.
|
|
5375
5382
|
*/
|
|
5376
5383
|
async write(sessionId) {
|
|
5377
5384
|
await ensureDir(path6.dirname(this.file));
|
|
@@ -5382,7 +5389,15 @@ var RecoveryLock = class {
|
|
|
5382
5389
|
hostname: this.hostname,
|
|
5383
5390
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5384
5391
|
};
|
|
5385
|
-
|
|
5392
|
+
try {
|
|
5393
|
+
await fsp2.writeFile(this.file, JSON.stringify(lock), { flag: "wx", mode: 384 });
|
|
5394
|
+
} catch (err) {
|
|
5395
|
+
const code = err.code;
|
|
5396
|
+
if (code === "EEXIST") {
|
|
5397
|
+
throw new Error(`Recovery lock already held by another process`);
|
|
5398
|
+
}
|
|
5399
|
+
throw err;
|
|
5400
|
+
}
|
|
5386
5401
|
}
|
|
5387
5402
|
/**
|
|
5388
5403
|
* Release the lock. Idempotent — silently succeeds if the file is
|
|
@@ -6624,8 +6639,8 @@ async function streamProviderToResponse(provider, req, signal, ctx, events) {
|
|
|
6624
6639
|
try {
|
|
6625
6640
|
await Promise.race([
|
|
6626
6641
|
Promise.resolve(iter.return?.()),
|
|
6627
|
-
new Promise((
|
|
6628
|
-
drainTimer = setTimeout(
|
|
6642
|
+
new Promise((resolve9) => {
|
|
6643
|
+
drainTimer = setTimeout(resolve9, 500);
|
|
6629
6644
|
})
|
|
6630
6645
|
]);
|
|
6631
6646
|
} finally {
|
|
@@ -6686,7 +6701,7 @@ async function runProviderWithRetry(opts) {
|
|
|
6686
6701
|
description
|
|
6687
6702
|
});
|
|
6688
6703
|
}
|
|
6689
|
-
await new Promise((
|
|
6704
|
+
await new Promise((resolve9, reject) => {
|
|
6690
6705
|
let settled = false;
|
|
6691
6706
|
const onAbort = () => {
|
|
6692
6707
|
if (settled) return;
|
|
@@ -6699,7 +6714,7 @@ async function runProviderWithRetry(opts) {
|
|
|
6699
6714
|
settled = true;
|
|
6700
6715
|
clearTimeout(t2);
|
|
6701
6716
|
signal.removeEventListener("abort", onAbort);
|
|
6702
|
-
|
|
6717
|
+
resolve9();
|
|
6703
6718
|
}, delay);
|
|
6704
6719
|
if (signal.aborted) {
|
|
6705
6720
|
onAbort();
|
|
@@ -8343,7 +8358,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
8343
8358
|
}
|
|
8344
8359
|
};
|
|
8345
8360
|
function sleep(ms) {
|
|
8346
|
-
return new Promise((
|
|
8361
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
8347
8362
|
}
|
|
8348
8363
|
|
|
8349
8364
|
// src/coordination/subagent-budget.ts
|
|
@@ -8493,12 +8508,12 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8493
8508
|
if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
|
|
8494
8509
|
return Promise.resolve("stop");
|
|
8495
8510
|
}
|
|
8496
|
-
return new Promise((
|
|
8511
|
+
return new Promise((resolve9) => {
|
|
8497
8512
|
let resolved = false;
|
|
8498
8513
|
const respond = (d) => {
|
|
8499
8514
|
if (resolved) return;
|
|
8500
8515
|
resolved = true;
|
|
8501
|
-
|
|
8516
|
+
resolve9(d);
|
|
8502
8517
|
};
|
|
8503
8518
|
const fallback = setTimeout(
|
|
8504
8519
|
() => respond("stop"),
|
|
@@ -11539,7 +11554,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
11539
11554
|
taskIds.map((id) => {
|
|
11540
11555
|
const cached = this.completedResults.find((r) => r.taskId === id);
|
|
11541
11556
|
if (cached) return cached;
|
|
11542
|
-
return new Promise((
|
|
11557
|
+
return new Promise((resolve9, reject) => {
|
|
11543
11558
|
const timeout = setTimeout(() => {
|
|
11544
11559
|
this.off("task.completed", handler);
|
|
11545
11560
|
reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
|
|
@@ -11548,7 +11563,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
11548
11563
|
if (result.taskId === id) {
|
|
11549
11564
|
clearTimeout(timeout);
|
|
11550
11565
|
this.off("task.completed", handler);
|
|
11551
|
-
|
|
11566
|
+
resolve9(result);
|
|
11552
11567
|
}
|
|
11553
11568
|
};
|
|
11554
11569
|
this.on("task.completed", handler);
|
|
@@ -11978,7 +11993,7 @@ function providerErrorToSubagentError(err, message, cause) {
|
|
|
11978
11993
|
|
|
11979
11994
|
// src/execution/parallel-eternal-engine.ts
|
|
11980
11995
|
function sleep2(ms) {
|
|
11981
|
-
return new Promise((
|
|
11996
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
11982
11997
|
}
|
|
11983
11998
|
var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
|
|
11984
11999
|
var ParallelEternalEngine = class {
|
|
@@ -13620,11 +13635,11 @@ var Director = class {
|
|
|
13620
13635
|
if (cached) return cached;
|
|
13621
13636
|
const existing = this.taskWaiters.get(id);
|
|
13622
13637
|
if (existing) return existing.promise;
|
|
13623
|
-
let
|
|
13638
|
+
let resolve9;
|
|
13624
13639
|
const promise = new Promise((res) => {
|
|
13625
|
-
|
|
13640
|
+
resolve9 = res;
|
|
13626
13641
|
});
|
|
13627
|
-
this.taskWaiters.set(id, { promise, resolve:
|
|
13642
|
+
this.taskWaiters.set(id, { promise, resolve: resolve9 });
|
|
13628
13643
|
return promise;
|
|
13629
13644
|
})
|
|
13630
13645
|
);
|
|
@@ -13940,7 +13955,7 @@ function createDelegateTool(opts) {
|
|
|
13940
13955
|
subagentId
|
|
13941
13956
|
});
|
|
13942
13957
|
const dir = director;
|
|
13943
|
-
const result = await new Promise((
|
|
13958
|
+
const result = await new Promise((resolve9) => {
|
|
13944
13959
|
let settled = false;
|
|
13945
13960
|
let timer;
|
|
13946
13961
|
const finish = (value) => {
|
|
@@ -13949,7 +13964,7 @@ function createDelegateTool(opts) {
|
|
|
13949
13964
|
if (timer) clearTimeout(timer);
|
|
13950
13965
|
offTool();
|
|
13951
13966
|
offIter();
|
|
13952
|
-
|
|
13967
|
+
resolve9(value);
|
|
13953
13968
|
};
|
|
13954
13969
|
const arm = () => {
|
|
13955
13970
|
if (timer) clearTimeout(timer);
|
|
@@ -17092,9 +17107,9 @@ var DefaultHealthRegistry = class {
|
|
|
17092
17107
|
}
|
|
17093
17108
|
async runOne(check) {
|
|
17094
17109
|
let timer = null;
|
|
17095
|
-
const timeout = new Promise((
|
|
17110
|
+
const timeout = new Promise((resolve9) => {
|
|
17096
17111
|
timer = setTimeout(
|
|
17097
|
-
() =>
|
|
17112
|
+
() => resolve9({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
|
|
17098
17113
|
this.timeoutMs
|
|
17099
17114
|
);
|
|
17100
17115
|
});
|
|
@@ -17333,14 +17348,14 @@ async function startMetricsServer(opts) {
|
|
|
17333
17348
|
const { createServer } = await import('http');
|
|
17334
17349
|
server = createServer(listener);
|
|
17335
17350
|
}
|
|
17336
|
-
await new Promise((
|
|
17351
|
+
await new Promise((resolve9, reject) => {
|
|
17337
17352
|
const onError = (err) => {
|
|
17338
17353
|
server.off("listening", onListening);
|
|
17339
17354
|
reject(err);
|
|
17340
17355
|
};
|
|
17341
17356
|
const onListening = () => {
|
|
17342
17357
|
server.off("error", onError);
|
|
17343
|
-
|
|
17358
|
+
resolve9();
|
|
17344
17359
|
};
|
|
17345
17360
|
server.once("error", onError);
|
|
17346
17361
|
server.once("listening", onListening);
|
|
@@ -17352,8 +17367,8 @@ async function startMetricsServer(opts) {
|
|
|
17352
17367
|
return {
|
|
17353
17368
|
port: boundPort,
|
|
17354
17369
|
url: `${protocol}://${host}:${boundPort}${path28}`,
|
|
17355
|
-
close: () => new Promise((
|
|
17356
|
-
server.close((err) => err ? reject(err) :
|
|
17370
|
+
close: () => new Promise((resolve9, reject) => {
|
|
17371
|
+
server.close((err) => err ? reject(err) : resolve9());
|
|
17357
17372
|
})
|
|
17358
17373
|
};
|
|
17359
17374
|
}
|
|
@@ -18449,10 +18464,12 @@ async function collectFiles(dir, baseDir) {
|
|
|
18449
18464
|
// src/storage/session-rewinder.ts
|
|
18450
18465
|
init_atomic_write();
|
|
18451
18466
|
var DefaultSessionRewinder = class {
|
|
18452
|
-
constructor(sessionsDir) {
|
|
18467
|
+
constructor(sessionsDir, projectRoot) {
|
|
18453
18468
|
this.sessionsDir = sessionsDir;
|
|
18469
|
+
this.projectRoot = projectRoot;
|
|
18454
18470
|
}
|
|
18455
18471
|
sessionsDir;
|
|
18472
|
+
projectRoot;
|
|
18456
18473
|
async listCheckpoints(sessionId) {
|
|
18457
18474
|
const file = path6.join(this.sessionsDir, `${sessionId}.jsonl`);
|
|
18458
18475
|
const raw = await fsp2.readFile(file, "utf8");
|
|
@@ -18509,7 +18526,7 @@ var DefaultSessionRewinder = class {
|
|
|
18509
18526
|
}
|
|
18510
18527
|
}
|
|
18511
18528
|
}
|
|
18512
|
-
const result = await revertSnapshots(snapshotsToRevert);
|
|
18529
|
+
const result = await revertSnapshots(snapshotsToRevert, this.projectRoot);
|
|
18513
18530
|
const removedEvents = events.length - targetIdx - 1;
|
|
18514
18531
|
return { ...result, toPromptIndex: checkpointIndex, removedEvents };
|
|
18515
18532
|
}
|
|
@@ -18539,7 +18556,7 @@ var DefaultSessionRewinder = class {
|
|
|
18539
18556
|
snapshotsToRevert.push({ promptIndex: event.promptIndex, files: event.files });
|
|
18540
18557
|
}
|
|
18541
18558
|
}
|
|
18542
|
-
const result = await revertSnapshots(snapshotsToRevert.reverse());
|
|
18559
|
+
const result = await revertSnapshots(snapshotsToRevert.reverse(), this.projectRoot);
|
|
18543
18560
|
return { ...result, toPromptIndex: targetIndex, removedEvents: snapshotsToRevert.length };
|
|
18544
18561
|
}
|
|
18545
18562
|
async rewindToStart(sessionId) {
|
|
@@ -18555,7 +18572,7 @@ var DefaultSessionRewinder = class {
|
|
|
18555
18572
|
if (allSnapshots.length === 0) {
|
|
18556
18573
|
return { revertedFiles: [], errors: [], toPromptIndex: 0, removedEvents: 0 };
|
|
18557
18574
|
}
|
|
18558
|
-
const result = await revertSnapshots(allSnapshots.reverse());
|
|
18575
|
+
const result = await revertSnapshots(allSnapshots.reverse(), this.projectRoot);
|
|
18559
18576
|
return { ...result, toPromptIndex: 0, removedEvents: allSnapshots.length };
|
|
18560
18577
|
}
|
|
18561
18578
|
};
|
|
@@ -18573,12 +18590,19 @@ function parseEvents(raw) {
|
|
|
18573
18590
|
}
|
|
18574
18591
|
return events;
|
|
18575
18592
|
}
|
|
18576
|
-
async function revertSnapshots(snapshots) {
|
|
18593
|
+
async function revertSnapshots(snapshots, projectRoot) {
|
|
18577
18594
|
const revertedFiles = [];
|
|
18578
18595
|
const errors = [];
|
|
18579
18596
|
for (const snapshot of snapshots) {
|
|
18580
18597
|
for (const file of snapshot.files) {
|
|
18581
18598
|
try {
|
|
18599
|
+
const absPath = path6.resolve(file.path);
|
|
18600
|
+
const root = path6.resolve(projectRoot);
|
|
18601
|
+
const rel = path6.relative(root, absPath);
|
|
18602
|
+
if (rel.startsWith("..") || path6.isAbsolute(rel)) {
|
|
18603
|
+
errors.push(`${file.path}: path resolves outside project root \u2014 skipping`);
|
|
18604
|
+
continue;
|
|
18605
|
+
}
|
|
18582
18606
|
if (file.action === "deleted") {
|
|
18583
18607
|
if (file.before !== null) {
|
|
18584
18608
|
await atomicWrite(file.path, file.before, { mode: 420 });
|
|
@@ -19754,7 +19778,7 @@ var SecurityScannerOrchestrator = class {
|
|
|
19754
19778
|
const delay = Math.round(policy.delayMs(attempt));
|
|
19755
19779
|
const status = isProviderErr ? err.status : 0;
|
|
19756
19780
|
console.warn(`[SecurityScanner] retry ${attempt + 1} after ${delay}ms (status=${status}) \u2014 ${errAsErr.message}`);
|
|
19757
|
-
await new Promise((
|
|
19781
|
+
await new Promise((resolve9) => setTimeout(resolve9, delay));
|
|
19758
19782
|
return this.completeWithRetry(provider, request, abortController, attempt + 1);
|
|
19759
19783
|
}
|
|
19760
19784
|
}
|
|
@@ -21251,12 +21275,12 @@ function makeContinueToNextIterationTool() {
|
|
|
21251
21275
|
// src/core/iteration-limit.ts
|
|
21252
21276
|
function requestLimitExtension(opts) {
|
|
21253
21277
|
const { events, currentIterations, currentLimit, autoExtend, timeoutMs = 3e4 } = opts;
|
|
21254
|
-
return new Promise((
|
|
21278
|
+
return new Promise((resolve9) => {
|
|
21255
21279
|
let resolved = false;
|
|
21256
21280
|
const timerFired = () => {
|
|
21257
21281
|
if (!resolved) {
|
|
21258
21282
|
resolved = true;
|
|
21259
|
-
|
|
21283
|
+
resolve9(0);
|
|
21260
21284
|
}
|
|
21261
21285
|
};
|
|
21262
21286
|
const timer = setTimeout(timerFired, timeoutMs);
|
|
@@ -21265,14 +21289,14 @@ function requestLimitExtension(opts) {
|
|
|
21265
21289
|
if (!resolved) {
|
|
21266
21290
|
resolved = true;
|
|
21267
21291
|
clearTimeout(timer);
|
|
21268
|
-
|
|
21292
|
+
resolve9(0);
|
|
21269
21293
|
}
|
|
21270
21294
|
};
|
|
21271
21295
|
const grant = (extra) => {
|
|
21272
21296
|
if (!resolved) {
|
|
21273
21297
|
resolved = true;
|
|
21274
21298
|
clearTimeout(timer);
|
|
21275
|
-
|
|
21299
|
+
resolve9(Math.max(0, extra));
|
|
21276
21300
|
}
|
|
21277
21301
|
};
|
|
21278
21302
|
events.emit("iteration.limit_reached", {
|
|
@@ -21286,7 +21310,7 @@ function requestLimitExtension(opts) {
|
|
|
21286
21310
|
if (!resolved) {
|
|
21287
21311
|
resolved = true;
|
|
21288
21312
|
clearTimeout(timer);
|
|
21289
|
-
|
|
21313
|
+
resolve9(100);
|
|
21290
21314
|
}
|
|
21291
21315
|
});
|
|
21292
21316
|
}
|
|
@@ -21855,13 +21879,13 @@ var Agent = class {
|
|
|
21855
21879
|
}
|
|
21856
21880
|
}
|
|
21857
21881
|
waitForConfirm(info) {
|
|
21858
|
-
return new Promise((
|
|
21882
|
+
return new Promise((resolve9) => {
|
|
21859
21883
|
this.events.emit("tool.confirm_needed", {
|
|
21860
21884
|
tool: info.tool,
|
|
21861
21885
|
input: info.input,
|
|
21862
21886
|
toolUseId: info.toolUseId,
|
|
21863
21887
|
suggestedPattern: info.suggestedPattern,
|
|
21864
|
-
resolve:
|
|
21888
|
+
resolve: resolve9
|
|
21865
21889
|
});
|
|
21866
21890
|
});
|
|
21867
21891
|
}
|
|
@@ -22578,12 +22602,12 @@ ${mem}`);
|
|
|
22578
22602
|
}
|
|
22579
22603
|
}
|
|
22580
22604
|
async gitStatus(root) {
|
|
22581
|
-
return new Promise((
|
|
22605
|
+
return new Promise((resolve9) => {
|
|
22582
22606
|
let settled = false;
|
|
22583
22607
|
const finish = (s) => {
|
|
22584
22608
|
if (settled) return;
|
|
22585
22609
|
settled = true;
|
|
22586
|
-
|
|
22610
|
+
resolve9(s);
|
|
22587
22611
|
};
|
|
22588
22612
|
let proc;
|
|
22589
22613
|
const timer = setTimeout(() => {
|
|
@@ -23941,7 +23965,7 @@ var PhaseOrchestrator = class {
|
|
|
23941
23965
|
};
|
|
23942
23966
|
}
|
|
23943
23967
|
delay(ms) {
|
|
23944
|
-
return new Promise((
|
|
23968
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
23945
23969
|
}
|
|
23946
23970
|
};
|
|
23947
23971
|
|
|
@@ -24609,7 +24633,11 @@ var WorktreeManager = class {
|
|
|
24609
24633
|
const slug = this.makeSlug(opts.slugHint ?? ownerId);
|
|
24610
24634
|
const branch = `wstack/ap/${slug}`;
|
|
24611
24635
|
const dir = join(this.worktreesRoot(), slug);
|
|
24612
|
-
|
|
24636
|
+
const absDir = resolve(dir);
|
|
24637
|
+
const absRoot = resolve(this.projectRoot);
|
|
24638
|
+
if (!absDir.startsWith(absRoot + sep)) {
|
|
24639
|
+
throw new Error(`Worktree dir "${absDir}" resolves outside project root`);
|
|
24640
|
+
}
|
|
24613
24641
|
const baseBranch = opts.baseBranch ?? await this.detectBaseBranch();
|
|
24614
24642
|
const handle = {
|
|
24615
24643
|
id: slug,
|
|
@@ -24660,7 +24688,8 @@ var WorktreeManager = class {
|
|
|
24660
24688
|
this.emitCommitted(handle, false);
|
|
24661
24689
|
return { committed: false };
|
|
24662
24690
|
}
|
|
24663
|
-
const
|
|
24691
|
+
const idArgs = await this.identityArgs(handle.dir);
|
|
24692
|
+
const committed = await this.runGit([...idArgs, "commit", "-m", message], handle.dir);
|
|
24664
24693
|
if (committed.code !== 0) {
|
|
24665
24694
|
this.fail(handle, committed.stderr || "git commit failed");
|
|
24666
24695
|
return { committed: false };
|
|
@@ -24686,7 +24715,10 @@ var WorktreeManager = class {
|
|
|
24686
24715
|
const mergeArgs = squash ? ["merge", "--squash", handle.branch] : ["merge", "--no-ff", handle.branch];
|
|
24687
24716
|
const merged = await this.runGit(mergeArgs, this.projectRoot);
|
|
24688
24717
|
if (merged.code !== 0) {
|
|
24689
|
-
const
|
|
24718
|
+
const fromOutput = parseConflictPaths(`${merged.stdout}
|
|
24719
|
+
${merged.stderr}`);
|
|
24720
|
+
const fromIndex = await this.unmergedFiles();
|
|
24721
|
+
const conflictFiles = [.../* @__PURE__ */ new Set([...fromOutput, ...fromIndex])];
|
|
24690
24722
|
await this.runGit(["reset", "--hard", "HEAD"], this.projectRoot);
|
|
24691
24723
|
handle.conflictFiles = conflictFiles;
|
|
24692
24724
|
this.setStatus(handle, "needs-review", { lastError: merged.stderr });
|
|
@@ -24700,7 +24732,8 @@ var WorktreeManager = class {
|
|
|
24700
24732
|
}
|
|
24701
24733
|
if (squash) {
|
|
24702
24734
|
const msg = opts.message ?? `merge ${handle.branch} (squash)`;
|
|
24703
|
-
const
|
|
24735
|
+
const idArgs = await this.identityArgs(this.projectRoot);
|
|
24736
|
+
const commit = await this.runGit([...idArgs, "commit", "-m", msg], this.projectRoot);
|
|
24704
24737
|
if (commit.code !== 0 && !/nothing to commit/i.test(commit.stdout + commit.stderr)) {
|
|
24705
24738
|
this.fail(handle, commit.stderr || "squash commit failed");
|
|
24706
24739
|
return { ok: false, stderr: commit.stderr };
|
|
@@ -24775,11 +24808,27 @@ var WorktreeManager = class {
|
|
|
24775
24808
|
}
|
|
24776
24809
|
return { insertions, deletions, files, sha };
|
|
24777
24810
|
}
|
|
24811
|
+
/**
|
|
24812
|
+
* `git -c user.*` fallback so commits succeed on machines and CI runners
|
|
24813
|
+
* that have no global git identity configured. Returns `[]` when both
|
|
24814
|
+
* `user.name` and `user.email` are already set (the common case), so a real
|
|
24815
|
+
* user's identity is never overridden. The worktree branch commits are
|
|
24816
|
+
* squashed away on merge, so the fallback identity never reaches the base
|
|
24817
|
+
* branch history.
|
|
24818
|
+
*/
|
|
24819
|
+
async identityArgs(cwd) {
|
|
24820
|
+
const name = (await this.runGit(["config", "user.name"], cwd)).stdout.trim();
|
|
24821
|
+
const email = (await this.runGit(["config", "user.email"], cwd)).stdout.trim();
|
|
24822
|
+
if (name && email) return [];
|
|
24823
|
+
return [
|
|
24824
|
+
"-c",
|
|
24825
|
+
`user.name=${name || "WrongStack AutoPhase"}`,
|
|
24826
|
+
"-c",
|
|
24827
|
+
`user.email=${email || "autophase@wrongstack.local"}`
|
|
24828
|
+
];
|
|
24829
|
+
}
|
|
24778
24830
|
async unmergedFiles() {
|
|
24779
|
-
const res = await this.runGit(
|
|
24780
|
-
["diff", "--name-only", "--diff-filter=U"],
|
|
24781
|
-
this.projectRoot
|
|
24782
|
-
);
|
|
24831
|
+
const res = await this.runGit(["diff", "--name-only", "--diff-filter=U"], this.projectRoot);
|
|
24783
24832
|
return res.stdout.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
24784
24833
|
}
|
|
24785
24834
|
emitCommitted(handle, committed) {
|
|
@@ -24832,6 +24881,14 @@ var WorktreeManager = class {
|
|
|
24832
24881
|
});
|
|
24833
24882
|
}
|
|
24834
24883
|
};
|
|
24884
|
+
function parseConflictPaths(output) {
|
|
24885
|
+
const paths = /* @__PURE__ */ new Set();
|
|
24886
|
+
for (const line of output.split("\n")) {
|
|
24887
|
+
const m = line.match(/^CONFLICT \([^)]*\): Merge conflict in (.+?)\s*$/);
|
|
24888
|
+
if (m?.[1]) paths.add(m[1]);
|
|
24889
|
+
}
|
|
24890
|
+
return [...paths];
|
|
24891
|
+
}
|
|
24835
24892
|
function assertSafePath(dir, projectRoot) {
|
|
24836
24893
|
const root = resolve(projectRoot);
|
|
24837
24894
|
const abs = resolve(dir);
|