@buildautomaton/cli 0.1.21 → 0.1.23
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/cli.js +3861 -3787
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1156 -1082
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23088,7 +23088,7 @@ function installBridgeProcessResilience() {
|
|
|
23088
23088
|
}
|
|
23089
23089
|
|
|
23090
23090
|
// src/cli-version.ts
|
|
23091
|
-
var CLI_VERSION = "0.1.
|
|
23091
|
+
var CLI_VERSION = "0.1.23".length > 0 ? "0.1.23" : "0.0.0-dev";
|
|
23092
23092
|
|
|
23093
23093
|
// ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
|
|
23094
23094
|
import process7 from "node:process";
|
|
@@ -24006,330 +24006,757 @@ function resolveSessionParentPathForAgentProcess(resolvedSessionParentPath) {
|
|
|
24006
24006
|
return getBridgeRoot();
|
|
24007
24007
|
}
|
|
24008
24008
|
|
|
24009
|
-
// src/
|
|
24010
|
-
|
|
24011
|
-
|
|
24012
|
-
|
|
24013
|
-
|
|
24009
|
+
// ../types/src/work-items.ts
|
|
24010
|
+
init_zod();
|
|
24011
|
+
var WorkItemStatusSchema = external_exports.enum(["backlog", "in-progress", "completed"]);
|
|
24012
|
+
var WorkItemProgressSchema = external_exports.object({
|
|
24013
|
+
remainingCriteria: external_exports.array(external_exports.string()).default([]),
|
|
24014
|
+
openQuestions: external_exports.array(external_exports.string()).default([]),
|
|
24015
|
+
assignedTo: external_exports.enum(["agent", "human-product", "human-expert"]).optional()
|
|
24016
|
+
});
|
|
24017
|
+
var ChangeSchema = external_exports.object({
|
|
24018
|
+
id: external_exports.string(),
|
|
24019
|
+
description: external_exports.string(),
|
|
24020
|
+
buildingBlockId: external_exports.string(),
|
|
24021
|
+
buildingBlockType: external_exports.enum(["function", "workflow", "connector", "ui-component", "app-fragment", "application", "project"]),
|
|
24022
|
+
action: external_exports.enum(["create", "update", "split", "combine"])
|
|
24023
|
+
});
|
|
24024
|
+
var CompletionCriterionSchema = external_exports.object({
|
|
24025
|
+
id: external_exports.string(),
|
|
24026
|
+
description: external_exports.string(),
|
|
24027
|
+
type: external_exports.enum(["write-code", "write-tests", "verify-tests", "other"]),
|
|
24028
|
+
verified: external_exports.boolean().default(false)
|
|
24029
|
+
});
|
|
24030
|
+
var WorkItemPrioritySchema = external_exports.enum(["low", "medium", "high", "critical"]);
|
|
24031
|
+
var IterationPhaseSchema = external_exports.enum(["analysis", "implementation", "verify", "reprioritize", "completed"]);
|
|
24032
|
+
var WorkItemDependencySchema = external_exports.object({
|
|
24033
|
+
type: external_exports.enum(["work-item"]),
|
|
24034
|
+
id: external_exports.string()
|
|
24035
|
+
});
|
|
24036
|
+
var WorkItemSchema = external_exports.object({
|
|
24037
|
+
id: external_exports.string(),
|
|
24038
|
+
sessionId: external_exports.string().optional(),
|
|
24039
|
+
summary: external_exports.string().optional(),
|
|
24040
|
+
description: external_exports.string(),
|
|
24041
|
+
status: WorkItemStatusSchema,
|
|
24042
|
+
buildingBlockId: external_exports.string().optional(),
|
|
24043
|
+
buildingBlockType: external_exports.enum(["function", "workflow", "connector", "ui-component", "app-fragment", "application", "project"]),
|
|
24044
|
+
changes: external_exports.array(ChangeSchema).default([]),
|
|
24045
|
+
completionCriteria: external_exports.array(CompletionCriterionSchema).default([]),
|
|
24046
|
+
priority: WorkItemPrioritySchema.default("medium"),
|
|
24047
|
+
dependencies: external_exports.array(WorkItemDependencySchema).default([]),
|
|
24048
|
+
assignedToUserId: external_exports.string().optional()
|
|
24049
|
+
});
|
|
24014
24050
|
|
|
24015
|
-
// src/
|
|
24016
|
-
|
|
24017
|
-
|
|
24018
|
-
|
|
24019
|
-
|
|
24051
|
+
// ../types/src/user-profiles.ts
|
|
24052
|
+
init_zod();
|
|
24053
|
+
var UserWorkspaceProfileSchema = external_exports.object({
|
|
24054
|
+
id: external_exports.string(),
|
|
24055
|
+
workspaceId: external_exports.string(),
|
|
24056
|
+
userId: external_exports.string(),
|
|
24057
|
+
roleDescription: external_exports.string().optional(),
|
|
24058
|
+
expertiseAreas: external_exports.array(external_exports.string()),
|
|
24059
|
+
preferences: external_exports.record(external_exports.unknown()).optional(),
|
|
24060
|
+
learnings: external_exports.array(external_exports.string())
|
|
24061
|
+
});
|
|
24020
24062
|
|
|
24021
|
-
// src/
|
|
24022
|
-
|
|
24023
|
-
|
|
24063
|
+
// ../types/src/runtime.ts
|
|
24064
|
+
init_zod();
|
|
24065
|
+
var WorkspaceOwnerInfoSchema = external_exports.object({
|
|
24066
|
+
ownerId: external_exports.string(),
|
|
24067
|
+
ownerName: external_exports.string().optional(),
|
|
24068
|
+
ownerEmail: external_exports.string().optional(),
|
|
24069
|
+
ownerProfilePictureUrl: external_exports.string().optional()
|
|
24070
|
+
});
|
|
24071
|
+
var WorkspaceRuntimeEntrySchema = external_exports.object({
|
|
24072
|
+
workspaceId: external_exports.string(),
|
|
24073
|
+
path: external_exports.string(),
|
|
24074
|
+
name: external_exports.string().optional(),
|
|
24075
|
+
owner: WorkspaceOwnerInfoSchema.optional(),
|
|
24076
|
+
isOwner: external_exports.boolean().optional()
|
|
24077
|
+
});
|
|
24024
24078
|
|
|
24025
|
-
//
|
|
24026
|
-
|
|
24027
|
-
var
|
|
24028
|
-
|
|
24029
|
-
|
|
24030
|
-
|
|
24031
|
-
import { spawn as spawn3 } from "child_process";
|
|
24032
|
-
import { normalize as normalize2 } from "node:path";
|
|
24033
|
-
import { EventEmitter } from "node:events";
|
|
24034
|
-
var __defProp2 = Object.defineProperty;
|
|
24035
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
24036
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
24037
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
24038
|
-
var __esm2 = (fn, res) => function __init() {
|
|
24039
|
-
return fn && (res = (0, fn[__getOwnPropNames2(fn)[0]])(fn = 0)), res;
|
|
24040
|
-
};
|
|
24041
|
-
var __commonJS2 = (cb, mod) => function __require2() {
|
|
24042
|
-
return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
24043
|
-
};
|
|
24044
|
-
var __export2 = (target, all) => {
|
|
24045
|
-
for (var name in all)
|
|
24046
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
24047
|
-
};
|
|
24048
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
24049
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
24050
|
-
for (let key of __getOwnPropNames2(from))
|
|
24051
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
24052
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
24053
|
-
}
|
|
24054
|
-
return to;
|
|
24055
|
-
};
|
|
24056
|
-
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
24057
|
-
function pathspec(...paths) {
|
|
24058
|
-
const key = new String(paths);
|
|
24059
|
-
cache.set(key, paths);
|
|
24060
|
-
return key;
|
|
24061
|
-
}
|
|
24062
|
-
function isPathSpec(path34) {
|
|
24063
|
-
return path34 instanceof String && cache.has(path34);
|
|
24064
|
-
}
|
|
24065
|
-
function toPaths(pathSpec) {
|
|
24066
|
-
return cache.get(pathSpec) || [];
|
|
24067
|
-
}
|
|
24068
|
-
var cache;
|
|
24069
|
-
var init_pathspec = __esm2({
|
|
24070
|
-
"src/lib/args/pathspec.ts"() {
|
|
24071
|
-
"use strict";
|
|
24072
|
-
cache = /* @__PURE__ */ new WeakMap();
|
|
24073
|
-
}
|
|
24079
|
+
// ../types/src/agent.ts
|
|
24080
|
+
init_zod();
|
|
24081
|
+
var ProjectContextSchema = external_exports.object({
|
|
24082
|
+
projectId: external_exports.string(),
|
|
24083
|
+
context: external_exports.record(external_exports.unknown()).default({}),
|
|
24084
|
+
updatedAt: external_exports.string()
|
|
24074
24085
|
});
|
|
24075
|
-
var
|
|
24076
|
-
|
|
24077
|
-
"
|
|
24078
|
-
|
|
24079
|
-
|
|
24080
|
-
|
|
24081
|
-
|
|
24082
|
-
|
|
24083
|
-
|
|
24084
|
-
|
|
24085
|
-
|
|
24086
|
-
|
|
24086
|
+
var WebSocketMessageTypeSchema = external_exports.enum([
|
|
24087
|
+
"plan-update",
|
|
24088
|
+
"work-item-update",
|
|
24089
|
+
"work-item-added",
|
|
24090
|
+
"work-item-removed",
|
|
24091
|
+
"project-processing-start",
|
|
24092
|
+
"project-processing-update",
|
|
24093
|
+
"project-processing-complete",
|
|
24094
|
+
"project-processing-error",
|
|
24095
|
+
"file-tool-request",
|
|
24096
|
+
"file-tool-response",
|
|
24097
|
+
"file-generated"
|
|
24098
|
+
]);
|
|
24099
|
+
var WebSocketMessageSchema = external_exports.object({
|
|
24100
|
+
type: WebSocketMessageTypeSchema,
|
|
24101
|
+
contextId: external_exports.string().optional(),
|
|
24102
|
+
data: external_exports.any().optional(),
|
|
24103
|
+
error: external_exports.string().optional()
|
|
24087
24104
|
});
|
|
24088
|
-
|
|
24089
|
-
|
|
24090
|
-
|
|
24091
|
-
|
|
24092
|
-
|
|
24093
|
-
|
|
24094
|
-
|
|
24095
|
-
|
|
24096
|
-
|
|
24097
|
-
|
|
24098
|
-
|
|
24099
|
-
|
|
24105
|
+
|
|
24106
|
+
// ../types/src/checkpoints.ts
|
|
24107
|
+
init_zod();
|
|
24108
|
+
var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
|
|
24109
|
+
var CheckpointSummarySchema = external_exports.object({
|
|
24110
|
+
id: external_exports.string(),
|
|
24111
|
+
kind: CheckpointKindSchema,
|
|
24112
|
+
/** ISO date for daily (YYYY-MM-DD), ISO week for weekly, null for overall */
|
|
24113
|
+
periodKey: external_exports.string().nullable(),
|
|
24114
|
+
summary: external_exports.string(),
|
|
24115
|
+
createdAt: external_exports.string(),
|
|
24116
|
+
updatedAt: external_exports.string()
|
|
24100
24117
|
});
|
|
24101
|
-
|
|
24102
|
-
|
|
24103
|
-
|
|
24104
|
-
|
|
24105
|
-
|
|
24106
|
-
|
|
24107
|
-
|
|
24108
|
-
|
|
24109
|
-
|
|
24110
|
-
|
|
24111
|
-
|
|
24118
|
+
|
|
24119
|
+
// ../types/src/threads.ts
|
|
24120
|
+
init_zod();
|
|
24121
|
+
var ThreadMetaSchema = external_exports.object({
|
|
24122
|
+
threadId: external_exports.string(),
|
|
24123
|
+
workspaceId: external_exports.string(),
|
|
24124
|
+
/** External source (e.g. slack, discord); null if internal-only */
|
|
24125
|
+
externalSource: external_exports.string().nullable(),
|
|
24126
|
+
/** Id in the external system (e.g. channel_id + thread_ts) */
|
|
24127
|
+
externalId: external_exports.string().nullable(),
|
|
24128
|
+
title: external_exports.string().optional(),
|
|
24129
|
+
createdAt: external_exports.string(),
|
|
24130
|
+
updatedAt: external_exports.string()
|
|
24112
24131
|
});
|
|
24113
|
-
|
|
24114
|
-
|
|
24115
|
-
|
|
24116
|
-
|
|
24117
|
-
|
|
24118
|
-
|
|
24119
|
-
|
|
24120
|
-
|
|
24121
|
-
|
|
24122
|
-
|
|
24123
|
-
|
|
24124
|
-
|
|
24125
|
-
|
|
24126
|
-
|
|
24127
|
-
|
|
24128
|
-
}
|
|
24129
|
-
|
|
24130
|
-
|
|
24131
|
-
|
|
24132
|
-
|
|
24133
|
-
|
|
24134
|
-
|
|
24135
|
-
|
|
24136
|
-
|
|
24137
|
-
|
|
24138
|
-
|
|
24139
|
-
|
|
24140
|
-
|
|
24141
|
-
|
|
24142
|
-
|
|
24143
|
-
|
|
24144
|
-
|
|
24145
|
-
|
|
24146
|
-
|
|
24147
|
-
|
|
24148
|
-
|
|
24149
|
-
|
|
24150
|
-
|
|
24151
|
-
|
|
24152
|
-
|
|
24153
|
-
|
|
24154
|
-
|
|
24155
|
-
|
|
24156
|
-
|
|
24157
|
-
|
|
24158
|
-
|
|
24159
|
-
|
|
24160
|
-
|
|
24161
|
-
|
|
24162
|
-
|
|
24163
|
-
|
|
24164
|
-
}
|
|
24165
|
-
|
|
24166
|
-
|
|
24167
|
-
|
|
24168
|
-
|
|
24169
|
-
|
|
24170
|
-
|
|
24171
|
-
|
|
24172
|
-
|
|
24173
|
-
|
|
24174
|
-
|
|
24175
|
-
|
|
24176
|
-
|
|
24177
|
-
|
|
24178
|
-
|
|
24179
|
-
|
|
24180
|
-
|
|
24181
|
-
|
|
24182
|
-
|
|
24183
|
-
|
|
24184
|
-
|
|
24185
|
-
|
|
24186
|
-
|
|
24187
|
-
|
|
24188
|
-
|
|
24189
|
-
|
|
24190
|
-
|
|
24191
|
-
|
|
24192
|
-
|
|
24193
|
-
|
|
24132
|
+
var ThreadMessageSchema = external_exports.object({
|
|
24133
|
+
messageId: external_exports.string(),
|
|
24134
|
+
threadId: external_exports.string(),
|
|
24135
|
+
/** Role: user, assistant, system */
|
|
24136
|
+
role: external_exports.enum(["user", "assistant", "system"]),
|
|
24137
|
+
content: external_exports.string(),
|
|
24138
|
+
/** Optional reference to a ContentItem (e.g. doc, Notion page) */
|
|
24139
|
+
contentItemId: external_exports.string().nullable(),
|
|
24140
|
+
/** External message id if synced from external chat */
|
|
24141
|
+
externalId: external_exports.string().nullable(),
|
|
24142
|
+
createdAt: external_exports.string(),
|
|
24143
|
+
updatedAt: external_exports.string()
|
|
24144
|
+
});
|
|
24145
|
+
var ThreadCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
24146
|
+
threadId: external_exports.string()
|
|
24147
|
+
});
|
|
24148
|
+
|
|
24149
|
+
// ../types/src/content-items.ts
|
|
24150
|
+
init_zod();
|
|
24151
|
+
var ContentSourceSchema = external_exports.enum(["notion", "doc", "slack_thread", "other"]);
|
|
24152
|
+
var ContentItemMetaSchema = external_exports.object({
|
|
24153
|
+
contentId: external_exports.string(),
|
|
24154
|
+
workspaceId: external_exports.string(),
|
|
24155
|
+
source: ContentSourceSchema,
|
|
24156
|
+
/** Id in the external system (e.g. Notion page id, doc url) */
|
|
24157
|
+
externalId: external_exports.string(),
|
|
24158
|
+
/** If source is slack_thread, points to Thread DO id */
|
|
24159
|
+
threadId: external_exports.string().nullable(),
|
|
24160
|
+
title: external_exports.string().optional(),
|
|
24161
|
+
createdAt: external_exports.string(),
|
|
24162
|
+
updatedAt: external_exports.string()
|
|
24163
|
+
});
|
|
24164
|
+
var ContentStorageRefSchema = external_exports.object({
|
|
24165
|
+
storageKey: external_exports.string(),
|
|
24166
|
+
/** Optional: mime type or format hint */
|
|
24167
|
+
contentType: external_exports.string().optional()
|
|
24168
|
+
});
|
|
24169
|
+
var ContentCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
24170
|
+
contentId: external_exports.string()
|
|
24171
|
+
});
|
|
24172
|
+
|
|
24173
|
+
// ../types/src/stories.ts
|
|
24174
|
+
init_zod();
|
|
24175
|
+
var StoryMetaSchema = external_exports.object({
|
|
24176
|
+
storyId: external_exports.string(),
|
|
24177
|
+
workspaceId: external_exports.string(),
|
|
24178
|
+
title: external_exports.string(),
|
|
24179
|
+
/** feature | bug | epic */
|
|
24180
|
+
kind: external_exports.enum(["feature", "bug", "epic"]).default("feature"),
|
|
24181
|
+
createdAt: external_exports.string(),
|
|
24182
|
+
updatedAt: external_exports.string()
|
|
24183
|
+
});
|
|
24184
|
+
var StoryContentItemRefSchema = external_exports.object({
|
|
24185
|
+
id: external_exports.string(),
|
|
24186
|
+
storyId: external_exports.string(),
|
|
24187
|
+
contentItemId: external_exports.string(),
|
|
24188
|
+
/** Snapshot summary when added to story (or updated) */
|
|
24189
|
+
summary: external_exports.string(),
|
|
24190
|
+
orderIndex: external_exports.number().default(0),
|
|
24191
|
+
createdAt: external_exports.string(),
|
|
24192
|
+
updatedAt: external_exports.string()
|
|
24193
|
+
});
|
|
24194
|
+
var StoryCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
24195
|
+
storyId: external_exports.string()
|
|
24196
|
+
});
|
|
24197
|
+
|
|
24198
|
+
// ../types/src/sessions.ts
|
|
24199
|
+
init_zod();
|
|
24200
|
+
var BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID = "__builtin_change_summary__";
|
|
24201
|
+
var SessionMetaSchema = external_exports.object({
|
|
24202
|
+
sessionId: external_exports.string(),
|
|
24203
|
+
workspaceId: external_exports.string(),
|
|
24204
|
+
title: external_exports.string().optional(),
|
|
24205
|
+
createdAt: external_exports.string(),
|
|
24206
|
+
updatedAt: external_exports.string()
|
|
24207
|
+
});
|
|
24208
|
+
var SessionPromptSchema = external_exports.object({
|
|
24209
|
+
id: external_exports.string(),
|
|
24210
|
+
sessionId: external_exports.string(),
|
|
24211
|
+
/** text | resource */
|
|
24212
|
+
type: external_exports.enum(["text", "resource"]).default("text"),
|
|
24213
|
+
text: external_exports.string().optional(),
|
|
24214
|
+
resourceUri: external_exports.string().optional(),
|
|
24215
|
+
createdAt: external_exports.string()
|
|
24216
|
+
});
|
|
24217
|
+
var SessionResponseSchema = external_exports.object({
|
|
24218
|
+
id: external_exports.string(),
|
|
24219
|
+
sessionId: external_exports.string(),
|
|
24220
|
+
promptId: external_exports.string(),
|
|
24221
|
+
/** message | completion */
|
|
24222
|
+
kind: external_exports.enum(["message", "completion"]),
|
|
24223
|
+
content: external_exports.string().optional(),
|
|
24224
|
+
/** For completion: stopReason etc. */
|
|
24225
|
+
stopReason: external_exports.string().optional(),
|
|
24226
|
+
createdAt: external_exports.string()
|
|
24227
|
+
});
|
|
24228
|
+
var SessionToolCallSchema = external_exports.object({
|
|
24229
|
+
id: external_exports.string(),
|
|
24230
|
+
sessionId: external_exports.string(),
|
|
24231
|
+
promptId: external_exports.string(),
|
|
24232
|
+
name: external_exports.string(),
|
|
24233
|
+
params: external_exports.record(external_exports.unknown()).optional(),
|
|
24234
|
+
result: external_exports.record(external_exports.unknown()).optional(),
|
|
24235
|
+
createdAt: external_exports.string()
|
|
24236
|
+
});
|
|
24237
|
+
var SessionThreadRefSchema = external_exports.object({
|
|
24238
|
+
sessionId: external_exports.string(),
|
|
24239
|
+
threadId: external_exports.string(),
|
|
24240
|
+
addedAt: external_exports.string()
|
|
24241
|
+
});
|
|
24242
|
+
var USER_ENDED_SESSION_TURN_ERROR_TEXT = "Stopped by user";
|
|
24243
|
+
var LEGACY_USER_ENDED_SESSION_TURN_ERRORS = ["Removed from queue", "Cancelled before start"];
|
|
24244
|
+
function isUserEndedSessionTurnErrorText(errorText) {
|
|
24245
|
+
const raw = (errorText ?? "").trim();
|
|
24246
|
+
if (!raw) return false;
|
|
24247
|
+
const firstLine = raw.split(/\r?\n/)[0]?.trim() ?? "";
|
|
24248
|
+
if (firstLine === USER_ENDED_SESSION_TURN_ERROR_TEXT) return true;
|
|
24249
|
+
if (LEGACY_USER_ENDED_SESSION_TURN_ERRORS.includes(firstLine)) return true;
|
|
24250
|
+
if (raw === USER_ENDED_SESSION_TURN_ERROR_TEXT) return true;
|
|
24251
|
+
return LEGACY_USER_ENDED_SESSION_TURN_ERRORS.includes(raw);
|
|
24194
24252
|
}
|
|
24195
|
-
|
|
24196
|
-
|
|
24197
|
-
|
|
24198
|
-
|
|
24199
|
-
|
|
24200
|
-
return
|
|
24253
|
+
|
|
24254
|
+
// ../types/src/change-summary-path.ts
|
|
24255
|
+
function normalizeRepoRelativePath(p) {
|
|
24256
|
+
let t = p.trim().replace(/\\/g, "/");
|
|
24257
|
+
while (t.startsWith("./")) t = t.slice(2);
|
|
24258
|
+
return t.replace(/\/+/g, "/");
|
|
24201
24259
|
}
|
|
24202
|
-
function
|
|
24203
|
-
const
|
|
24204
|
-
|
|
24205
|
-
|
|
24260
|
+
function resolveChangeSummaryPathAgainstAllowed(rawPath, allowed) {
|
|
24261
|
+
const trimmed2 = rawPath.trim();
|
|
24262
|
+
if (!trimmed2) return null;
|
|
24263
|
+
if (allowed.has(trimmed2)) return trimmed2;
|
|
24264
|
+
const n = normalizeRepoRelativePath(trimmed2);
|
|
24265
|
+
if (allowed.has(n)) return n;
|
|
24266
|
+
for (const a of allowed) {
|
|
24267
|
+
if (normalizeRepoRelativePath(a) === n) return a;
|
|
24206
24268
|
}
|
|
24207
|
-
return
|
|
24269
|
+
return null;
|
|
24208
24270
|
}
|
|
24209
|
-
|
|
24210
|
-
|
|
24271
|
+
|
|
24272
|
+
// ../types/src/parse-change-summary-json.ts
|
|
24273
|
+
function clampSummaryToAtMostTwoLines(summary) {
|
|
24274
|
+
const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
|
|
24275
|
+
return lines.slice(0, 2).join("\n");
|
|
24211
24276
|
}
|
|
24212
|
-
function
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
|
|
24216
|
-
|
|
24277
|
+
function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
24278
|
+
if (raw == null || raw.trim() === "") return [];
|
|
24279
|
+
let text = raw.trim();
|
|
24280
|
+
const fence = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
24281
|
+
if (fence?.[1]) text = fence[1].trim();
|
|
24282
|
+
let parsed;
|
|
24283
|
+
try {
|
|
24284
|
+
parsed = JSON.parse(text);
|
|
24285
|
+
} catch {
|
|
24286
|
+
const start = text.indexOf("[");
|
|
24287
|
+
const end = text.lastIndexOf("]");
|
|
24288
|
+
if (start < 0 || end <= start) return [];
|
|
24289
|
+
try {
|
|
24290
|
+
parsed = JSON.parse(text.slice(start, end + 1));
|
|
24291
|
+
} catch {
|
|
24292
|
+
return [];
|
|
24217
24293
|
}
|
|
24218
|
-
});
|
|
24219
|
-
return out;
|
|
24220
|
-
}
|
|
24221
|
-
function delay(duration3 = 0) {
|
|
24222
|
-
return new Promise((done) => setTimeout(done, duration3));
|
|
24223
|
-
}
|
|
24224
|
-
function orVoid(input) {
|
|
24225
|
-
if (input === false) {
|
|
24226
|
-
return void 0;
|
|
24227
24294
|
}
|
|
24228
|
-
|
|
24229
|
-
|
|
24230
|
-
|
|
24231
|
-
|
|
24232
|
-
|
|
24233
|
-
|
|
24234
|
-
"src/lib/utils/util.ts"() {
|
|
24235
|
-
"use strict";
|
|
24236
|
-
init_argument_filters();
|
|
24237
|
-
NULL = "\0";
|
|
24238
|
-
NOOP = () => {
|
|
24239
|
-
};
|
|
24240
|
-
objectToString = Object.prototype.toString.call.bind(Object.prototype.toString);
|
|
24295
|
+
const rows = [];
|
|
24296
|
+
let arr = [];
|
|
24297
|
+
if (Array.isArray(parsed)) {
|
|
24298
|
+
arr = parsed;
|
|
24299
|
+
} else if (parsed && typeof parsed === "object" && Array.isArray(parsed.files)) {
|
|
24300
|
+
arr = parsed.files;
|
|
24241
24301
|
}
|
|
24242
|
-
|
|
24243
|
-
|
|
24244
|
-
|
|
24245
|
-
|
|
24302
|
+
const skip = options?.skipPathAllowlist === true;
|
|
24303
|
+
for (const item of arr) {
|
|
24304
|
+
if (!item || typeof item !== "object") continue;
|
|
24305
|
+
const o = item;
|
|
24306
|
+
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
24307
|
+
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
24308
|
+
if (!rawPath || !summary) continue;
|
|
24309
|
+
const path34 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
24310
|
+
if (!path34) continue;
|
|
24311
|
+
rows.push({ path: path34, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
24246
24312
|
}
|
|
24247
|
-
return
|
|
24248
|
-
}
|
|
24249
|
-
function filterPrimitives(input, omit2) {
|
|
24250
|
-
const type = isPathSpec(input) ? "string" : typeof input;
|
|
24251
|
-
return /number|string|boolean/.test(type) && (!omit2 || !omit2.includes(type));
|
|
24252
|
-
}
|
|
24253
|
-
function filterPlainObject(input) {
|
|
24254
|
-
return !!input && objectToString(input) === "[object Object]";
|
|
24255
|
-
}
|
|
24256
|
-
function filterFunction(input) {
|
|
24257
|
-
return typeof input === "function";
|
|
24313
|
+
return rows;
|
|
24258
24314
|
}
|
|
24259
|
-
|
|
24260
|
-
|
|
24261
|
-
var
|
|
24262
|
-
|
|
24263
|
-
|
|
24264
|
-
|
|
24265
|
-
|
|
24266
|
-
|
|
24267
|
-
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
|
|
24273
|
-
|
|
24274
|
-
|
|
24275
|
-
|
|
24276
|
-
|
|
24277
|
-
|
|
24278
|
-
|
|
24279
|
-
|
|
24280
|
-
}
|
|
24281
|
-
|
|
24282
|
-
|
|
24283
|
-
|
|
24284
|
-
|
|
24285
|
-
|
|
24286
|
-
|
|
24315
|
+
|
|
24316
|
+
// ../types/src/build-change-summary-prompt.ts
|
|
24317
|
+
var PATCH_PREVIEW_MAX = 12e3;
|
|
24318
|
+
function clip(s, max) {
|
|
24319
|
+
if (s.length <= max) return s;
|
|
24320
|
+
return `${s.slice(0, max)}
|
|
24321
|
+
|
|
24322
|
+
\u2026(truncated, ${s.length - max} more characters)`;
|
|
24323
|
+
}
|
|
24324
|
+
function buildSessionChangeSummaryPrompt(files) {
|
|
24325
|
+
const lines = [
|
|
24326
|
+
"You are the same agent that produced the changes below. Summarize **your own** edits so a reader can scan them quickly.",
|
|
24327
|
+
"",
|
|
24328
|
+
"Write in second person (you / your): what you changed in each path and why it matters.",
|
|
24329
|
+
"",
|
|
24330
|
+
"Each summary must be **very concise**: **one line** of plain text, or **at most two short lines** (use a single line break between the two if needed). No bullets, no paragraphs.",
|
|
24331
|
+
"",
|
|
24332
|
+
"## How to format your reply (machine parsing)",
|
|
24333
|
+
"",
|
|
24334
|
+
"- Put the machine-readable part **only** inside a **markdown fenced code block** whose opening fence is exactly ```json on its own line. Close the block with ``` on its own line after the JSON.",
|
|
24335
|
+
"- Inside that fence: **nothing except** one valid JSON value \u2014 the array described below. No trailing commentary inside the fence.",
|
|
24336
|
+
"- **Do not** attach prose to the JSON on the same line (wrong: `Only one file\u2026page.tsx.[{\u2026}]`). Wrong: any sentence that ends with `.` immediately before `[`. Put a blank line before the ```json line.",
|
|
24337
|
+
"- If you add optional plain English before the fence (e.g. one short sentence), keep it **separate**: end that sentence, blank line, then ```json.",
|
|
24338
|
+
'- In each `"summary"` string, avoid raw double-quote characters, or escape them as `\\"` so the JSON parses.',
|
|
24339
|
+
"",
|
|
24340
|
+
"JSON shape **inside the fence** (array only):",
|
|
24341
|
+
'[{"path":"<file path exactly as given>","summary":"<one line, or two short lines separated by \\n>"}]',
|
|
24342
|
+
"",
|
|
24343
|
+
"Rules:",
|
|
24344
|
+
"- Include **exactly one** object per file path listed below (same path strings).",
|
|
24345
|
+
"- If a path is a removed directory, state briefly what you removed.",
|
|
24346
|
+
"- Do not invent paths; use only the paths provided.",
|
|
24347
|
+
"",
|
|
24348
|
+
"## Files you changed",
|
|
24349
|
+
""
|
|
24350
|
+
];
|
|
24351
|
+
for (const f of files) {
|
|
24352
|
+
lines.push(`### ${f.path}`);
|
|
24353
|
+
if (f.directoryRemoved) {
|
|
24354
|
+
lines.push("(directory removed)");
|
|
24355
|
+
lines.push("");
|
|
24356
|
+
continue;
|
|
24357
|
+
}
|
|
24358
|
+
if (f.patchContent && f.patchContent.trim() !== "") {
|
|
24359
|
+
lines.push("```diff");
|
|
24360
|
+
lines.push(clip(f.patchContent.trim(), PATCH_PREVIEW_MAX));
|
|
24361
|
+
lines.push("```");
|
|
24362
|
+
} else if (f.oldText != null || f.newText != null) {
|
|
24363
|
+
const oldT = (f.oldText ?? "").trim();
|
|
24364
|
+
const newT = (f.newText ?? "").trim();
|
|
24365
|
+
lines.push("Previous snippet:", clip(oldT, 6e3));
|
|
24366
|
+
lines.push("New snippet:", clip(newT, 6e3));
|
|
24367
|
+
} else {
|
|
24368
|
+
lines.push("(no diff body stored for this path)");
|
|
24369
|
+
}
|
|
24370
|
+
lines.push("");
|
|
24371
|
+
}
|
|
24372
|
+
return lines.join("\n");
|
|
24373
|
+
}
|
|
24374
|
+
|
|
24375
|
+
// ../types/src/dedupe-session-file-changes-by-path.ts
|
|
24376
|
+
function defaultRichness(c) {
|
|
24377
|
+
const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
|
|
24378
|
+
const nt = typeof c.newText === "string" ? c.newText.length : 0;
|
|
24379
|
+
const ot = typeof c.oldText === "string" ? c.oldText.length : 0;
|
|
24380
|
+
const dir = c.directoryRemoved === true ? 8 : 0;
|
|
24381
|
+
return (patch > 0 ? 4 : 0) + (nt > 0 ? 2 : 0) + (ot > 0 ? 1 : 0) + dir;
|
|
24382
|
+
}
|
|
24383
|
+
function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichness(item)) {
|
|
24384
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
24385
|
+
for (const item of items) {
|
|
24386
|
+
const p = typeof item.path === "string" ? item.path.trim() : "";
|
|
24387
|
+
if (!p) continue;
|
|
24388
|
+
const prev = byPath.get(p);
|
|
24389
|
+
if (!prev || richness(item) >= richness(prev)) byPath.set(p, item);
|
|
24287
24390
|
}
|
|
24391
|
+
return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
|
|
24392
|
+
}
|
|
24393
|
+
|
|
24394
|
+
// ../types/src/artifacts.ts
|
|
24395
|
+
init_zod();
|
|
24396
|
+
var ArtifactMetaSchema = external_exports.object({
|
|
24397
|
+
artifactId: external_exports.string(),
|
|
24398
|
+
workspaceId: external_exports.string(),
|
|
24399
|
+
/** Slug for permalink: /workspaces/:wid/artifacts/:slug */
|
|
24400
|
+
permalinkSlug: external_exports.string(),
|
|
24401
|
+
title: external_exports.string(),
|
|
24402
|
+
/** e.g. summary_report, build_log */
|
|
24403
|
+
type: external_exports.string().default("report"),
|
|
24404
|
+
/** Optional session that produced this artifact */
|
|
24405
|
+
sessionId: external_exports.string().nullable(),
|
|
24406
|
+
createdAt: external_exports.string(),
|
|
24407
|
+
updatedAt: external_exports.string()
|
|
24288
24408
|
});
|
|
24289
|
-
|
|
24290
|
-
|
|
24291
|
-
|
|
24409
|
+
|
|
24410
|
+
// ../types/src/templates.ts
|
|
24411
|
+
init_zod();
|
|
24412
|
+
var TemplateMetaSchema = external_exports.object({
|
|
24413
|
+
templateId: external_exports.string(),
|
|
24414
|
+
workspaceId: external_exports.string(),
|
|
24415
|
+
name: external_exports.string(),
|
|
24416
|
+
/** e.g. summary_report, build_log */
|
|
24417
|
+
artifactType: external_exports.string().optional(),
|
|
24418
|
+
createdAt: external_exports.string(),
|
|
24419
|
+
updatedAt: external_exports.string()
|
|
24420
|
+
});
|
|
24421
|
+
|
|
24422
|
+
// ../types/src/git-repos.ts
|
|
24423
|
+
init_zod();
|
|
24424
|
+
var GitRepoMetaSchema = external_exports.object({
|
|
24425
|
+
/** Stable id for the repo (e.g. hash of normalized canonical URL). Used for DO idFromName. */
|
|
24426
|
+
repoId: external_exports.string(),
|
|
24427
|
+
/** Canonical external URL (e.g. https://github.com/org/repo). Normalize before storing. */
|
|
24428
|
+
canonicalUrl: external_exports.string().url(),
|
|
24429
|
+
/** Optional workspace this repo was first linked in. */
|
|
24430
|
+
workspaceId: external_exports.string().nullable(),
|
|
24431
|
+
displayName: external_exports.string().optional(),
|
|
24432
|
+
createdAt: external_exports.string(),
|
|
24433
|
+
updatedAt: external_exports.string()
|
|
24434
|
+
});
|
|
24435
|
+
|
|
24436
|
+
// src/git/session-git-queue.ts
|
|
24437
|
+
import { execFile as execFile7 } from "node:child_process";
|
|
24438
|
+
import { readFile, stat } from "node:fs/promises";
|
|
24439
|
+
import { promisify as promisify7 } from "node:util";
|
|
24440
|
+
import * as path8 from "node:path";
|
|
24441
|
+
|
|
24442
|
+
// src/git/pre-turn-snapshot.ts
|
|
24443
|
+
import * as fs8 from "node:fs";
|
|
24444
|
+
import * as path7 from "node:path";
|
|
24445
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
24446
|
+
import { promisify as promisify6 } from "node:util";
|
|
24447
|
+
|
|
24448
|
+
// src/git/discover-repos.ts
|
|
24449
|
+
import * as fs7 from "node:fs";
|
|
24450
|
+
import * as path6 from "node:path";
|
|
24451
|
+
|
|
24452
|
+
// ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
|
|
24453
|
+
var import_file_exists = __toESM(require_dist(), 1);
|
|
24454
|
+
var import_debug = __toESM(require_src(), 1);
|
|
24455
|
+
var import_promise_deferred = __toESM(require_dist2(), 1);
|
|
24456
|
+
var import_promise_deferred2 = __toESM(require_dist2(), 1);
|
|
24457
|
+
import { Buffer as Buffer22 } from "node:buffer";
|
|
24458
|
+
import { spawn as spawn3 } from "child_process";
|
|
24459
|
+
import { normalize as normalize2 } from "node:path";
|
|
24460
|
+
import { EventEmitter } from "node:events";
|
|
24461
|
+
var __defProp2 = Object.defineProperty;
|
|
24462
|
+
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
24463
|
+
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
24464
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
24465
|
+
var __esm2 = (fn, res) => function __init() {
|
|
24466
|
+
return fn && (res = (0, fn[__getOwnPropNames2(fn)[0]])(fn = 0)), res;
|
|
24467
|
+
};
|
|
24468
|
+
var __commonJS2 = (cb, mod) => function __require2() {
|
|
24469
|
+
return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
24470
|
+
};
|
|
24471
|
+
var __export2 = (target, all) => {
|
|
24472
|
+
for (var name in all)
|
|
24473
|
+
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
24474
|
+
};
|
|
24475
|
+
var __copyProps2 = (to, from, except, desc) => {
|
|
24476
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
24477
|
+
for (let key of __getOwnPropNames2(from))
|
|
24478
|
+
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
24479
|
+
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
24480
|
+
}
|
|
24481
|
+
return to;
|
|
24482
|
+
};
|
|
24483
|
+
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
24484
|
+
function pathspec(...paths) {
|
|
24485
|
+
const key = new String(paths);
|
|
24486
|
+
cache.set(key, paths);
|
|
24487
|
+
return key;
|
|
24488
|
+
}
|
|
24489
|
+
function isPathSpec(path34) {
|
|
24490
|
+
return path34 instanceof String && cache.has(path34);
|
|
24491
|
+
}
|
|
24492
|
+
function toPaths(pathSpec) {
|
|
24493
|
+
return cache.get(pathSpec) || [];
|
|
24494
|
+
}
|
|
24495
|
+
var cache;
|
|
24496
|
+
var init_pathspec = __esm2({
|
|
24497
|
+
"src/lib/args/pathspec.ts"() {
|
|
24292
24498
|
"use strict";
|
|
24293
|
-
|
|
24294
|
-
ExitCodes2[ExitCodes2["SUCCESS"] = 0] = "SUCCESS";
|
|
24295
|
-
ExitCodes2[ExitCodes2["ERROR"] = 1] = "ERROR";
|
|
24296
|
-
ExitCodes2[ExitCodes2["NOT_FOUND"] = -2] = "NOT_FOUND";
|
|
24297
|
-
ExitCodes2[ExitCodes2["UNCLEAN"] = 128] = "UNCLEAN";
|
|
24298
|
-
return ExitCodes2;
|
|
24299
|
-
})(ExitCodes || {});
|
|
24499
|
+
cache = /* @__PURE__ */ new WeakMap();
|
|
24300
24500
|
}
|
|
24301
24501
|
});
|
|
24302
|
-
var
|
|
24303
|
-
var
|
|
24304
|
-
"src/lib/
|
|
24502
|
+
var GitError;
|
|
24503
|
+
var init_git_error = __esm2({
|
|
24504
|
+
"src/lib/errors/git-error.ts"() {
|
|
24305
24505
|
"use strict";
|
|
24306
|
-
|
|
24307
|
-
constructor(
|
|
24308
|
-
|
|
24309
|
-
this.
|
|
24310
|
-
|
|
24311
|
-
asStrings() {
|
|
24312
|
-
return new _GitOutputStreams(this.stdOut.toString("utf8"), this.stdErr.toString("utf8"));
|
|
24506
|
+
GitError = class extends Error {
|
|
24507
|
+
constructor(task, message) {
|
|
24508
|
+
super(message);
|
|
24509
|
+
this.task = task;
|
|
24510
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
24313
24511
|
}
|
|
24314
24512
|
};
|
|
24315
24513
|
}
|
|
24316
24514
|
});
|
|
24317
|
-
|
|
24318
|
-
|
|
24319
|
-
|
|
24320
|
-
var LineParser;
|
|
24321
|
-
var RemoteLineParser;
|
|
24322
|
-
var init_line_parser = __esm2({
|
|
24323
|
-
"src/lib/utils/line-parser.ts"() {
|
|
24515
|
+
var GitResponseError;
|
|
24516
|
+
var init_git_response_error = __esm2({
|
|
24517
|
+
"src/lib/errors/git-response-error.ts"() {
|
|
24324
24518
|
"use strict";
|
|
24325
|
-
|
|
24326
|
-
|
|
24327
|
-
|
|
24328
|
-
|
|
24329
|
-
this.
|
|
24330
|
-
|
|
24331
|
-
|
|
24332
|
-
|
|
24519
|
+
init_git_error();
|
|
24520
|
+
GitResponseError = class extends GitError {
|
|
24521
|
+
constructor(git, message) {
|
|
24522
|
+
super(void 0, message || String(git));
|
|
24523
|
+
this.git = git;
|
|
24524
|
+
}
|
|
24525
|
+
};
|
|
24526
|
+
}
|
|
24527
|
+
});
|
|
24528
|
+
var TaskConfigurationError;
|
|
24529
|
+
var init_task_configuration_error = __esm2({
|
|
24530
|
+
"src/lib/errors/task-configuration-error.ts"() {
|
|
24531
|
+
"use strict";
|
|
24532
|
+
init_git_error();
|
|
24533
|
+
TaskConfigurationError = class extends GitError {
|
|
24534
|
+
constructor(message) {
|
|
24535
|
+
super(void 0, message);
|
|
24536
|
+
}
|
|
24537
|
+
};
|
|
24538
|
+
}
|
|
24539
|
+
});
|
|
24540
|
+
function asFunction(source) {
|
|
24541
|
+
if (typeof source !== "function") {
|
|
24542
|
+
return NOOP;
|
|
24543
|
+
}
|
|
24544
|
+
return source;
|
|
24545
|
+
}
|
|
24546
|
+
function isUserFunction(source) {
|
|
24547
|
+
return typeof source === "function" && source !== NOOP;
|
|
24548
|
+
}
|
|
24549
|
+
function splitOn(input, char) {
|
|
24550
|
+
const index = input.indexOf(char);
|
|
24551
|
+
if (index <= 0) {
|
|
24552
|
+
return [input, ""];
|
|
24553
|
+
}
|
|
24554
|
+
return [input.substr(0, index), input.substr(index + 1)];
|
|
24555
|
+
}
|
|
24556
|
+
function first(input, offset = 0) {
|
|
24557
|
+
return isArrayLike(input) && input.length > offset ? input[offset] : void 0;
|
|
24558
|
+
}
|
|
24559
|
+
function last(input, offset = 0) {
|
|
24560
|
+
if (isArrayLike(input) && input.length > offset) {
|
|
24561
|
+
return input[input.length - 1 - offset];
|
|
24562
|
+
}
|
|
24563
|
+
}
|
|
24564
|
+
function isArrayLike(input) {
|
|
24565
|
+
return filterHasLength(input);
|
|
24566
|
+
}
|
|
24567
|
+
function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
24568
|
+
return input.split(separator).reduce((output, line) => {
|
|
24569
|
+
const lineContent = trimmed2 ? line.trim() : line;
|
|
24570
|
+
if (lineContent) {
|
|
24571
|
+
output.push(lineContent);
|
|
24572
|
+
}
|
|
24573
|
+
return output;
|
|
24574
|
+
}, []);
|
|
24575
|
+
}
|
|
24576
|
+
function forEachLineWithContent(input, callback) {
|
|
24577
|
+
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
24578
|
+
}
|
|
24579
|
+
function folderExists(path34) {
|
|
24580
|
+
return (0, import_file_exists.exists)(path34, import_file_exists.FOLDER);
|
|
24581
|
+
}
|
|
24582
|
+
function append(target, item) {
|
|
24583
|
+
if (Array.isArray(target)) {
|
|
24584
|
+
if (!target.includes(item)) {
|
|
24585
|
+
target.push(item);
|
|
24586
|
+
}
|
|
24587
|
+
} else {
|
|
24588
|
+
target.add(item);
|
|
24589
|
+
}
|
|
24590
|
+
return item;
|
|
24591
|
+
}
|
|
24592
|
+
function including(target, item) {
|
|
24593
|
+
if (Array.isArray(target) && !target.includes(item)) {
|
|
24594
|
+
target.push(item);
|
|
24595
|
+
}
|
|
24596
|
+
return target;
|
|
24597
|
+
}
|
|
24598
|
+
function remove(target, item) {
|
|
24599
|
+
if (Array.isArray(target)) {
|
|
24600
|
+
const index = target.indexOf(item);
|
|
24601
|
+
if (index >= 0) {
|
|
24602
|
+
target.splice(index, 1);
|
|
24603
|
+
}
|
|
24604
|
+
} else {
|
|
24605
|
+
target.delete(item);
|
|
24606
|
+
}
|
|
24607
|
+
return item;
|
|
24608
|
+
}
|
|
24609
|
+
function asArray(source) {
|
|
24610
|
+
return Array.isArray(source) ? source : [source];
|
|
24611
|
+
}
|
|
24612
|
+
function asCamelCase(str) {
|
|
24613
|
+
return str.replace(/[\s-]+(.)/g, (_all, chr) => {
|
|
24614
|
+
return chr.toUpperCase();
|
|
24615
|
+
});
|
|
24616
|
+
}
|
|
24617
|
+
function asStringArray(source) {
|
|
24618
|
+
return asArray(source).map((item) => {
|
|
24619
|
+
return item instanceof String ? item : String(item);
|
|
24620
|
+
});
|
|
24621
|
+
}
|
|
24622
|
+
function asNumber(source, onNaN = 0) {
|
|
24623
|
+
if (source == null) {
|
|
24624
|
+
return onNaN;
|
|
24625
|
+
}
|
|
24626
|
+
const num = parseInt(source, 10);
|
|
24627
|
+
return Number.isNaN(num) ? onNaN : num;
|
|
24628
|
+
}
|
|
24629
|
+
function prefixedArray(input, prefix) {
|
|
24630
|
+
const output = [];
|
|
24631
|
+
for (let i = 0, max = input.length; i < max; i++) {
|
|
24632
|
+
output.push(prefix, input[i]);
|
|
24633
|
+
}
|
|
24634
|
+
return output;
|
|
24635
|
+
}
|
|
24636
|
+
function bufferToString(input) {
|
|
24637
|
+
return (Array.isArray(input) ? Buffer22.concat(input) : input).toString("utf-8");
|
|
24638
|
+
}
|
|
24639
|
+
function pick2(source, properties) {
|
|
24640
|
+
const out = {};
|
|
24641
|
+
properties.forEach((key) => {
|
|
24642
|
+
if (source[key] !== void 0) {
|
|
24643
|
+
out[key] = source[key];
|
|
24644
|
+
}
|
|
24645
|
+
});
|
|
24646
|
+
return out;
|
|
24647
|
+
}
|
|
24648
|
+
function delay(duration3 = 0) {
|
|
24649
|
+
return new Promise((done) => setTimeout(done, duration3));
|
|
24650
|
+
}
|
|
24651
|
+
function orVoid(input) {
|
|
24652
|
+
if (input === false) {
|
|
24653
|
+
return void 0;
|
|
24654
|
+
}
|
|
24655
|
+
return input;
|
|
24656
|
+
}
|
|
24657
|
+
var NULL;
|
|
24658
|
+
var NOOP;
|
|
24659
|
+
var objectToString;
|
|
24660
|
+
var init_util3 = __esm2({
|
|
24661
|
+
"src/lib/utils/util.ts"() {
|
|
24662
|
+
"use strict";
|
|
24663
|
+
init_argument_filters();
|
|
24664
|
+
NULL = "\0";
|
|
24665
|
+
NOOP = () => {
|
|
24666
|
+
};
|
|
24667
|
+
objectToString = Object.prototype.toString.call.bind(Object.prototype.toString);
|
|
24668
|
+
}
|
|
24669
|
+
});
|
|
24670
|
+
function filterType(input, filter, def) {
|
|
24671
|
+
if (filter(input)) {
|
|
24672
|
+
return input;
|
|
24673
|
+
}
|
|
24674
|
+
return arguments.length > 2 ? def : void 0;
|
|
24675
|
+
}
|
|
24676
|
+
function filterPrimitives(input, omit2) {
|
|
24677
|
+
const type = isPathSpec(input) ? "string" : typeof input;
|
|
24678
|
+
return /number|string|boolean/.test(type) && (!omit2 || !omit2.includes(type));
|
|
24679
|
+
}
|
|
24680
|
+
function filterPlainObject(input) {
|
|
24681
|
+
return !!input && objectToString(input) === "[object Object]";
|
|
24682
|
+
}
|
|
24683
|
+
function filterFunction(input) {
|
|
24684
|
+
return typeof input === "function";
|
|
24685
|
+
}
|
|
24686
|
+
var filterArray;
|
|
24687
|
+
var filterNumber;
|
|
24688
|
+
var filterString;
|
|
24689
|
+
var filterStringOrStringArray;
|
|
24690
|
+
var filterHasLength;
|
|
24691
|
+
var init_argument_filters = __esm2({
|
|
24692
|
+
"src/lib/utils/argument-filters.ts"() {
|
|
24693
|
+
"use strict";
|
|
24694
|
+
init_pathspec();
|
|
24695
|
+
init_util3();
|
|
24696
|
+
filterArray = (input) => {
|
|
24697
|
+
return Array.isArray(input);
|
|
24698
|
+
};
|
|
24699
|
+
filterNumber = (input) => {
|
|
24700
|
+
return typeof input === "number";
|
|
24701
|
+
};
|
|
24702
|
+
filterString = (input) => {
|
|
24703
|
+
return typeof input === "string";
|
|
24704
|
+
};
|
|
24705
|
+
filterStringOrStringArray = (input) => {
|
|
24706
|
+
return filterString(input) || Array.isArray(input) && input.every(filterString);
|
|
24707
|
+
};
|
|
24708
|
+
filterHasLength = (input) => {
|
|
24709
|
+
if (input == null || "number|boolean|function".includes(typeof input)) {
|
|
24710
|
+
return false;
|
|
24711
|
+
}
|
|
24712
|
+
return typeof input.length === "number";
|
|
24713
|
+
};
|
|
24714
|
+
}
|
|
24715
|
+
});
|
|
24716
|
+
var ExitCodes;
|
|
24717
|
+
var init_exit_codes = __esm2({
|
|
24718
|
+
"src/lib/utils/exit-codes.ts"() {
|
|
24719
|
+
"use strict";
|
|
24720
|
+
ExitCodes = /* @__PURE__ */ ((ExitCodes2) => {
|
|
24721
|
+
ExitCodes2[ExitCodes2["SUCCESS"] = 0] = "SUCCESS";
|
|
24722
|
+
ExitCodes2[ExitCodes2["ERROR"] = 1] = "ERROR";
|
|
24723
|
+
ExitCodes2[ExitCodes2["NOT_FOUND"] = -2] = "NOT_FOUND";
|
|
24724
|
+
ExitCodes2[ExitCodes2["UNCLEAN"] = 128] = "UNCLEAN";
|
|
24725
|
+
return ExitCodes2;
|
|
24726
|
+
})(ExitCodes || {});
|
|
24727
|
+
}
|
|
24728
|
+
});
|
|
24729
|
+
var GitOutputStreams;
|
|
24730
|
+
var init_git_output_streams = __esm2({
|
|
24731
|
+
"src/lib/utils/git-output-streams.ts"() {
|
|
24732
|
+
"use strict";
|
|
24733
|
+
GitOutputStreams = class _GitOutputStreams {
|
|
24734
|
+
constructor(stdOut, stdErr) {
|
|
24735
|
+
this.stdOut = stdOut;
|
|
24736
|
+
this.stdErr = stdErr;
|
|
24737
|
+
}
|
|
24738
|
+
asStrings() {
|
|
24739
|
+
return new _GitOutputStreams(this.stdOut.toString("utf8"), this.stdErr.toString("utf8"));
|
|
24740
|
+
}
|
|
24741
|
+
};
|
|
24742
|
+
}
|
|
24743
|
+
});
|
|
24744
|
+
function useMatchesDefault() {
|
|
24745
|
+
throw new Error(`LineParser:useMatches not implemented`);
|
|
24746
|
+
}
|
|
24747
|
+
var LineParser;
|
|
24748
|
+
var RemoteLineParser;
|
|
24749
|
+
var init_line_parser = __esm2({
|
|
24750
|
+
"src/lib/utils/line-parser.ts"() {
|
|
24751
|
+
"use strict";
|
|
24752
|
+
LineParser = class {
|
|
24753
|
+
constructor(regExp, useMatches) {
|
|
24754
|
+
this.matches = [];
|
|
24755
|
+
this.useMatches = useMatchesDefault;
|
|
24756
|
+
this.parse = (line, target) => {
|
|
24757
|
+
this.resetMatches();
|
|
24758
|
+
if (!this._regExp.every((reg, index) => this.addMatch(reg, index, line(index)))) {
|
|
24759
|
+
return false;
|
|
24333
24760
|
}
|
|
24334
24761
|
return this.useMatches(target, this.prepareMatches()) !== false;
|
|
24335
24762
|
};
|
|
@@ -28521,748 +28948,332 @@ function timeoutPlugin({
|
|
|
28521
28948
|
};
|
|
28522
28949
|
}
|
|
28523
28950
|
}
|
|
28524
|
-
init_pathspec();
|
|
28525
|
-
function suffixPathsPlugin() {
|
|
28526
|
-
return {
|
|
28527
|
-
type: "spawn.args",
|
|
28528
|
-
action(data) {
|
|
28529
|
-
const prefix = [];
|
|
28530
|
-
let suffix;
|
|
28531
|
-
function append2(args) {
|
|
28532
|
-
(suffix = suffix || []).push(...args);
|
|
28533
|
-
}
|
|
28534
|
-
for (let i = 0; i < data.length; i++) {
|
|
28535
|
-
const param = data[i];
|
|
28536
|
-
if (isPathSpec(param)) {
|
|
28537
|
-
append2(toPaths(param));
|
|
28538
|
-
continue;
|
|
28539
|
-
}
|
|
28540
|
-
if (param === "--") {
|
|
28541
|
-
append2(
|
|
28542
|
-
data.slice(i + 1).flatMap((item) => isPathSpec(item) && toPaths(item) || item)
|
|
28543
|
-
);
|
|
28544
|
-
break;
|
|
28545
|
-
}
|
|
28546
|
-
prefix.push(param);
|
|
28547
|
-
}
|
|
28548
|
-
return !suffix ? prefix : [...prefix, "--", ...suffix.map(String)];
|
|
28549
|
-
}
|
|
28550
|
-
};
|
|
28551
|
-
}
|
|
28552
|
-
init_utils();
|
|
28553
|
-
var Git = require_git();
|
|
28554
|
-
function gitInstanceFactory(baseDir, options) {
|
|
28555
|
-
const plugins = new PluginStore();
|
|
28556
|
-
const config2 = createInstanceConfig(
|
|
28557
|
-
baseDir && (typeof baseDir === "string" ? { baseDir } : baseDir) || {},
|
|
28558
|
-
options
|
|
28559
|
-
);
|
|
28560
|
-
if (!folderExists(config2.baseDir)) {
|
|
28561
|
-
throw new GitConstructError(
|
|
28562
|
-
config2,
|
|
28563
|
-
`Cannot use simple-git on a directory that does not exist`
|
|
28564
|
-
);
|
|
28565
|
-
}
|
|
28566
|
-
if (Array.isArray(config2.config)) {
|
|
28567
|
-
plugins.add(commandConfigPrefixingPlugin(config2.config));
|
|
28568
|
-
}
|
|
28569
|
-
plugins.add(blockUnsafeOperationsPlugin(config2.unsafe));
|
|
28570
|
-
plugins.add(suffixPathsPlugin());
|
|
28571
|
-
plugins.add(completionDetectionPlugin(config2.completion));
|
|
28572
|
-
config2.abort && plugins.add(abortPlugin(config2.abort));
|
|
28573
|
-
config2.progress && plugins.add(progressMonitorPlugin(config2.progress));
|
|
28574
|
-
config2.timeout && plugins.add(timeoutPlugin(config2.timeout));
|
|
28575
|
-
config2.spawnOptions && plugins.add(spawnOptionsPlugin(config2.spawnOptions));
|
|
28576
|
-
plugins.add(errorDetectionPlugin(errorDetectionHandler(true)));
|
|
28577
|
-
config2.errors && plugins.add(errorDetectionPlugin(config2.errors));
|
|
28578
|
-
customBinaryPlugin(plugins, config2.binary, config2.unsafe?.allowUnsafeCustomBinary);
|
|
28579
|
-
return new Git(config2, plugins);
|
|
28580
|
-
}
|
|
28581
|
-
init_git_response_error();
|
|
28582
|
-
var simpleGit = gitInstanceFactory;
|
|
28583
|
-
|
|
28584
|
-
// src/git/remote-origin-url.ts
|
|
28585
|
-
async function getRemoteOriginUrl(gitDir) {
|
|
28586
|
-
try {
|
|
28587
|
-
const git = simpleGit(gitDir);
|
|
28588
|
-
const remotes = await git.getRemotes(true);
|
|
28589
|
-
const list = Array.isArray(remotes) ? remotes : [];
|
|
28590
|
-
const origin = list.find((r) => r.name === "origin");
|
|
28591
|
-
if (!origin?.refs?.fetch && !origin?.refs?.push) return "";
|
|
28592
|
-
return (origin.refs.fetch ?? origin.refs.push ?? "").trim();
|
|
28593
|
-
} catch {
|
|
28594
|
-
return "";
|
|
28595
|
-
}
|
|
28596
|
-
}
|
|
28597
|
-
|
|
28598
|
-
// src/git/is-git-repo.ts
|
|
28599
|
-
async function isGitRepoDirectory(dirPath) {
|
|
28600
|
-
try {
|
|
28601
|
-
return await simpleGit(dirPath).checkIsRepo();
|
|
28602
|
-
} catch {
|
|
28603
|
-
return false;
|
|
28604
|
-
}
|
|
28605
|
-
}
|
|
28606
|
-
|
|
28607
|
-
// src/git/discover-repos.ts
|
|
28608
|
-
async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
28609
|
-
const result = [];
|
|
28610
|
-
const cwdResolved = path6.resolve(cwd);
|
|
28611
|
-
if (await isGitRepoDirectory(cwdResolved)) {
|
|
28612
|
-
const remoteUrl = await getRemoteOriginUrl(cwdResolved);
|
|
28613
|
-
result.push({ absolutePath: cwdResolved, remoteUrl });
|
|
28614
|
-
}
|
|
28615
|
-
let entries;
|
|
28616
|
-
try {
|
|
28617
|
-
entries = fs7.readdirSync(cwdResolved, { withFileTypes: true });
|
|
28618
|
-
} catch {
|
|
28619
|
-
return result;
|
|
28620
|
-
}
|
|
28621
|
-
for (const ent of entries) {
|
|
28622
|
-
if (!ent.isDirectory()) continue;
|
|
28623
|
-
const childPath = path6.join(cwdResolved, ent.name);
|
|
28624
|
-
if (await isGitRepoDirectory(childPath)) {
|
|
28625
|
-
const remoteUrl = await getRemoteOriginUrl(childPath);
|
|
28626
|
-
result.push({ absolutePath: childPath, remoteUrl });
|
|
28627
|
-
}
|
|
28628
|
-
}
|
|
28629
|
-
return result;
|
|
28630
|
-
}
|
|
28631
|
-
async function discoverGitReposUnderRoot(rootPath) {
|
|
28632
|
-
const root = path6.resolve(rootPath);
|
|
28633
|
-
const roots = [];
|
|
28634
|
-
async function walk(dir) {
|
|
28635
|
-
if (await isGitRepoDirectory(dir)) {
|
|
28636
|
-
roots.push(path6.resolve(dir));
|
|
28637
|
-
return;
|
|
28638
|
-
}
|
|
28639
|
-
let entries;
|
|
28640
|
-
try {
|
|
28641
|
-
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
28642
|
-
} catch {
|
|
28643
|
-
return;
|
|
28644
|
-
}
|
|
28645
|
-
for (const ent of entries) {
|
|
28646
|
-
if (!ent.isDirectory() || ent.name === ".git") continue;
|
|
28647
|
-
await walk(path6.join(dir, ent.name));
|
|
28648
|
-
}
|
|
28649
|
-
}
|
|
28650
|
-
await walk(root);
|
|
28651
|
-
const uniq = [...new Set(roots)];
|
|
28652
|
-
const out = [];
|
|
28653
|
-
for (const p of uniq) {
|
|
28654
|
-
const remoteUrl = await getRemoteOriginUrl(p);
|
|
28655
|
-
out.push({ absolutePath: p, remoteUrl });
|
|
28656
|
-
}
|
|
28657
|
-
return out;
|
|
28658
|
-
}
|
|
28659
|
-
|
|
28660
|
-
// src/git/pre-turn-snapshot.ts
|
|
28661
|
-
var execFileAsync5 = promisify6(execFile6);
|
|
28662
|
-
function snapshotsDirForCwd(agentCwd) {
|
|
28663
|
-
return path7.join(agentCwd, ".buildautomaton", "snapshots");
|
|
28664
|
-
}
|
|
28665
|
-
async function gitStashCreate(repoRoot, log2) {
|
|
28666
|
-
try {
|
|
28667
|
-
const { stdout } = await execFileAsync5("git", ["stash", "create"], {
|
|
28668
|
-
cwd: repoRoot,
|
|
28669
|
-
maxBuffer: 10 * 1024 * 1024
|
|
28670
|
-
});
|
|
28671
|
-
return stdout.trim();
|
|
28672
|
-
} catch (e) {
|
|
28673
|
-
log2(
|
|
28674
|
-
`[snapshot] Git stash create failed in ${repoRoot}: ${e instanceof Error ? e.message : String(e)}`
|
|
28675
|
-
);
|
|
28676
|
-
return "";
|
|
28677
|
-
}
|
|
28678
|
-
}
|
|
28679
|
-
async function gitRun(repoRoot, args, log2, label) {
|
|
28680
|
-
try {
|
|
28681
|
-
await execFileAsync5("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
|
|
28682
|
-
return { ok: true };
|
|
28683
|
-
} catch (e) {
|
|
28684
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
28685
|
-
log2(`[snapshot] Git ${label} failed in ${repoRoot}: ${msg}`);
|
|
28686
|
-
return { ok: false, error: msg };
|
|
28687
|
-
}
|
|
28688
|
-
}
|
|
28689
|
-
async function resolveSnapshotRepoRoots(options) {
|
|
28690
|
-
const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
|
|
28691
|
-
if (worktreePaths?.length) {
|
|
28692
|
-
const uniq = [...new Set(worktreePaths.map((p) => path7.resolve(p)))];
|
|
28693
|
-
return uniq;
|
|
28694
|
-
}
|
|
28695
|
-
try {
|
|
28696
|
-
const repos = await discoverGitReposUnderRoot(fallbackCwd);
|
|
28697
|
-
const mapped = repos.map((r) => r.absolutePath);
|
|
28698
|
-
const sid = sessionId?.trim();
|
|
28699
|
-
if (sid) {
|
|
28700
|
-
const filtered = mapped.filter((root) => path7.basename(root) === sid);
|
|
28701
|
-
if (filtered.length > 0) return filtered;
|
|
28702
|
-
}
|
|
28703
|
-
return mapped;
|
|
28704
|
-
} catch (e) {
|
|
28705
|
-
log2(`[snapshot] Discover repositories failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
28706
|
-
return [];
|
|
28707
|
-
}
|
|
28708
|
-
}
|
|
28709
|
-
async function capturePreTurnSnapshot(options) {
|
|
28710
|
-
const { runId, repoRoots, agentCwd, log: log2 } = options;
|
|
28711
|
-
if (!runId || !repoRoots.length) {
|
|
28712
|
-
return { ok: false, error: "No git repos to snapshot" };
|
|
28713
|
-
}
|
|
28714
|
-
const repos = [];
|
|
28715
|
-
for (const root of repoRoots) {
|
|
28716
|
-
const stashSha = await gitStashCreate(root, log2);
|
|
28717
|
-
repos.push({ path: root, stashSha });
|
|
28718
|
-
}
|
|
28719
|
-
const dir = snapshotsDirForCwd(agentCwd);
|
|
28720
|
-
try {
|
|
28721
|
-
fs8.mkdirSync(dir, { recursive: true });
|
|
28722
|
-
} catch (e) {
|
|
28723
|
-
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
28724
|
-
}
|
|
28725
|
-
const payload = {
|
|
28726
|
-
runId,
|
|
28727
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28728
|
-
repos
|
|
28729
|
-
};
|
|
28730
|
-
const filePath = path7.join(dir, `${runId}.json`);
|
|
28731
|
-
try {
|
|
28732
|
-
fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
28733
|
-
} catch (e) {
|
|
28734
|
-
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
28735
|
-
}
|
|
28736
|
-
const repoList = repos.map((r) => r.path).join(", ");
|
|
28737
|
-
log2(
|
|
28738
|
-
`[snapshot] Saved pre-turn snapshot ${runId.slice(0, 8)}\u2026 (${repos.length} repo(s)): ${repoList}`
|
|
28739
|
-
);
|
|
28740
|
-
return { ok: true, filePath, repos };
|
|
28741
|
-
}
|
|
28742
|
-
async function applyPreTurnSnapshot(filePath, log2) {
|
|
28743
|
-
let data;
|
|
28744
|
-
try {
|
|
28745
|
-
const raw = fs8.readFileSync(filePath, "utf8");
|
|
28746
|
-
data = JSON.parse(raw);
|
|
28747
|
-
} catch (e) {
|
|
28748
|
-
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
28749
|
-
}
|
|
28750
|
-
if (!Array.isArray(data.repos)) {
|
|
28751
|
-
return { ok: false, error: "Invalid snapshot file" };
|
|
28752
|
-
}
|
|
28753
|
-
for (const r of data.repos) {
|
|
28754
|
-
if (!r.path) continue;
|
|
28755
|
-
const reset = await gitRun(r.path, ["reset", "--hard", "HEAD"], log2, "reset --hard");
|
|
28756
|
-
if (!reset.ok) return reset;
|
|
28757
|
-
const clean = await gitRun(r.path, ["clean", "-fd"], log2, "clean -fd");
|
|
28758
|
-
if (!clean.ok) return clean;
|
|
28759
|
-
if (r.stashSha) {
|
|
28760
|
-
const ap = await gitRun(r.path, ["stash", "apply", r.stashSha], log2, "stash apply");
|
|
28761
|
-
if (!ap.ok) return ap;
|
|
28762
|
-
}
|
|
28763
|
-
}
|
|
28764
|
-
log2(`[snapshot] Restored pre-turn state for ${data.runId.slice(0, 8)}\u2026`);
|
|
28765
|
-
return { ok: true };
|
|
28766
|
-
}
|
|
28767
|
-
function snapshotFilePath(agentCwd, runId) {
|
|
28768
|
-
return path7.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
|
|
28769
|
-
}
|
|
28770
|
-
|
|
28771
|
-
// src/git/session-git-queue.ts
|
|
28772
|
-
var execFileAsync6 = promisify7(execFile7);
|
|
28773
|
-
var MAX_FULL_FILE_TEXT_BYTES = 512 * 1024;
|
|
28774
|
-
async function readWorkspaceFileAsUtf8(absPath) {
|
|
28775
|
-
try {
|
|
28776
|
-
const st = await stat(absPath);
|
|
28777
|
-
if (!st.isFile() || st.size > MAX_FULL_FILE_TEXT_BYTES) return void 0;
|
|
28778
|
-
return await readFile(absPath, "utf8");
|
|
28779
|
-
} catch {
|
|
28780
|
-
return void 0;
|
|
28781
|
-
}
|
|
28782
|
-
}
|
|
28783
|
-
async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
28784
|
-
const { sessionId, runId, agentCwd, sendSessionUpdate, log: log2 } = options;
|
|
28785
|
-
const filePath = snapshotFilePath(agentCwd, runId);
|
|
28786
|
-
let data;
|
|
28787
|
-
try {
|
|
28788
|
-
const raw = await readFile(filePath, "utf8");
|
|
28789
|
-
data = JSON.parse(raw);
|
|
28790
|
-
} catch (e) {
|
|
28791
|
-
log2(
|
|
28792
|
-
`[session-git-queue] No pre-turn snapshot for run ${runId.slice(0, 8)}\u2026: ${e instanceof Error ? e.message : String(e)}`
|
|
28793
|
-
);
|
|
28794
|
-
return;
|
|
28795
|
-
}
|
|
28796
|
-
if (!Array.isArray(data.repos) || !data.repos.length) {
|
|
28797
|
-
log2(`[session-git-queue] Empty repos in snapshot ${runId.slice(0, 8)}\u2026; skipping aggregate diff.`);
|
|
28798
|
-
return;
|
|
28799
|
-
}
|
|
28800
|
-
const multiRepo = data.repos.length > 1;
|
|
28801
|
-
for (const repo of data.repos) {
|
|
28802
|
-
if (!repo.stashSha) continue;
|
|
28803
|
-
let namesRaw;
|
|
28804
|
-
try {
|
|
28805
|
-
const { stdout } = await execFileAsync6("git", ["diff", "--name-only", repo.stashSha], {
|
|
28806
|
-
cwd: repo.path,
|
|
28807
|
-
maxBuffer: 10 * 1024 * 1024
|
|
28808
|
-
});
|
|
28809
|
-
namesRaw = stdout;
|
|
28810
|
-
} catch (e) {
|
|
28811
|
-
log2(
|
|
28812
|
-
`[session-git-queue] Git diff --name-only failed in ${repo.path}: ${e instanceof Error ? e.message : String(e)}`
|
|
28813
|
-
);
|
|
28814
|
-
continue;
|
|
28815
|
-
}
|
|
28816
|
-
const lines = namesRaw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
28817
|
-
const slug = path8.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
|
|
28818
|
-
for (const rel of lines) {
|
|
28819
|
-
if (rel.includes("..")) continue;
|
|
28820
|
-
try {
|
|
28821
|
-
const { stdout: patchContent } = await execFileAsync6(
|
|
28822
|
-
"git",
|
|
28823
|
-
["diff", "--no-color", repo.stashSha, "--", rel],
|
|
28824
|
-
{
|
|
28825
|
-
cwd: repo.path,
|
|
28826
|
-
maxBuffer: 50 * 1024 * 1024
|
|
28827
|
-
}
|
|
28828
|
-
);
|
|
28829
|
-
if (!patchContent.trim()) continue;
|
|
28830
|
-
const displayPath = multiRepo ? `${slug}/${rel}` : rel;
|
|
28831
|
-
const workspaceFilePath = path8.join(repo.path, rel);
|
|
28832
|
-
const newText = await readWorkspaceFileAsUtf8(workspaceFilePath);
|
|
28833
|
-
sendSessionUpdate({
|
|
28834
|
-
type: "session_file_change",
|
|
28835
|
-
sessionId,
|
|
28836
|
-
runId,
|
|
28837
|
-
path: displayPath,
|
|
28838
|
-
patchContent,
|
|
28839
|
-
...newText !== void 0 ? { newText } : {}
|
|
28840
|
-
});
|
|
28841
|
-
} catch (e) {
|
|
28842
|
-
log2(
|
|
28843
|
-
`[session-git-queue] Git diff failed for ${rel}: ${e instanceof Error ? e.message : String(e)}`
|
|
28844
|
-
);
|
|
28845
|
-
}
|
|
28846
|
-
}
|
|
28847
|
-
}
|
|
28848
|
-
}
|
|
28849
|
-
|
|
28850
|
-
// ../types/src/work-items.ts
|
|
28851
|
-
init_zod();
|
|
28852
|
-
var WorkItemStatusSchema = external_exports.enum(["backlog", "in-progress", "completed"]);
|
|
28853
|
-
var WorkItemProgressSchema = external_exports.object({
|
|
28854
|
-
remainingCriteria: external_exports.array(external_exports.string()).default([]),
|
|
28855
|
-
openQuestions: external_exports.array(external_exports.string()).default([]),
|
|
28856
|
-
assignedTo: external_exports.enum(["agent", "human-product", "human-expert"]).optional()
|
|
28857
|
-
});
|
|
28858
|
-
var ChangeSchema = external_exports.object({
|
|
28859
|
-
id: external_exports.string(),
|
|
28860
|
-
description: external_exports.string(),
|
|
28861
|
-
buildingBlockId: external_exports.string(),
|
|
28862
|
-
buildingBlockType: external_exports.enum(["function", "workflow", "connector", "ui-component", "app-fragment", "application", "project"]),
|
|
28863
|
-
action: external_exports.enum(["create", "update", "split", "combine"])
|
|
28864
|
-
});
|
|
28865
|
-
var CompletionCriterionSchema = external_exports.object({
|
|
28866
|
-
id: external_exports.string(),
|
|
28867
|
-
description: external_exports.string(),
|
|
28868
|
-
type: external_exports.enum(["write-code", "write-tests", "verify-tests", "other"]),
|
|
28869
|
-
verified: external_exports.boolean().default(false)
|
|
28870
|
-
});
|
|
28871
|
-
var WorkItemPrioritySchema = external_exports.enum(["low", "medium", "high", "critical"]);
|
|
28872
|
-
var IterationPhaseSchema = external_exports.enum(["analysis", "implementation", "verify", "reprioritize", "completed"]);
|
|
28873
|
-
var WorkItemDependencySchema = external_exports.object({
|
|
28874
|
-
type: external_exports.enum(["work-item"]),
|
|
28875
|
-
id: external_exports.string()
|
|
28876
|
-
});
|
|
28877
|
-
var WorkItemSchema = external_exports.object({
|
|
28878
|
-
id: external_exports.string(),
|
|
28879
|
-
sessionId: external_exports.string().optional(),
|
|
28880
|
-
summary: external_exports.string().optional(),
|
|
28881
|
-
description: external_exports.string(),
|
|
28882
|
-
status: WorkItemStatusSchema,
|
|
28883
|
-
buildingBlockId: external_exports.string().optional(),
|
|
28884
|
-
buildingBlockType: external_exports.enum(["function", "workflow", "connector", "ui-component", "app-fragment", "application", "project"]),
|
|
28885
|
-
changes: external_exports.array(ChangeSchema).default([]),
|
|
28886
|
-
completionCriteria: external_exports.array(CompletionCriterionSchema).default([]),
|
|
28887
|
-
priority: WorkItemPrioritySchema.default("medium"),
|
|
28888
|
-
dependencies: external_exports.array(WorkItemDependencySchema).default([]),
|
|
28889
|
-
assignedToUserId: external_exports.string().optional()
|
|
28890
|
-
});
|
|
28891
|
-
|
|
28892
|
-
// ../types/src/user-profiles.ts
|
|
28893
|
-
init_zod();
|
|
28894
|
-
var UserWorkspaceProfileSchema = external_exports.object({
|
|
28895
|
-
id: external_exports.string(),
|
|
28896
|
-
workspaceId: external_exports.string(),
|
|
28897
|
-
userId: external_exports.string(),
|
|
28898
|
-
roleDescription: external_exports.string().optional(),
|
|
28899
|
-
expertiseAreas: external_exports.array(external_exports.string()),
|
|
28900
|
-
preferences: external_exports.record(external_exports.unknown()).optional(),
|
|
28901
|
-
learnings: external_exports.array(external_exports.string())
|
|
28902
|
-
});
|
|
28903
|
-
|
|
28904
|
-
// ../types/src/runtime.ts
|
|
28905
|
-
init_zod();
|
|
28906
|
-
var WorkspaceOwnerInfoSchema = external_exports.object({
|
|
28907
|
-
ownerId: external_exports.string(),
|
|
28908
|
-
ownerName: external_exports.string().optional(),
|
|
28909
|
-
ownerEmail: external_exports.string().optional(),
|
|
28910
|
-
ownerProfilePictureUrl: external_exports.string().optional()
|
|
28911
|
-
});
|
|
28912
|
-
var WorkspaceRuntimeEntrySchema = external_exports.object({
|
|
28913
|
-
workspaceId: external_exports.string(),
|
|
28914
|
-
path: external_exports.string(),
|
|
28915
|
-
name: external_exports.string().optional(),
|
|
28916
|
-
owner: WorkspaceOwnerInfoSchema.optional(),
|
|
28917
|
-
isOwner: external_exports.boolean().optional()
|
|
28918
|
-
});
|
|
28919
|
-
|
|
28920
|
-
// ../types/src/agent.ts
|
|
28921
|
-
init_zod();
|
|
28922
|
-
var ProjectContextSchema = external_exports.object({
|
|
28923
|
-
projectId: external_exports.string(),
|
|
28924
|
-
context: external_exports.record(external_exports.unknown()).default({}),
|
|
28925
|
-
updatedAt: external_exports.string()
|
|
28926
|
-
});
|
|
28927
|
-
var WebSocketMessageTypeSchema = external_exports.enum([
|
|
28928
|
-
"plan-update",
|
|
28929
|
-
"work-item-update",
|
|
28930
|
-
"work-item-added",
|
|
28931
|
-
"work-item-removed",
|
|
28932
|
-
"project-processing-start",
|
|
28933
|
-
"project-processing-update",
|
|
28934
|
-
"project-processing-complete",
|
|
28935
|
-
"project-processing-error",
|
|
28936
|
-
"file-tool-request",
|
|
28937
|
-
"file-tool-response",
|
|
28938
|
-
"file-generated"
|
|
28939
|
-
]);
|
|
28940
|
-
var WebSocketMessageSchema = external_exports.object({
|
|
28941
|
-
type: WebSocketMessageTypeSchema,
|
|
28942
|
-
contextId: external_exports.string().optional(),
|
|
28943
|
-
data: external_exports.any().optional(),
|
|
28944
|
-
error: external_exports.string().optional()
|
|
28945
|
-
});
|
|
28946
|
-
|
|
28947
|
-
// ../types/src/checkpoints.ts
|
|
28948
|
-
init_zod();
|
|
28949
|
-
var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
|
|
28950
|
-
var CheckpointSummarySchema = external_exports.object({
|
|
28951
|
-
id: external_exports.string(),
|
|
28952
|
-
kind: CheckpointKindSchema,
|
|
28953
|
-
/** ISO date for daily (YYYY-MM-DD), ISO week for weekly, null for overall */
|
|
28954
|
-
periodKey: external_exports.string().nullable(),
|
|
28955
|
-
summary: external_exports.string(),
|
|
28956
|
-
createdAt: external_exports.string(),
|
|
28957
|
-
updatedAt: external_exports.string()
|
|
28958
|
-
});
|
|
28959
|
-
|
|
28960
|
-
// ../types/src/threads.ts
|
|
28961
|
-
init_zod();
|
|
28962
|
-
var ThreadMetaSchema = external_exports.object({
|
|
28963
|
-
threadId: external_exports.string(),
|
|
28964
|
-
workspaceId: external_exports.string(),
|
|
28965
|
-
/** External source (e.g. slack, discord); null if internal-only */
|
|
28966
|
-
externalSource: external_exports.string().nullable(),
|
|
28967
|
-
/** Id in the external system (e.g. channel_id + thread_ts) */
|
|
28968
|
-
externalId: external_exports.string().nullable(),
|
|
28969
|
-
title: external_exports.string().optional(),
|
|
28970
|
-
createdAt: external_exports.string(),
|
|
28971
|
-
updatedAt: external_exports.string()
|
|
28972
|
-
});
|
|
28973
|
-
var ThreadMessageSchema = external_exports.object({
|
|
28974
|
-
messageId: external_exports.string(),
|
|
28975
|
-
threadId: external_exports.string(),
|
|
28976
|
-
/** Role: user, assistant, system */
|
|
28977
|
-
role: external_exports.enum(["user", "assistant", "system"]),
|
|
28978
|
-
content: external_exports.string(),
|
|
28979
|
-
/** Optional reference to a ContentItem (e.g. doc, Notion page) */
|
|
28980
|
-
contentItemId: external_exports.string().nullable(),
|
|
28981
|
-
/** External message id if synced from external chat */
|
|
28982
|
-
externalId: external_exports.string().nullable(),
|
|
28983
|
-
createdAt: external_exports.string(),
|
|
28984
|
-
updatedAt: external_exports.string()
|
|
28985
|
-
});
|
|
28986
|
-
var ThreadCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
28987
|
-
threadId: external_exports.string()
|
|
28988
|
-
});
|
|
28989
|
-
|
|
28990
|
-
// ../types/src/content-items.ts
|
|
28991
|
-
init_zod();
|
|
28992
|
-
var ContentSourceSchema = external_exports.enum(["notion", "doc", "slack_thread", "other"]);
|
|
28993
|
-
var ContentItemMetaSchema = external_exports.object({
|
|
28994
|
-
contentId: external_exports.string(),
|
|
28995
|
-
workspaceId: external_exports.string(),
|
|
28996
|
-
source: ContentSourceSchema,
|
|
28997
|
-
/** Id in the external system (e.g. Notion page id, doc url) */
|
|
28998
|
-
externalId: external_exports.string(),
|
|
28999
|
-
/** If source is slack_thread, points to Thread DO id */
|
|
29000
|
-
threadId: external_exports.string().nullable(),
|
|
29001
|
-
title: external_exports.string().optional(),
|
|
29002
|
-
createdAt: external_exports.string(),
|
|
29003
|
-
updatedAt: external_exports.string()
|
|
29004
|
-
});
|
|
29005
|
-
var ContentStorageRefSchema = external_exports.object({
|
|
29006
|
-
storageKey: external_exports.string(),
|
|
29007
|
-
/** Optional: mime type or format hint */
|
|
29008
|
-
contentType: external_exports.string().optional()
|
|
29009
|
-
});
|
|
29010
|
-
var ContentCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
29011
|
-
contentId: external_exports.string()
|
|
29012
|
-
});
|
|
29013
|
-
|
|
29014
|
-
// ../types/src/stories.ts
|
|
29015
|
-
init_zod();
|
|
29016
|
-
var StoryMetaSchema = external_exports.object({
|
|
29017
|
-
storyId: external_exports.string(),
|
|
29018
|
-
workspaceId: external_exports.string(),
|
|
29019
|
-
title: external_exports.string(),
|
|
29020
|
-
/** feature | bug | epic */
|
|
29021
|
-
kind: external_exports.enum(["feature", "bug", "epic"]).default("feature"),
|
|
29022
|
-
createdAt: external_exports.string(),
|
|
29023
|
-
updatedAt: external_exports.string()
|
|
29024
|
-
});
|
|
29025
|
-
var StoryContentItemRefSchema = external_exports.object({
|
|
29026
|
-
id: external_exports.string(),
|
|
29027
|
-
storyId: external_exports.string(),
|
|
29028
|
-
contentItemId: external_exports.string(),
|
|
29029
|
-
/** Snapshot summary when added to story (or updated) */
|
|
29030
|
-
summary: external_exports.string(),
|
|
29031
|
-
orderIndex: external_exports.number().default(0),
|
|
29032
|
-
createdAt: external_exports.string(),
|
|
29033
|
-
updatedAt: external_exports.string()
|
|
29034
|
-
});
|
|
29035
|
-
var StoryCheckpointSummarySchema = CheckpointSummarySchema.extend({
|
|
29036
|
-
storyId: external_exports.string()
|
|
29037
|
-
});
|
|
29038
|
-
|
|
29039
|
-
// ../types/src/sessions.ts
|
|
29040
|
-
init_zod();
|
|
29041
|
-
var BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID = "__builtin_change_summary__";
|
|
29042
|
-
var SessionMetaSchema = external_exports.object({
|
|
29043
|
-
sessionId: external_exports.string(),
|
|
29044
|
-
workspaceId: external_exports.string(),
|
|
29045
|
-
title: external_exports.string().optional(),
|
|
29046
|
-
createdAt: external_exports.string(),
|
|
29047
|
-
updatedAt: external_exports.string()
|
|
29048
|
-
});
|
|
29049
|
-
var SessionPromptSchema = external_exports.object({
|
|
29050
|
-
id: external_exports.string(),
|
|
29051
|
-
sessionId: external_exports.string(),
|
|
29052
|
-
/** text | resource */
|
|
29053
|
-
type: external_exports.enum(["text", "resource"]).default("text"),
|
|
29054
|
-
text: external_exports.string().optional(),
|
|
29055
|
-
resourceUri: external_exports.string().optional(),
|
|
29056
|
-
createdAt: external_exports.string()
|
|
29057
|
-
});
|
|
29058
|
-
var SessionResponseSchema = external_exports.object({
|
|
29059
|
-
id: external_exports.string(),
|
|
29060
|
-
sessionId: external_exports.string(),
|
|
29061
|
-
promptId: external_exports.string(),
|
|
29062
|
-
/** message | completion */
|
|
29063
|
-
kind: external_exports.enum(["message", "completion"]),
|
|
29064
|
-
content: external_exports.string().optional(),
|
|
29065
|
-
/** For completion: stopReason etc. */
|
|
29066
|
-
stopReason: external_exports.string().optional(),
|
|
29067
|
-
createdAt: external_exports.string()
|
|
29068
|
-
});
|
|
29069
|
-
var SessionToolCallSchema = external_exports.object({
|
|
29070
|
-
id: external_exports.string(),
|
|
29071
|
-
sessionId: external_exports.string(),
|
|
29072
|
-
promptId: external_exports.string(),
|
|
29073
|
-
name: external_exports.string(),
|
|
29074
|
-
params: external_exports.record(external_exports.unknown()).optional(),
|
|
29075
|
-
result: external_exports.record(external_exports.unknown()).optional(),
|
|
29076
|
-
createdAt: external_exports.string()
|
|
29077
|
-
});
|
|
29078
|
-
var SessionThreadRefSchema = external_exports.object({
|
|
29079
|
-
sessionId: external_exports.string(),
|
|
29080
|
-
threadId: external_exports.string(),
|
|
29081
|
-
addedAt: external_exports.string()
|
|
29082
|
-
});
|
|
29083
|
-
|
|
29084
|
-
// ../types/src/change-summary-path.ts
|
|
29085
|
-
function normalizeRepoRelativePath(p) {
|
|
29086
|
-
let t = p.trim().replace(/\\/g, "/");
|
|
29087
|
-
while (t.startsWith("./")) t = t.slice(2);
|
|
29088
|
-
return t.replace(/\/+/g, "/");
|
|
28951
|
+
init_pathspec();
|
|
28952
|
+
function suffixPathsPlugin() {
|
|
28953
|
+
return {
|
|
28954
|
+
type: "spawn.args",
|
|
28955
|
+
action(data) {
|
|
28956
|
+
const prefix = [];
|
|
28957
|
+
let suffix;
|
|
28958
|
+
function append2(args) {
|
|
28959
|
+
(suffix = suffix || []).push(...args);
|
|
28960
|
+
}
|
|
28961
|
+
for (let i = 0; i < data.length; i++) {
|
|
28962
|
+
const param = data[i];
|
|
28963
|
+
if (isPathSpec(param)) {
|
|
28964
|
+
append2(toPaths(param));
|
|
28965
|
+
continue;
|
|
28966
|
+
}
|
|
28967
|
+
if (param === "--") {
|
|
28968
|
+
append2(
|
|
28969
|
+
data.slice(i + 1).flatMap((item) => isPathSpec(item) && toPaths(item) || item)
|
|
28970
|
+
);
|
|
28971
|
+
break;
|
|
28972
|
+
}
|
|
28973
|
+
prefix.push(param);
|
|
28974
|
+
}
|
|
28975
|
+
return !suffix ? prefix : [...prefix, "--", ...suffix.map(String)];
|
|
28976
|
+
}
|
|
28977
|
+
};
|
|
29089
28978
|
}
|
|
29090
|
-
|
|
29091
|
-
|
|
29092
|
-
|
|
29093
|
-
|
|
29094
|
-
const
|
|
29095
|
-
|
|
29096
|
-
|
|
29097
|
-
|
|
28979
|
+
init_utils();
|
|
28980
|
+
var Git = require_git();
|
|
28981
|
+
function gitInstanceFactory(baseDir, options) {
|
|
28982
|
+
const plugins = new PluginStore();
|
|
28983
|
+
const config2 = createInstanceConfig(
|
|
28984
|
+
baseDir && (typeof baseDir === "string" ? { baseDir } : baseDir) || {},
|
|
28985
|
+
options
|
|
28986
|
+
);
|
|
28987
|
+
if (!folderExists(config2.baseDir)) {
|
|
28988
|
+
throw new GitConstructError(
|
|
28989
|
+
config2,
|
|
28990
|
+
`Cannot use simple-git on a directory that does not exist`
|
|
28991
|
+
);
|
|
28992
|
+
}
|
|
28993
|
+
if (Array.isArray(config2.config)) {
|
|
28994
|
+
plugins.add(commandConfigPrefixingPlugin(config2.config));
|
|
28995
|
+
}
|
|
28996
|
+
plugins.add(blockUnsafeOperationsPlugin(config2.unsafe));
|
|
28997
|
+
plugins.add(suffixPathsPlugin());
|
|
28998
|
+
plugins.add(completionDetectionPlugin(config2.completion));
|
|
28999
|
+
config2.abort && plugins.add(abortPlugin(config2.abort));
|
|
29000
|
+
config2.progress && plugins.add(progressMonitorPlugin(config2.progress));
|
|
29001
|
+
config2.timeout && plugins.add(timeoutPlugin(config2.timeout));
|
|
29002
|
+
config2.spawnOptions && plugins.add(spawnOptionsPlugin(config2.spawnOptions));
|
|
29003
|
+
plugins.add(errorDetectionPlugin(errorDetectionHandler(true)));
|
|
29004
|
+
config2.errors && plugins.add(errorDetectionPlugin(config2.errors));
|
|
29005
|
+
customBinaryPlugin(plugins, config2.binary, config2.unsafe?.allowUnsafeCustomBinary);
|
|
29006
|
+
return new Git(config2, plugins);
|
|
29007
|
+
}
|
|
29008
|
+
init_git_response_error();
|
|
29009
|
+
var simpleGit = gitInstanceFactory;
|
|
29010
|
+
|
|
29011
|
+
// src/git/remote-origin-url.ts
|
|
29012
|
+
async function getRemoteOriginUrl(gitDir) {
|
|
29013
|
+
try {
|
|
29014
|
+
const git = simpleGit(gitDir);
|
|
29015
|
+
const remotes = await git.getRemotes(true);
|
|
29016
|
+
const list = Array.isArray(remotes) ? remotes : [];
|
|
29017
|
+
const origin = list.find((r) => r.name === "origin");
|
|
29018
|
+
if (!origin?.refs?.fetch && !origin?.refs?.push) return "";
|
|
29019
|
+
return (origin.refs.fetch ?? origin.refs.push ?? "").trim();
|
|
29020
|
+
} catch {
|
|
29021
|
+
return "";
|
|
29098
29022
|
}
|
|
29099
|
-
return null;
|
|
29100
29023
|
}
|
|
29101
29024
|
|
|
29102
|
-
//
|
|
29103
|
-
function
|
|
29104
|
-
|
|
29105
|
-
|
|
29025
|
+
// src/git/is-git-repo.ts
|
|
29026
|
+
async function isGitRepoDirectory(dirPath) {
|
|
29027
|
+
try {
|
|
29028
|
+
return await simpleGit(dirPath).checkIsRepo();
|
|
29029
|
+
} catch {
|
|
29030
|
+
return false;
|
|
29031
|
+
}
|
|
29106
29032
|
}
|
|
29107
|
-
|
|
29108
|
-
|
|
29109
|
-
|
|
29110
|
-
const
|
|
29111
|
-
|
|
29112
|
-
|
|
29033
|
+
|
|
29034
|
+
// src/git/discover-repos.ts
|
|
29035
|
+
async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
29036
|
+
const result = [];
|
|
29037
|
+
const cwdResolved = path6.resolve(cwd);
|
|
29038
|
+
if (await isGitRepoDirectory(cwdResolved)) {
|
|
29039
|
+
const remoteUrl = await getRemoteOriginUrl(cwdResolved);
|
|
29040
|
+
result.push({ absolutePath: cwdResolved, remoteUrl });
|
|
29041
|
+
}
|
|
29042
|
+
let entries;
|
|
29113
29043
|
try {
|
|
29114
|
-
|
|
29044
|
+
entries = fs7.readdirSync(cwdResolved, { withFileTypes: true });
|
|
29115
29045
|
} catch {
|
|
29116
|
-
|
|
29117
|
-
|
|
29118
|
-
|
|
29046
|
+
return result;
|
|
29047
|
+
}
|
|
29048
|
+
for (const ent of entries) {
|
|
29049
|
+
if (!ent.isDirectory()) continue;
|
|
29050
|
+
const childPath = path6.join(cwdResolved, ent.name);
|
|
29051
|
+
if (await isGitRepoDirectory(childPath)) {
|
|
29052
|
+
const remoteUrl = await getRemoteOriginUrl(childPath);
|
|
29053
|
+
result.push({ absolutePath: childPath, remoteUrl });
|
|
29054
|
+
}
|
|
29055
|
+
}
|
|
29056
|
+
return result;
|
|
29057
|
+
}
|
|
29058
|
+
async function discoverGitReposUnderRoot(rootPath) {
|
|
29059
|
+
const root = path6.resolve(rootPath);
|
|
29060
|
+
const roots = [];
|
|
29061
|
+
async function walk(dir) {
|
|
29062
|
+
if (await isGitRepoDirectory(dir)) {
|
|
29063
|
+
roots.push(path6.resolve(dir));
|
|
29064
|
+
return;
|
|
29065
|
+
}
|
|
29066
|
+
let entries;
|
|
29119
29067
|
try {
|
|
29120
|
-
|
|
29068
|
+
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
29121
29069
|
} catch {
|
|
29122
|
-
return
|
|
29070
|
+
return;
|
|
29071
|
+
}
|
|
29072
|
+
for (const ent of entries) {
|
|
29073
|
+
if (!ent.isDirectory() || ent.name === ".git") continue;
|
|
29074
|
+
await walk(path6.join(dir, ent.name));
|
|
29123
29075
|
}
|
|
29124
29076
|
}
|
|
29125
|
-
|
|
29126
|
-
|
|
29127
|
-
|
|
29128
|
-
|
|
29129
|
-
|
|
29130
|
-
|
|
29077
|
+
await walk(root);
|
|
29078
|
+
const uniq = [...new Set(roots)];
|
|
29079
|
+
const out = [];
|
|
29080
|
+
for (const p of uniq) {
|
|
29081
|
+
const remoteUrl = await getRemoteOriginUrl(p);
|
|
29082
|
+
out.push({ absolutePath: p, remoteUrl });
|
|
29131
29083
|
}
|
|
29132
|
-
|
|
29133
|
-
|
|
29134
|
-
|
|
29135
|
-
|
|
29136
|
-
|
|
29137
|
-
|
|
29138
|
-
|
|
29139
|
-
|
|
29140
|
-
|
|
29141
|
-
|
|
29084
|
+
return out;
|
|
29085
|
+
}
|
|
29086
|
+
|
|
29087
|
+
// src/git/pre-turn-snapshot.ts
|
|
29088
|
+
var execFileAsync5 = promisify6(execFile6);
|
|
29089
|
+
function snapshotsDirForCwd(agentCwd) {
|
|
29090
|
+
return path7.join(agentCwd, ".buildautomaton", "snapshots");
|
|
29091
|
+
}
|
|
29092
|
+
async function gitStashCreate(repoRoot, log2) {
|
|
29093
|
+
try {
|
|
29094
|
+
const { stdout } = await execFileAsync5("git", ["stash", "create"], {
|
|
29095
|
+
cwd: repoRoot,
|
|
29096
|
+
maxBuffer: 10 * 1024 * 1024
|
|
29097
|
+
});
|
|
29098
|
+
return stdout.trim();
|
|
29099
|
+
} catch (e) {
|
|
29100
|
+
log2(
|
|
29101
|
+
`[snapshot] Git stash create failed in ${repoRoot}: ${e instanceof Error ? e.message : String(e)}`
|
|
29102
|
+
);
|
|
29103
|
+
return "";
|
|
29104
|
+
}
|
|
29105
|
+
}
|
|
29106
|
+
async function gitRun(repoRoot, args, log2, label) {
|
|
29107
|
+
try {
|
|
29108
|
+
await execFileAsync5("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
|
|
29109
|
+
return { ok: true };
|
|
29110
|
+
} catch (e) {
|
|
29111
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
29112
|
+
log2(`[snapshot] Git ${label} failed in ${repoRoot}: ${msg}`);
|
|
29113
|
+
return { ok: false, error: msg };
|
|
29114
|
+
}
|
|
29115
|
+
}
|
|
29116
|
+
async function resolveSnapshotRepoRoots(options) {
|
|
29117
|
+
const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
|
|
29118
|
+
if (worktreePaths?.length) {
|
|
29119
|
+
const uniq = [...new Set(worktreePaths.map((p) => path7.resolve(p)))];
|
|
29120
|
+
return uniq;
|
|
29121
|
+
}
|
|
29122
|
+
try {
|
|
29123
|
+
const repos = await discoverGitReposUnderRoot(fallbackCwd);
|
|
29124
|
+
const mapped = repos.map((r) => r.absolutePath);
|
|
29125
|
+
const sid = sessionId?.trim();
|
|
29126
|
+
if (sid) {
|
|
29127
|
+
const filtered = mapped.filter((root) => path7.basename(root) === sid);
|
|
29128
|
+
if (filtered.length > 0) return filtered;
|
|
29129
|
+
}
|
|
29130
|
+
return mapped;
|
|
29131
|
+
} catch (e) {
|
|
29132
|
+
log2(`[snapshot] Discover repositories failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
29133
|
+
return [];
|
|
29134
|
+
}
|
|
29135
|
+
}
|
|
29136
|
+
async function capturePreTurnSnapshot(options) {
|
|
29137
|
+
const { runId, repoRoots, agentCwd, log: log2 } = options;
|
|
29138
|
+
if (!runId || !repoRoots.length) {
|
|
29139
|
+
return { ok: false, error: "No git repos to snapshot" };
|
|
29140
|
+
}
|
|
29141
|
+
const repos = [];
|
|
29142
|
+
for (const root of repoRoots) {
|
|
29143
|
+
const stashSha = await gitStashCreate(root, log2);
|
|
29144
|
+
repos.push({ path: root, stashSha });
|
|
29145
|
+
}
|
|
29146
|
+
const dir = snapshotsDirForCwd(agentCwd);
|
|
29147
|
+
try {
|
|
29148
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
29149
|
+
} catch (e) {
|
|
29150
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
29151
|
+
}
|
|
29152
|
+
const payload = {
|
|
29153
|
+
runId,
|
|
29154
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
29155
|
+
repos
|
|
29156
|
+
};
|
|
29157
|
+
const filePath = path7.join(dir, `${runId}.json`);
|
|
29158
|
+
try {
|
|
29159
|
+
fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
29160
|
+
} catch (e) {
|
|
29161
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
29162
|
+
}
|
|
29163
|
+
const repoList = repos.map((r) => r.path).join(", ");
|
|
29164
|
+
log2(
|
|
29165
|
+
`[snapshot] Saved pre-turn snapshot ${runId.slice(0, 8)}\u2026 (${repos.length} repo(s)): ${repoList}`
|
|
29166
|
+
);
|
|
29167
|
+
return { ok: true, filePath, repos };
|
|
29168
|
+
}
|
|
29169
|
+
async function applyPreTurnSnapshot(filePath, log2) {
|
|
29170
|
+
let data;
|
|
29171
|
+
try {
|
|
29172
|
+
const raw = fs8.readFileSync(filePath, "utf8");
|
|
29173
|
+
data = JSON.parse(raw);
|
|
29174
|
+
} catch (e) {
|
|
29175
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
29176
|
+
}
|
|
29177
|
+
if (!Array.isArray(data.repos)) {
|
|
29178
|
+
return { ok: false, error: "Invalid snapshot file" };
|
|
29142
29179
|
}
|
|
29143
|
-
|
|
29180
|
+
for (const r of data.repos) {
|
|
29181
|
+
if (!r.path) continue;
|
|
29182
|
+
const reset = await gitRun(r.path, ["reset", "--hard", "HEAD"], log2, "reset --hard");
|
|
29183
|
+
if (!reset.ok) return reset;
|
|
29184
|
+
const clean = await gitRun(r.path, ["clean", "-fd"], log2, "clean -fd");
|
|
29185
|
+
if (!clean.ok) return clean;
|
|
29186
|
+
if (r.stashSha) {
|
|
29187
|
+
const ap = await gitRun(r.path, ["stash", "apply", r.stashSha], log2, "stash apply");
|
|
29188
|
+
if (!ap.ok) return ap;
|
|
29189
|
+
}
|
|
29190
|
+
}
|
|
29191
|
+
log2(`[snapshot] Restored pre-turn state for ${data.runId.slice(0, 8)}\u2026`);
|
|
29192
|
+
return { ok: true };
|
|
29193
|
+
}
|
|
29194
|
+
function snapshotFilePath(agentCwd, runId) {
|
|
29195
|
+
return path7.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
|
|
29144
29196
|
}
|
|
29145
29197
|
|
|
29146
|
-
//
|
|
29147
|
-
var
|
|
29148
|
-
|
|
29149
|
-
|
|
29150
|
-
|
|
29151
|
-
|
|
29152
|
-
|
|
29198
|
+
// src/git/session-git-queue.ts
|
|
29199
|
+
var execFileAsync6 = promisify7(execFile7);
|
|
29200
|
+
var MAX_FULL_FILE_TEXT_BYTES = 512 * 1024;
|
|
29201
|
+
async function readWorkspaceFileAsUtf8(absPath) {
|
|
29202
|
+
try {
|
|
29203
|
+
const st = await stat(absPath);
|
|
29204
|
+
if (!st.isFile() || st.size > MAX_FULL_FILE_TEXT_BYTES) return void 0;
|
|
29205
|
+
return await readFile(absPath, "utf8");
|
|
29206
|
+
} catch {
|
|
29207
|
+
return void 0;
|
|
29208
|
+
}
|
|
29153
29209
|
}
|
|
29154
|
-
function
|
|
29155
|
-
const
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
""
|
|
29160
|
-
|
|
29161
|
-
|
|
29162
|
-
|
|
29163
|
-
|
|
29164
|
-
|
|
29165
|
-
|
|
29166
|
-
|
|
29167
|
-
|
|
29168
|
-
|
|
29169
|
-
|
|
29170
|
-
|
|
29171
|
-
|
|
29172
|
-
|
|
29173
|
-
|
|
29174
|
-
|
|
29175
|
-
|
|
29176
|
-
|
|
29177
|
-
|
|
29178
|
-
|
|
29179
|
-
|
|
29180
|
-
|
|
29181
|
-
|
|
29182
|
-
|
|
29183
|
-
|
|
29184
|
-
|
|
29185
|
-
lines.push("");
|
|
29210
|
+
async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
29211
|
+
const { sessionId, runId, agentCwd, sendSessionUpdate, log: log2 } = options;
|
|
29212
|
+
const filePath = snapshotFilePath(agentCwd, runId);
|
|
29213
|
+
let data;
|
|
29214
|
+
try {
|
|
29215
|
+
const raw = await readFile(filePath, "utf8");
|
|
29216
|
+
data = JSON.parse(raw);
|
|
29217
|
+
} catch (e) {
|
|
29218
|
+
log2(
|
|
29219
|
+
`[session-git-queue] No pre-turn snapshot for run ${runId.slice(0, 8)}\u2026: ${e instanceof Error ? e.message : String(e)}`
|
|
29220
|
+
);
|
|
29221
|
+
return;
|
|
29222
|
+
}
|
|
29223
|
+
if (!Array.isArray(data.repos) || !data.repos.length) {
|
|
29224
|
+
log2(`[session-git-queue] Empty repos in snapshot ${runId.slice(0, 8)}\u2026; skipping aggregate diff.`);
|
|
29225
|
+
return;
|
|
29226
|
+
}
|
|
29227
|
+
const multiRepo = data.repos.length > 1;
|
|
29228
|
+
for (const repo of data.repos) {
|
|
29229
|
+
if (!repo.stashSha) continue;
|
|
29230
|
+
let namesRaw;
|
|
29231
|
+
try {
|
|
29232
|
+
const { stdout } = await execFileAsync6("git", ["diff", "--name-only", repo.stashSha], {
|
|
29233
|
+
cwd: repo.path,
|
|
29234
|
+
maxBuffer: 10 * 1024 * 1024
|
|
29235
|
+
});
|
|
29236
|
+
namesRaw = stdout;
|
|
29237
|
+
} catch (e) {
|
|
29238
|
+
log2(
|
|
29239
|
+
`[session-git-queue] Git diff --name-only failed in ${repo.path}: ${e instanceof Error ? e.message : String(e)}`
|
|
29240
|
+
);
|
|
29186
29241
|
continue;
|
|
29187
29242
|
}
|
|
29188
|
-
|
|
29189
|
-
|
|
29190
|
-
|
|
29191
|
-
|
|
29192
|
-
|
|
29193
|
-
|
|
29194
|
-
|
|
29195
|
-
|
|
29196
|
-
|
|
29197
|
-
|
|
29198
|
-
|
|
29243
|
+
const lines = namesRaw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
29244
|
+
const slug = path8.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
|
|
29245
|
+
for (const rel of lines) {
|
|
29246
|
+
if (rel.includes("..")) continue;
|
|
29247
|
+
try {
|
|
29248
|
+
const { stdout: patchContent } = await execFileAsync6(
|
|
29249
|
+
"git",
|
|
29250
|
+
["diff", "--no-color", repo.stashSha, "--", rel],
|
|
29251
|
+
{
|
|
29252
|
+
cwd: repo.path,
|
|
29253
|
+
maxBuffer: 50 * 1024 * 1024
|
|
29254
|
+
}
|
|
29255
|
+
);
|
|
29256
|
+
if (!patchContent.trim()) continue;
|
|
29257
|
+
const displayPath = multiRepo ? `${slug}/${rel}` : rel;
|
|
29258
|
+
const workspaceFilePath = path8.join(repo.path, rel);
|
|
29259
|
+
const newText = await readWorkspaceFileAsUtf8(workspaceFilePath);
|
|
29260
|
+
sendSessionUpdate({
|
|
29261
|
+
type: "session_file_change",
|
|
29262
|
+
sessionId,
|
|
29263
|
+
runId,
|
|
29264
|
+
path: displayPath,
|
|
29265
|
+
patchContent,
|
|
29266
|
+
...newText !== void 0 ? { newText } : {}
|
|
29267
|
+
});
|
|
29268
|
+
} catch (e) {
|
|
29269
|
+
log2(
|
|
29270
|
+
`[session-git-queue] Git diff failed for ${rel}: ${e instanceof Error ? e.message : String(e)}`
|
|
29271
|
+
);
|
|
29272
|
+
}
|
|
29199
29273
|
}
|
|
29200
|
-
lines.push("");
|
|
29201
|
-
}
|
|
29202
|
-
return lines.join("\n");
|
|
29203
|
-
}
|
|
29204
|
-
|
|
29205
|
-
// ../types/src/dedupe-session-file-changes-by-path.ts
|
|
29206
|
-
function defaultRichness(c) {
|
|
29207
|
-
const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
|
|
29208
|
-
const nt = typeof c.newText === "string" ? c.newText.length : 0;
|
|
29209
|
-
const ot = typeof c.oldText === "string" ? c.oldText.length : 0;
|
|
29210
|
-
const dir = c.directoryRemoved === true ? 8 : 0;
|
|
29211
|
-
return (patch > 0 ? 4 : 0) + (nt > 0 ? 2 : 0) + (ot > 0 ? 1 : 0) + dir;
|
|
29212
|
-
}
|
|
29213
|
-
function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichness(item)) {
|
|
29214
|
-
const byPath = /* @__PURE__ */ new Map();
|
|
29215
|
-
for (const item of items) {
|
|
29216
|
-
const p = typeof item.path === "string" ? item.path.trim() : "";
|
|
29217
|
-
if (!p) continue;
|
|
29218
|
-
const prev = byPath.get(p);
|
|
29219
|
-
if (!prev || richness(item) >= richness(prev)) byPath.set(p, item);
|
|
29220
29274
|
}
|
|
29221
|
-
return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
|
|
29222
29275
|
}
|
|
29223
29276
|
|
|
29224
|
-
// ../types/src/artifacts.ts
|
|
29225
|
-
init_zod();
|
|
29226
|
-
var ArtifactMetaSchema = external_exports.object({
|
|
29227
|
-
artifactId: external_exports.string(),
|
|
29228
|
-
workspaceId: external_exports.string(),
|
|
29229
|
-
/** Slug for permalink: /workspaces/:wid/artifacts/:slug */
|
|
29230
|
-
permalinkSlug: external_exports.string(),
|
|
29231
|
-
title: external_exports.string(),
|
|
29232
|
-
/** e.g. summary_report, build_log */
|
|
29233
|
-
type: external_exports.string().default("report"),
|
|
29234
|
-
/** Optional session that produced this artifact */
|
|
29235
|
-
sessionId: external_exports.string().nullable(),
|
|
29236
|
-
createdAt: external_exports.string(),
|
|
29237
|
-
updatedAt: external_exports.string()
|
|
29238
|
-
});
|
|
29239
|
-
|
|
29240
|
-
// ../types/src/templates.ts
|
|
29241
|
-
init_zod();
|
|
29242
|
-
var TemplateMetaSchema = external_exports.object({
|
|
29243
|
-
templateId: external_exports.string(),
|
|
29244
|
-
workspaceId: external_exports.string(),
|
|
29245
|
-
name: external_exports.string(),
|
|
29246
|
-
/** e.g. summary_report, build_log */
|
|
29247
|
-
artifactType: external_exports.string().optional(),
|
|
29248
|
-
createdAt: external_exports.string(),
|
|
29249
|
-
updatedAt: external_exports.string()
|
|
29250
|
-
});
|
|
29251
|
-
|
|
29252
|
-
// ../types/src/git-repos.ts
|
|
29253
|
-
init_zod();
|
|
29254
|
-
var GitRepoMetaSchema = external_exports.object({
|
|
29255
|
-
/** Stable id for the repo (e.g. hash of normalized canonical URL). Used for DO idFromName. */
|
|
29256
|
-
repoId: external_exports.string(),
|
|
29257
|
-
/** Canonical external URL (e.g. https://github.com/org/repo). Normalize before storing. */
|
|
29258
|
-
canonicalUrl: external_exports.string().url(),
|
|
29259
|
-
/** Optional workspace this repo was first linked in. */
|
|
29260
|
-
workspaceId: external_exports.string().nullable(),
|
|
29261
|
-
displayName: external_exports.string().optional(),
|
|
29262
|
-
createdAt: external_exports.string(),
|
|
29263
|
-
updatedAt: external_exports.string()
|
|
29264
|
-
});
|
|
29265
|
-
|
|
29266
29277
|
// src/agents/acp/put-summarize-change-summaries.ts
|
|
29267
29278
|
async function putEncryptedChangeSummaryRows(params) {
|
|
29268
29279
|
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
@@ -29412,6 +29423,8 @@ async function sendPromptToAgent(options) {
|
|
|
29412
29423
|
log: log2
|
|
29413
29424
|
});
|
|
29414
29425
|
const errStr = typeof result.error === "string" ? result.error : void 0;
|
|
29426
|
+
const resultStop = typeof result.stopReason === "string" ? result.stopReason.trim() : "";
|
|
29427
|
+
const cancelledByAgent = resultStop.toLowerCase() === "cancelled" || errStr != null && isUserEndedSessionTurnErrorText(errStr);
|
|
29415
29428
|
sendResult2({
|
|
29416
29429
|
type: "prompt_result",
|
|
29417
29430
|
id: promptId,
|
|
@@ -29419,12 +29432,17 @@ async function sendPromptToAgent(options) {
|
|
|
29419
29432
|
...runId ? { runId } : {},
|
|
29420
29433
|
...result,
|
|
29421
29434
|
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
29422
|
-
...augmentPromptResultAuthFields(agentType, errStr)
|
|
29435
|
+
...augmentPromptResultAuthFields(agentType, errStr),
|
|
29436
|
+
...!result.success && cancelledByAgent ? { stopReason: "cancelled" } : {}
|
|
29423
29437
|
});
|
|
29424
29438
|
if (!result.success) {
|
|
29425
|
-
|
|
29426
|
-
|
|
29427
|
-
|
|
29439
|
+
if (cancelledByAgent) {
|
|
29440
|
+
log2("[Agent] Run ended after stop request (stopped by user).");
|
|
29441
|
+
} else {
|
|
29442
|
+
log2(
|
|
29443
|
+
`[Agent] Prompt did not run successfully on the agent (no successful start/completion): ${result.error ?? "Unknown error"}`
|
|
29444
|
+
);
|
|
29445
|
+
}
|
|
29428
29446
|
}
|
|
29429
29447
|
} catch (err) {
|
|
29430
29448
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -29504,7 +29522,8 @@ async function createClaudeCodeAcpClient(options) {
|
|
|
29504
29522
|
...options,
|
|
29505
29523
|
command,
|
|
29506
29524
|
/** Claude-based agents sometimes ignore `session/cancel`; unblocks stop / stuck prompt. */
|
|
29507
|
-
|
|
29525
|
+
/** Claude Code can be slow to honor ACP `session/cancel`; give the subprocess a moment before SIGKILL (see ACP prompt-turn cancellation). */
|
|
29526
|
+
killSubprocessAfterCancelMs: options.killSubprocessAfterCancelMs ?? 2500
|
|
29508
29527
|
});
|
|
29509
29528
|
}
|
|
29510
29529
|
|
|
@@ -33768,7 +33787,6 @@ var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
|
33768
33787
|
"session_archived",
|
|
33769
33788
|
"session_discarded",
|
|
33770
33789
|
"revert_turn_snapshot",
|
|
33771
|
-
"cancel_run",
|
|
33772
33790
|
"cursor_request_response",
|
|
33773
33791
|
"skill_call",
|
|
33774
33792
|
"file_browser_request",
|
|
@@ -33838,6 +33856,9 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
33838
33856
|
handleBridgeAgentConfig(msg, deps);
|
|
33839
33857
|
};
|
|
33840
33858
|
|
|
33859
|
+
// src/prompt-turn-queue/runner.ts
|
|
33860
|
+
import fs28 from "node:fs";
|
|
33861
|
+
|
|
33841
33862
|
// src/prompt-turn-queue/client-report.ts
|
|
33842
33863
|
function sendPromptQueueClientReport(ws, queues) {
|
|
33843
33864
|
if (!ws) return false;
|
|
@@ -33872,6 +33893,14 @@ function queueStateFilePath(queueKey) {
|
|
|
33872
33893
|
}
|
|
33873
33894
|
|
|
33874
33895
|
// src/prompt-turn-queue/disk-store.ts
|
|
33896
|
+
var MERGEABLE_SERVER_STATES = /* @__PURE__ */ new Set([
|
|
33897
|
+
"queued",
|
|
33898
|
+
"requeued",
|
|
33899
|
+
"requeued_with_revert",
|
|
33900
|
+
"cancel_requested",
|
|
33901
|
+
"stopping",
|
|
33902
|
+
"discarded"
|
|
33903
|
+
]);
|
|
33875
33904
|
function parsePersistedQueueFile(raw) {
|
|
33876
33905
|
try {
|
|
33877
33906
|
const o = JSON.parse(raw);
|
|
@@ -33908,7 +33937,7 @@ function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
|
33908
33937
|
const lastClientState = o.lastClientState ?? null;
|
|
33909
33938
|
const payload = o.payload && typeof o.payload === "object" ? o.payload : {};
|
|
33910
33939
|
if (!turnId || !sessionId) continue;
|
|
33911
|
-
if (serverState
|
|
33940
|
+
if (!MERGEABLE_SERVER_STATES.has(String(serverState))) continue;
|
|
33912
33941
|
const old = prev?.turns.find((t) => t.turnId === turnId);
|
|
33913
33942
|
const mergedClient = old?.lastClientState === "running" && lastClientState == null ? "running" : lastClientState;
|
|
33914
33943
|
turns.push({
|
|
@@ -33926,11 +33955,17 @@ function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
|
33926
33955
|
|
|
33927
33956
|
// src/prompt-turn-queue/runner.ts
|
|
33928
33957
|
var runIdToQueueKey = /* @__PURE__ */ new Map();
|
|
33958
|
+
function isRunnableServerState(s) {
|
|
33959
|
+
return s === "queued" || s === "requeued" || s === "requeued_with_revert";
|
|
33960
|
+
}
|
|
33929
33961
|
function pickNextRunnableTurn(turns) {
|
|
33930
33962
|
for (const t of turns) {
|
|
33931
33963
|
if (t.serverState === "discarded" || t.serverState === "stopping") continue;
|
|
33932
|
-
if (t.serverState
|
|
33933
|
-
if (t.
|
|
33964
|
+
if (t.serverState === "cancel_requested") continue;
|
|
33965
|
+
if (!isRunnableServerState(t.serverState)) continue;
|
|
33966
|
+
if (t.lastClientState === "running" || t.lastClientState === "stopped" || t.lastClientState === "failed" || t.lastClientState === "cancelled") {
|
|
33967
|
+
continue;
|
|
33968
|
+
}
|
|
33934
33969
|
return t;
|
|
33935
33970
|
}
|
|
33936
33971
|
return null;
|
|
@@ -33938,6 +33973,25 @@ function pickNextRunnableTurn(turns) {
|
|
|
33938
33973
|
function hasRunningTurn(turns) {
|
|
33939
33974
|
return turns.some((t) => t.lastClientState === "running");
|
|
33940
33975
|
}
|
|
33976
|
+
async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
33977
|
+
if (next.serverState !== "requeued_with_revert") return true;
|
|
33978
|
+
const sid = next.sessionId;
|
|
33979
|
+
const pl = next.payload;
|
|
33980
|
+
const tid = typeof pl.snapshotRevertTurnId === "string" && pl.snapshotRevertTurnId.trim() !== "" ? pl.snapshotRevertTurnId.trim() : next.turnId;
|
|
33981
|
+
const agentBase = deps.sessionWorktreeManager.getSessionWorktreeRootForSession(sid) ?? getBridgeRoot();
|
|
33982
|
+
const file2 = snapshotFilePath(agentBase, tid);
|
|
33983
|
+
if (!fs28.existsSync(file2)) {
|
|
33984
|
+
deps.log(
|
|
33985
|
+
`[Queue] requeued_with_revert: no pre-turn snapshot for ${tid.slice(0, 8)}\u2026; continuing without revert.`
|
|
33986
|
+
);
|
|
33987
|
+
return true;
|
|
33988
|
+
}
|
|
33989
|
+
const res = await applyPreTurnSnapshot(file2, deps.log);
|
|
33990
|
+
if (!res.ok) {
|
|
33991
|
+
deps.log(`[Queue] requeued_with_revert: snapshot apply failed: ${res.error ?? "unknown"}`);
|
|
33992
|
+
}
|
|
33993
|
+
return res.ok;
|
|
33994
|
+
}
|
|
33941
33995
|
function dispatchLocalPrompt(next, deps) {
|
|
33942
33996
|
const pl = next.payload;
|
|
33943
33997
|
const rawParent = pl["sessionParent"];
|
|
@@ -33960,7 +34014,7 @@ function dispatchLocalPrompt(next, deps) {
|
|
|
33960
34014
|
};
|
|
33961
34015
|
handleBridgePrompt(msg, deps);
|
|
33962
34016
|
}
|
|
33963
|
-
function applyPromptQueueStateFromServer(msg, deps) {
|
|
34017
|
+
async function applyPromptQueueStateFromServer(msg, deps) {
|
|
33964
34018
|
const raw = msg.queues;
|
|
33965
34019
|
if (!raw || typeof raw !== "object") return;
|
|
33966
34020
|
const getWs = deps.getWs;
|
|
@@ -33969,6 +34023,40 @@ function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
33969
34023
|
const file2 = mergeServerQueueSnapshot(queueKey, serverTurns);
|
|
33970
34024
|
writePersistedQueue(file2);
|
|
33971
34025
|
}
|
|
34026
|
+
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
34027
|
+
if (!Array.isArray(serverTurns)) continue;
|
|
34028
|
+
const file2 = readPersistedQueue(queueKey);
|
|
34029
|
+
if (!file2) continue;
|
|
34030
|
+
for (const running of file2.turns.filter((t) => t.lastClientState === "running")) {
|
|
34031
|
+
runIdToQueueKey.set(running.turnId, queueKey);
|
|
34032
|
+
}
|
|
34033
|
+
}
|
|
34034
|
+
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
34035
|
+
if (!Array.isArray(serverTurns)) continue;
|
|
34036
|
+
const file2 = readPersistedQueue(queueKey);
|
|
34037
|
+
if (!file2) continue;
|
|
34038
|
+
const cancelRow = file2.turns.find((t) => t.serverState === "cancel_requested" && t.lastClientState === "running");
|
|
34039
|
+
if (cancelRow) {
|
|
34040
|
+
const localCancelHandled = await deps.acpManager.cancelRun(cancelRow.turnId);
|
|
34041
|
+
if (!localCancelHandled) {
|
|
34042
|
+
deps.log(
|
|
34043
|
+
`[Queue] server cancel_requested for ${cancelRow.turnId.slice(0, 8)}\u2026 but no local agent run is active (e.g. after CLI restart); marking cancelled and notifying bridge.`
|
|
34044
|
+
);
|
|
34045
|
+
finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalClientState: "cancelled" });
|
|
34046
|
+
const ws = deps.getWs();
|
|
34047
|
+
if (ws && cancelRow.sessionId) {
|
|
34048
|
+
sendWsMessage(ws, {
|
|
34049
|
+
type: "prompt_result",
|
|
34050
|
+
sessionId: cancelRow.sessionId,
|
|
34051
|
+
runId: cancelRow.turnId,
|
|
34052
|
+
success: false,
|
|
34053
|
+
error: "Stopped by user",
|
|
34054
|
+
stopReason: "cancelled"
|
|
34055
|
+
});
|
|
34056
|
+
}
|
|
34057
|
+
}
|
|
34058
|
+
}
|
|
34059
|
+
}
|
|
33972
34060
|
const report = {};
|
|
33973
34061
|
const startedThisTick = /* @__PURE__ */ new Set();
|
|
33974
34062
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
@@ -33978,6 +34066,12 @@ function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
33978
34066
|
if (hasRunningTurn(file2.turns)) continue;
|
|
33979
34067
|
const next = pickNextRunnableTurn(file2.turns);
|
|
33980
34068
|
if (!next) continue;
|
|
34069
|
+
if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
|
|
34070
|
+
next.lastClientState = "failed";
|
|
34071
|
+
writePersistedQueue(file2);
|
|
34072
|
+
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, clientState: "failed" }] });
|
|
34073
|
+
continue;
|
|
34074
|
+
}
|
|
33981
34075
|
next.lastClientState = "running";
|
|
33982
34076
|
writePersistedQueue(file2);
|
|
33983
34077
|
runIdToQueueKey.set(next.turnId, queueKey);
|
|
@@ -33997,18 +34091,19 @@ function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
33997
34091
|
dispatchLocalPrompt(running, deps);
|
|
33998
34092
|
}
|
|
33999
34093
|
}
|
|
34000
|
-
function finalizePromptTurnOnBridge(getWs, runId, success2) {
|
|
34001
|
-
if (!runId) return;
|
|
34094
|
+
function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
34095
|
+
if (!runId) return false;
|
|
34002
34096
|
const queueKey = runIdToQueueKey.get(runId);
|
|
34003
34097
|
runIdToQueueKey.delete(runId);
|
|
34004
|
-
if (!queueKey) return;
|
|
34098
|
+
if (!queueKey) return false;
|
|
34005
34099
|
const f = readPersistedQueue(queueKey);
|
|
34006
|
-
if (!f) return;
|
|
34100
|
+
if (!f) return false;
|
|
34007
34101
|
const t = f.turns.find((x) => x.turnId === runId);
|
|
34008
|
-
if (!t) return;
|
|
34009
|
-
t.lastClientState = success2 ? "stopped" : "failed";
|
|
34102
|
+
if (!t) return false;
|
|
34103
|
+
t.lastClientState = opts?.terminalClientState ?? (success2 ? "stopped" : "failed");
|
|
34010
34104
|
writePersistedQueue(f);
|
|
34011
34105
|
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, clientState: t.lastClientState }] });
|
|
34106
|
+
return true;
|
|
34012
34107
|
}
|
|
34013
34108
|
|
|
34014
34109
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
@@ -34025,7 +34120,14 @@ function createBridgePromptSenders(deps, getWs) {
|
|
|
34025
34120
|
const encryptedFields = result.type === "prompt_result" && !skipEncryptForChangeSummaryFollowUp ? ["output", "error"] : [];
|
|
34026
34121
|
sendBridgeMessage(result, encryptedFields);
|
|
34027
34122
|
if (result.type === "prompt_result") {
|
|
34028
|
-
|
|
34123
|
+
const pr = result;
|
|
34124
|
+
const cancelled = pr.stopReason === "cancelled";
|
|
34125
|
+
finalizePromptTurnOnBridge(
|
|
34126
|
+
getWs,
|
|
34127
|
+
typeof pr.runId === "string" ? pr.runId : void 0,
|
|
34128
|
+
pr.success === true,
|
|
34129
|
+
cancelled ? { terminalClientState: "cancelled" } : void 0
|
|
34130
|
+
);
|
|
34029
34131
|
}
|
|
34030
34132
|
};
|
|
34031
34133
|
const sendSessionUpdate = (payload) => {
|
|
@@ -34290,34 +34392,9 @@ var handlePromptMessage = (msg, deps) => {
|
|
|
34290
34392
|
|
|
34291
34393
|
// src/bridge/routing/handlers/prompt-queue-state.ts
|
|
34292
34394
|
var handlePromptQueueStateMessage = (msg, deps) => {
|
|
34293
|
-
applyPromptQueueStateFromServer(msg, deps)
|
|
34294
|
-
};
|
|
34295
|
-
|
|
34296
|
-
// src/agents/acp/from-bridge/handle-bridge-cancel-run.ts
|
|
34297
|
-
async function handleBridgeCancelRun(msg, { log: log2, acpManager, getWs }) {
|
|
34298
|
-
const runId = msg.runId;
|
|
34299
|
-
if (!runId) return;
|
|
34300
|
-
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId.trim() : "";
|
|
34301
|
-
const sent = await acpManager.cancelRun(runId);
|
|
34302
|
-
if (sent) return;
|
|
34303
|
-
log2(`[Agent] Cancel: no local run for ${runId.slice(0, 8)}\u2026 \u2014 reporting stopped to cloud.`);
|
|
34304
|
-
const ws = getWs();
|
|
34305
|
-
if (!ws || ws.readyState !== 1) return;
|
|
34306
|
-
sendWsMessage(ws, {
|
|
34307
|
-
type: "prompt_result",
|
|
34308
|
-
id: `cancel-nack-${runId}`,
|
|
34309
|
-
runId,
|
|
34310
|
-
...sessionId ? { sessionId } : {},
|
|
34311
|
-
success: false,
|
|
34312
|
-
error: "Stopped by user",
|
|
34313
|
-
stopReason: "no_local_run"
|
|
34395
|
+
void applyPromptQueueStateFromServer(msg, deps).catch((err) => {
|
|
34396
|
+
deps.log(`[Queue] applyPromptQueueStateFromServer failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
34314
34397
|
});
|
|
34315
|
-
finalizePromptTurnOnBridge(getWs, runId, false);
|
|
34316
|
-
}
|
|
34317
|
-
|
|
34318
|
-
// src/bridge/routing/handlers/cancel-run.ts
|
|
34319
|
-
var handleCancelRunMessage = (msg, deps) => {
|
|
34320
|
-
void handleBridgeCancelRun(msg, deps);
|
|
34321
34398
|
};
|
|
34322
34399
|
|
|
34323
34400
|
// src/agents/acp/from-bridge/handle-bridge-cursor-request-response.ts
|
|
@@ -34356,7 +34433,7 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
34356
34433
|
};
|
|
34357
34434
|
|
|
34358
34435
|
// src/files/list-dir.ts
|
|
34359
|
-
import
|
|
34436
|
+
import fs29 from "node:fs";
|
|
34360
34437
|
import path31 from "node:path";
|
|
34361
34438
|
|
|
34362
34439
|
// src/files/ensure-under-cwd.ts
|
|
@@ -34378,7 +34455,7 @@ async function listDirAsync(relativePath) {
|
|
|
34378
34455
|
return { error: "Path is outside working directory" };
|
|
34379
34456
|
}
|
|
34380
34457
|
try {
|
|
34381
|
-
const names = await
|
|
34458
|
+
const names = await fs29.promises.readdir(resolved, { withFileTypes: true });
|
|
34382
34459
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
34383
34460
|
const entries = [];
|
|
34384
34461
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -34391,7 +34468,7 @@ async function listDirAsync(relativePath) {
|
|
|
34391
34468
|
let isDir = d.isDirectory();
|
|
34392
34469
|
if (d.isSymbolicLink()) {
|
|
34393
34470
|
try {
|
|
34394
|
-
const targetStat = await
|
|
34471
|
+
const targetStat = await fs29.promises.stat(fullPath);
|
|
34395
34472
|
isDir = targetStat.isDirectory();
|
|
34396
34473
|
} catch {
|
|
34397
34474
|
isDir = false;
|
|
@@ -34416,25 +34493,25 @@ async function listDirAsync(relativePath) {
|
|
|
34416
34493
|
}
|
|
34417
34494
|
|
|
34418
34495
|
// src/files/read-file.ts
|
|
34419
|
-
import
|
|
34496
|
+
import fs30 from "node:fs";
|
|
34420
34497
|
import { StringDecoder } from "node:string_decoder";
|
|
34421
34498
|
function resolveFilePath(relativePath) {
|
|
34422
34499
|
const resolved = ensureUnderCwd(relativePath, getBridgeRoot());
|
|
34423
34500
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
34424
34501
|
let real;
|
|
34425
34502
|
try {
|
|
34426
|
-
real =
|
|
34503
|
+
real = fs30.realpathSync(resolved);
|
|
34427
34504
|
} catch {
|
|
34428
34505
|
real = resolved;
|
|
34429
34506
|
}
|
|
34430
|
-
const stat2 =
|
|
34507
|
+
const stat2 = fs30.statSync(real);
|
|
34431
34508
|
if (!stat2.isFile()) return { error: "Not a file" };
|
|
34432
34509
|
return real;
|
|
34433
34510
|
}
|
|
34434
34511
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
34435
34512
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
34436
|
-
const fileSize =
|
|
34437
|
-
const fd =
|
|
34513
|
+
const fileSize = fs30.statSync(filePath).size;
|
|
34514
|
+
const fd = fs30.openSync(filePath, "r");
|
|
34438
34515
|
const bufSize = 64 * 1024;
|
|
34439
34516
|
const buf = Buffer.alloc(bufSize);
|
|
34440
34517
|
const decoder = new StringDecoder("utf8");
|
|
@@ -34447,7 +34524,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
34447
34524
|
let line0Accum = "";
|
|
34448
34525
|
try {
|
|
34449
34526
|
let bytesRead;
|
|
34450
|
-
while (!done && (bytesRead =
|
|
34527
|
+
while (!done && (bytesRead = fs30.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
34451
34528
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
34452
34529
|
partial2 = "";
|
|
34453
34530
|
let lineStart = 0;
|
|
@@ -34582,7 +34659,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
34582
34659
|
}
|
|
34583
34660
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
34584
34661
|
} finally {
|
|
34585
|
-
|
|
34662
|
+
fs30.closeSync(fd);
|
|
34586
34663
|
}
|
|
34587
34664
|
}
|
|
34588
34665
|
function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -34593,8 +34670,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
34593
34670
|
if (hasRange) {
|
|
34594
34671
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
34595
34672
|
}
|
|
34596
|
-
const stat2 =
|
|
34597
|
-
const raw =
|
|
34673
|
+
const stat2 = fs30.statSync(result);
|
|
34674
|
+
const raw = fs30.readFileSync(result, "utf8");
|
|
34598
34675
|
const lines = raw.split(/\r?\n/);
|
|
34599
34676
|
return { content: raw, totalLines: lines.length, size: stat2.size };
|
|
34600
34677
|
} catch (err) {
|
|
@@ -34712,7 +34789,7 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
34712
34789
|
}
|
|
34713
34790
|
|
|
34714
34791
|
// src/skills/install-remote-skills.ts
|
|
34715
|
-
import
|
|
34792
|
+
import fs31 from "node:fs";
|
|
34716
34793
|
import path32 from "node:path";
|
|
34717
34794
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
34718
34795
|
const installed2 = [];
|
|
@@ -34728,11 +34805,11 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
34728
34805
|
for (const f of item.files) {
|
|
34729
34806
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
34730
34807
|
const dest = path32.join(skillDir, f.path);
|
|
34731
|
-
|
|
34808
|
+
fs31.mkdirSync(path32.dirname(dest), { recursive: true });
|
|
34732
34809
|
if (f.text !== void 0) {
|
|
34733
|
-
|
|
34810
|
+
fs31.writeFileSync(dest, f.text, "utf8");
|
|
34734
34811
|
} else if (f.base64) {
|
|
34735
|
-
|
|
34812
|
+
fs31.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
34736
34813
|
}
|
|
34737
34814
|
}
|
|
34738
34815
|
installed2.push({
|
|
@@ -34882,7 +34959,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
34882
34959
|
};
|
|
34883
34960
|
|
|
34884
34961
|
// src/bridge/routing/handlers/revert-turn-snapshot.ts
|
|
34885
|
-
import * as
|
|
34962
|
+
import * as fs32 from "node:fs";
|
|
34886
34963
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
34887
34964
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
34888
34965
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -34894,7 +34971,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
34894
34971
|
if (!s) return;
|
|
34895
34972
|
const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
|
|
34896
34973
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
34897
|
-
if (!
|
|
34974
|
+
if (!fs32.existsSync(file2)) {
|
|
34898
34975
|
sendWsMessage(s, {
|
|
34899
34976
|
type: "revert_turn_snapshot_result",
|
|
34900
34977
|
id,
|
|
@@ -34973,9 +35050,6 @@ function dispatchBridgeMessage(msg, deps) {
|
|
|
34973
35050
|
case "revert_turn_snapshot":
|
|
34974
35051
|
handleRevertTurnSnapshotMessage(msg, deps);
|
|
34975
35052
|
break;
|
|
34976
|
-
case "cancel_run":
|
|
34977
|
-
handleCancelRunMessage(msg, deps);
|
|
34978
|
-
break;
|
|
34979
35053
|
case "cursor_request_response":
|
|
34980
35054
|
handleCursorRequestResponseMessage(msg, deps);
|
|
34981
35055
|
break;
|