@autopilot-harness/port-factory-droid 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Autopilot Harness contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,199 @@
1
+ import { type PhaseActionConfig, type ReviewEngine, type StateStore } from "@autopilot-harness/core";
2
+ /** Factory Droid UserPromptSubmit stdin (camelCase + snake_case). */
3
+ export interface FactorySubmitPayload {
4
+ session_id?: string;
5
+ sessionId?: string;
6
+ prompt?: string;
7
+ has_images?: boolean;
8
+ hasImages?: boolean;
9
+ /** Informational — store uses install-root projectRoot. */
10
+ cwd?: string;
11
+ transcript_path?: string;
12
+ transcriptPath?: string;
13
+ conversation_id?: string;
14
+ conversationId?: string;
15
+ permission_mode?: string;
16
+ permissionMode?: string;
17
+ hook_event_name?: string;
18
+ hookEventName?: string;
19
+ message_id?: string;
20
+ messageId?: string;
21
+ }
22
+ /** Factory Droid PostToolUse stdin. */
23
+ export interface FactoryEditPayload {
24
+ session_id?: string;
25
+ sessionId?: string;
26
+ conversation_id?: string;
27
+ conversationId?: string;
28
+ cwd?: string;
29
+ tool_name?: string;
30
+ toolName?: string;
31
+ tool_input?: Record<string, unknown> | string;
32
+ toolInput?: Record<string, unknown> | string;
33
+ tool_response?: Record<string, unknown> | string;
34
+ toolResponse?: Record<string, unknown> | string;
35
+ hook_event_name?: string;
36
+ hookEventName?: string;
37
+ }
38
+ /** Factory Droid Stop stdin (no SubagentStop / Session* in this port). */
39
+ export interface FactoryStopPayload {
40
+ session_id?: string;
41
+ sessionId?: string;
42
+ conversation_id?: string;
43
+ conversationId?: string;
44
+ cwd?: string;
45
+ transcript_path?: string;
46
+ transcriptPath?: string;
47
+ status?: string;
48
+ stop_hook_active?: boolean;
49
+ stopHookActive?: boolean;
50
+ tool_execution_count?: number;
51
+ toolExecutionCount?: number;
52
+ elapsed_time?: number;
53
+ elapsedTime?: number;
54
+ hook_event_name?: string;
55
+ hookEventName?: string;
56
+ last_assistant_message?: string;
57
+ lastAssistantMessage?: string;
58
+ /** Gate only genuine completions (`end_turn`); session-end reasons must not continue. */
59
+ reason?: unknown;
60
+ error?: unknown;
61
+ message?: unknown;
62
+ }
63
+ export interface FactoryPortConfig {
64
+ phaseActions?: PhaseActionConfig;
65
+ }
66
+ export declare const FACTORY_PLATFORM = "factory-droid";
67
+ /** @deprecated Prefer FACTORY_PLATFORM — kept for doctor/docs naming clarity. */
68
+ export declare const FACTORY_DROID_PLATFORM = "factory-droid";
69
+ /**
70
+ * Public research (2026-09): no documented numeric Stop cap; no raise knob.
71
+ * Live smoke (2026-09-15) proved multi-block under stop_hook_active.
72
+ * See plans/v0.8-factory-droid/research-stop-cap.md + live-smoke-evidence.
73
+ */
74
+ export declare const FACTORY_DROID_STOP_CAP_RAISE_FOUND = false;
75
+ /** Live proved multi-block under stop_hook_active (live-factory-smoke). */
76
+ export declare const FACTORY_DROID_MULTI_BLOCK_ACROSS_ACTIVE_PROVEN = true;
77
+ /**
78
+ * Multi-block when true (live-proved default; keep true).
79
+ * Flip to false only for degraded ≤1 / natural Stop (policy or host regress).
80
+ */
81
+ export declare const FACTORY_DROID_ALLOW_MULTI_BLOCK_WHEN_ACTIVE = true;
82
+ /** Doctor / docs ceiling when ALLOW is false (degraded). */
83
+ export declare const FACTORY_DROID_DEGRADED_STOP_CONTINUE_CAP = 1;
84
+ /** Env keys for hook-runner root resolution (never trust process.cwd alone). */
85
+ export declare const FACTORY_DROID_ENV_PROJECT_DIR = "FACTORY_PROJECT_DIR";
86
+ export declare const FACTORY_DROID_ENV_CWD = "DROID_CWD";
87
+ /**
88
+ * PostToolUse matcher draft (Factory tools).
89
+ * Live smoke may widen; dirty-arm covers Execute/shell on Stop.
90
+ */
91
+ export declare const FACTORY_POST_TOOL_USE_MATCHER = "Create|Edit|ApplyPatch";
92
+ export declare const MAX_NEED_PICK_SLUGS = 40;
93
+ export declare const MAX_NEED_PICK_CONTEXT_CHARS = 2000;
94
+ export declare const MAX_HOOK_STDIO_CHARS = 8192;
95
+ export declare const MAX_TOOL_ARGS_JSON_CHARS = 1048576;
96
+ export declare const MAX_APPLY_PATCH_COMMAND_CHARS = 1048576;
97
+ export declare const MAX_APPLY_PATCH_PATHS = 256;
98
+ /**
99
+ * UPS stdout — inject or block.
100
+ * Allow (no fields on this object): runner MUST write **zero-byte** stdout
101
+ * (never `JSON.stringify({})` — Factory appends allow stdout to model context).
102
+ */
103
+ export interface FactorySubmitResult {
104
+ decision?: "block";
105
+ reason?: string;
106
+ hookSpecificOutput?: {
107
+ hookEventName?: string;
108
+ additionalContext?: string;
109
+ };
110
+ }
111
+ export interface FactoryStopResult {
112
+ decision?: "block";
113
+ reason?: string;
114
+ continue?: boolean;
115
+ stopReason?: string;
116
+ suppressOutput?: boolean;
117
+ }
118
+ /**
119
+ * True when Factory stdout must be **zero-byte** (UPS allow / Stop silence).
120
+ * Runner must not `JSON.stringify` these — Factory appends non-empty stdout to
121
+ * model context on allow-like paths.
122
+ */
123
+ export declare function isFactoryEmptyStdout(result: FactorySubmitResult | FactoryStopResult | null | undefined): boolean;
124
+ /** @deprecated Prefer {@link isFactoryEmptyStdout} — same predicate (UPS allow). */
125
+ export declare const isFactoryUpsAllow: typeof isFactoryEmptyStdout;
126
+ /** True if either camelCase or snake_case flag is strictly true. */
127
+ export declare function isFactoryStopHookActive(payload: FactoryStopPayload): boolean;
128
+ /**
129
+ * Degraded ≤1: yield (natural Stop) when already continuing from a prior block.
130
+ * Exported so tests can cover the branch without flipping the ship constant.
131
+ */
132
+ export declare function shouldYieldFactoryStopWhenActive(payload: FactoryStopPayload, allowMultiBlock?: boolean): boolean;
133
+ /**
134
+ * Prefer install-root, then FACTORY_PROJECT_DIR, DROID_CWD, stdin cwd.
135
+ * Never returns process.cwd().
136
+ */
137
+ export declare function resolveFactoryWorkspaceRoot(opts: {
138
+ installRoot?: string;
139
+ env?: NodeJS.ProcessEnv;
140
+ stdinCwd?: string;
141
+ }): string | null;
142
+ /**
143
+ * Map stop_hook_active → ReviewEngine loopCount.
144
+ * true ⇒ already in auto-continuation chain this turn.
145
+ */
146
+ export declare function loopCountFromStopHookActive(payload: FactoryStopPayload): number;
147
+ export declare function collectFactoryStopErrorText(payload: FactoryStopPayload): string;
148
+ export declare function normalizeFactoryStopStatus(payload: FactoryStopPayload, opts?: {
149
+ status?: "completed" | "error" | "aborted";
150
+ }): "completed" | "error" | "aborted";
151
+ /**
152
+ * Session-end / non-completion Stop fires must not Autopilot-continue.
153
+ * Gate only when reason is absent/empty or a known completion value (`end_turn`).
154
+ */
155
+ export declare function isFactoryStopCompletionReason(payload: FactoryStopPayload): boolean;
156
+ export declare function buildNeedPickContext(userMessage: unknown, candidates?: ReadonlyArray<{
157
+ slug?: string;
158
+ }>): string;
159
+ /** Prefer Channel A inject (Factory UPS hookSpecificOutput shape). */
160
+ export declare function injectNeedPickContext(userMessage: unknown, candidates?: ReadonlyArray<{
161
+ slug?: string;
162
+ }>): FactorySubmitResult;
163
+ /** Fallback: UPS block discards prompt (user re-submits with slug). */
164
+ export declare function blockSubmit(userMessage: unknown, fallback: string): FactorySubmitResult;
165
+ /**
166
+ * Parse paths from ApplyPatch command / patch body.
167
+ * Supports `*** Add|Update|Delete File:`, `*** Rename File: a -> b`, and `+++` lines.
168
+ */
169
+ export declare function pathsFromApplyPatchCommand(command: string): string[];
170
+ export declare function filePathsFromFactoryEdit(payload: FactoryEditPayload): string[];
171
+ /** File-mutating tools Autopilot arms (shell → dirty-arm on Stop). */
172
+ export declare function isFactoryEditTool(toolName: string): boolean;
173
+ /**
174
+ * UserPromptSubmit → core triggers / FSM.
175
+ * Allow → empty-field object; **runner must emit zero-byte stdout** (Factory
176
+ * adds plain/JSON allow stdout to model context — never stringify `{}`).
177
+ * Prefer inject for needPick; fallback decision:block.
178
+ * Stop-reason re-entry: harness followups do not clear pending/chain.
179
+ */
180
+ export declare function handleUserPromptSubmit(store: StateStore, payload: FactorySubmitPayload, projectRoot: string, portConfig?: FactoryPortConfig): FactorySubmitResult;
181
+ /** Aliased export for vendor (never collide with Claude bare names). */
182
+ export declare const handleFactoryUserPromptSubmit: typeof handleUserPromptSubmit;
183
+ /**
184
+ * PostToolUse → markCodeEdited for Create / Edit / ApplyPatch.
185
+ * Observe/arm only — never decision:block (would feed reason back to Droid).
186
+ */
187
+ export declare function handlePostToolUse(store: StateStore, payload: FactoryEditPayload, projectRoot: string): void;
188
+ export declare const handleFactoryPostToolUse: typeof handlePostToolUse;
189
+ /**
190
+ * Stop → ReviewEngine.
191
+ * Continue: decision:block + reason.
192
+ * When FACTORY_DROID_ALLOW_MULTI_BLOCK_WHEN_ACTIVE is false (degraded):
193
+ * allow stop if stop_hook_active (≤1 continue / natural Stop).
194
+ */
195
+ export declare function handleStop(engine: ReviewEngine, payload: FactoryStopPayload, opts?: {
196
+ status?: "completed" | "error" | "aborted";
197
+ }): FactoryStopResult;
198
+ export declare const handleFactoryStop: typeof handleStop;
199
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,624 @@
1
+ import { applyOff, applyOn, applyReplan, applyResume, applyResumeReview, applyRun, applyTrackPick, ensureAmbientReviewSession, effectiveReviewingItemId, firstUnchecked, isChannelANeedPick, isHarnessFollowupMessage, isProductCodeEdit, isRecoverOrStuckFollowupMessage, isSafeTrackSlug, isUserAbortText, loadProjectHookConfig, loadProjectReviewConfig, notePlansDirEdit, parseAdvanceNextItemId, parseChecklist, parseTrigger, } from "@autopilot-harness/core";
2
+ export const FACTORY_PLATFORM = "factory-droid";
3
+ /** @deprecated Prefer FACTORY_PLATFORM — kept for doctor/docs naming clarity. */
4
+ export const FACTORY_DROID_PLATFORM = FACTORY_PLATFORM;
5
+ /**
6
+ * Public research (2026-09): no documented numeric Stop cap; no raise knob.
7
+ * Live smoke (2026-09-15) proved multi-block under stop_hook_active.
8
+ * See plans/v0.8-factory-droid/research-stop-cap.md + live-smoke-evidence.
9
+ */
10
+ export const FACTORY_DROID_STOP_CAP_RAISE_FOUND = false;
11
+ /** Live proved multi-block under stop_hook_active (live-factory-smoke). */
12
+ export const FACTORY_DROID_MULTI_BLOCK_ACROSS_ACTIVE_PROVEN = true;
13
+ /**
14
+ * Multi-block when true (live-proved default; keep true).
15
+ * Flip to false only for degraded ≤1 / natural Stop (policy or host regress).
16
+ */
17
+ export const FACTORY_DROID_ALLOW_MULTI_BLOCK_WHEN_ACTIVE = true;
18
+ /** Doctor / docs ceiling when ALLOW is false (degraded). */
19
+ export const FACTORY_DROID_DEGRADED_STOP_CONTINUE_CAP = 1;
20
+ /** Env keys for hook-runner root resolution (never trust process.cwd alone). */
21
+ export const FACTORY_DROID_ENV_PROJECT_DIR = "FACTORY_PROJECT_DIR";
22
+ export const FACTORY_DROID_ENV_CWD = "DROID_CWD";
23
+ /**
24
+ * PostToolUse matcher draft (Factory tools).
25
+ * Live smoke may widen; dirty-arm covers Execute/shell on Stop.
26
+ */
27
+ export const FACTORY_POST_TOOL_USE_MATCHER = "Create|Edit|ApplyPatch";
28
+ export const MAX_NEED_PICK_SLUGS = 40;
29
+ export const MAX_NEED_PICK_CONTEXT_CHARS = 2_000;
30
+ export const MAX_HOOK_STDIO_CHARS = 8_192;
31
+ export const MAX_TOOL_ARGS_JSON_CHARS = 1_048_576;
32
+ export const MAX_APPLY_PATCH_COMMAND_CHARS = 1_048_576;
33
+ export const MAX_APPLY_PATCH_PATHS = 256;
34
+ /**
35
+ * True when Factory stdout must be **zero-byte** (UPS allow / Stop silence).
36
+ * Runner must not `JSON.stringify` these — Factory appends non-empty stdout to
37
+ * model context on allow-like paths.
38
+ */
39
+ export function isFactoryEmptyStdout(result) {
40
+ if (result == null || typeof result !== "object" || Array.isArray(result)) {
41
+ return false;
42
+ }
43
+ // Allow only a true no-op object. Any defined field (including continue:false,
44
+ // stopReason, whitespace reason, empty hookSpecificOutput) must keep JSON
45
+ // stdout — never treat hard-stop / block / inject as empty-body allow.
46
+ for (const value of Object.values(result)) {
47
+ if (value !== undefined && value !== null)
48
+ return false;
49
+ }
50
+ return true;
51
+ }
52
+ /** @deprecated Prefer {@link isFactoryEmptyStdout} — same predicate (UPS allow). */
53
+ export const isFactoryUpsAllow = isFactoryEmptyStdout;
54
+ /** True if either camelCase or snake_case flag is strictly true. */
55
+ export function isFactoryStopHookActive(payload) {
56
+ return (payload.stop_hook_active === true || payload.stopHookActive === true);
57
+ }
58
+ /**
59
+ * Degraded ≤1: yield (natural Stop) when already continuing from a prior block.
60
+ * Exported so tests can cover the branch without flipping the ship constant.
61
+ */
62
+ export function shouldYieldFactoryStopWhenActive(payload, allowMultiBlock = FACTORY_DROID_ALLOW_MULTI_BLOCK_WHEN_ACTIVE) {
63
+ if (allowMultiBlock)
64
+ return false;
65
+ return isFactoryStopHookActive(payload);
66
+ }
67
+ function sid(p) {
68
+ for (const v of [
69
+ p.session_id,
70
+ p.sessionId,
71
+ p.conversation_id,
72
+ p.conversationId,
73
+ ]) {
74
+ if (typeof v === "string") {
75
+ const t = v.trim();
76
+ if (t)
77
+ return t;
78
+ }
79
+ }
80
+ return "";
81
+ }
82
+ function clipText(text, max = MAX_HOOK_STDIO_CHARS) {
83
+ if (text.length <= max)
84
+ return text;
85
+ return `${text.slice(0, max - 1)}…`;
86
+ }
87
+ function blockReason(message, fallback) {
88
+ const m = typeof message === "string" ? message.trim() : "";
89
+ return m || fallback;
90
+ }
91
+ /**
92
+ * Prefer install-root, then FACTORY_PROJECT_DIR, DROID_CWD, stdin cwd.
93
+ * Never returns process.cwd().
94
+ */
95
+ export function resolveFactoryWorkspaceRoot(opts) {
96
+ const env = opts.env ?? process.env;
97
+ const candidates = [
98
+ opts.installRoot,
99
+ env[FACTORY_DROID_ENV_PROJECT_DIR],
100
+ env[FACTORY_DROID_ENV_CWD],
101
+ opts.stdinCwd,
102
+ ];
103
+ for (const c of candidates) {
104
+ if (typeof c === "string") {
105
+ const t = c.trim();
106
+ // Reject NULs / newlines smuggled into a workspace root.
107
+ if (t && !/[\0\r\n]/.test(t))
108
+ return t;
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ /**
114
+ * Map stop_hook_active → ReviewEngine loopCount.
115
+ * true ⇒ already in auto-continuation chain this turn.
116
+ */
117
+ export function loopCountFromStopHookActive(payload) {
118
+ return isFactoryStopHookActive(payload) ? 1 : 0;
119
+ }
120
+ export function collectFactoryStopErrorText(payload) {
121
+ if (!payload || typeof payload !== "object")
122
+ return "";
123
+ const parts = [];
124
+ try {
125
+ const push = (value) => {
126
+ if (typeof value === "string" && value.trim()) {
127
+ parts.push(value);
128
+ return;
129
+ }
130
+ if (value && typeof value === "object" && !Array.isArray(value)) {
131
+ const o = value;
132
+ for (const key of ["message", "error", "name", "stack", "detail"]) {
133
+ const nested = o[key];
134
+ if (typeof nested === "string" && nested.trim())
135
+ parts.push(nested);
136
+ }
137
+ }
138
+ };
139
+ push(payload.error);
140
+ push(payload.message);
141
+ push(payload.reason);
142
+ }
143
+ catch {
144
+ return "";
145
+ }
146
+ return clipText(parts.join("\n"));
147
+ }
148
+ export function normalizeFactoryStopStatus(payload, opts) {
149
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
150
+ return opts?.status ?? "completed";
151
+ }
152
+ const statusRaw = String(payload.status ?? "")
153
+ .toLowerCase()
154
+ .trim();
155
+ const errText = collectFactoryStopErrorText(payload);
156
+ if (statusRaw === "aborted" ||
157
+ statusRaw === "cancelled" ||
158
+ statusRaw === "canceled") {
159
+ return "aborted";
160
+ }
161
+ if (opts?.status === "aborted")
162
+ return "aborted";
163
+ if (statusRaw === "error" || statusRaw === "failed") {
164
+ if (isUserAbortText(errText))
165
+ return "aborted";
166
+ return "error";
167
+ }
168
+ if (opts?.status === "error") {
169
+ if (isUserAbortText(errText))
170
+ return "aborted";
171
+ return "error";
172
+ }
173
+ if (opts?.status === "completed")
174
+ return "completed";
175
+ if (!statusRaw && isUserAbortText(errText))
176
+ return "aborted";
177
+ return "completed";
178
+ }
179
+ /**
180
+ * Session-end / non-completion Stop fires must not Autopilot-continue.
181
+ * Gate only when reason is absent/empty or a known completion value (`end_turn`).
182
+ */
183
+ export function isFactoryStopCompletionReason(payload) {
184
+ const raw = payload?.reason;
185
+ if (raw == null)
186
+ return true;
187
+ if (typeof raw !== "string")
188
+ return false;
189
+ const r = raw.trim().toLowerCase();
190
+ if (!r)
191
+ return true;
192
+ if (r === "end_turn" || r === "endturn" || r === "completed")
193
+ return true;
194
+ return false;
195
+ }
196
+ export function buildNeedPickContext(userMessage, candidates) {
197
+ const fromMessage = typeof userMessage === "string" && userMessage.trim().length > 0
198
+ ? userMessage.trim()
199
+ : "";
200
+ const slugs = [
201
+ ...new Set((candidates ?? [])
202
+ .map((c) => (c && typeof c.slug === "string" ? c.slug.trim() : ""))
203
+ .filter((s) => s.length > 0 && isSafeTrackSlug(s))),
204
+ ].slice(0, MAX_NEED_PICK_SLUGS);
205
+ let ctx = fromMessage ||
206
+ (slugs.length > 0
207
+ ? `Select a plan to execute:\n\n${slugs
208
+ .map((s, i) => ` ${i + 1}. ${s}`)
209
+ .join("\n")}\n\nReply with a number or /autopilot-run <slug>.`
210
+ : "Select a plan to execute. Reply with a number or /autopilot-run <slug>.");
211
+ if (ctx.length > MAX_NEED_PICK_CONTEXT_CHARS) {
212
+ ctx = `${ctx.slice(0, MAX_NEED_PICK_CONTEXT_CHARS - 1)}…`;
213
+ }
214
+ return ctx;
215
+ }
216
+ /** Prefer Channel A inject (Factory UPS hookSpecificOutput shape). */
217
+ export function injectNeedPickContext(userMessage, candidates) {
218
+ const ctx = buildNeedPickContext(userMessage, candidates);
219
+ return {
220
+ hookSpecificOutput: {
221
+ hookEventName: "UserPromptSubmit",
222
+ additionalContext: ctx,
223
+ },
224
+ };
225
+ }
226
+ /** Fallback: UPS block discards prompt (user re-submits with slug). */
227
+ export function blockSubmit(userMessage, fallback) {
228
+ return {
229
+ decision: "block",
230
+ reason: clipText(blockReason(typeof userMessage === "string" ? userMessage : undefined, fallback), MAX_NEED_PICK_CONTEXT_CHARS + 256),
231
+ };
232
+ }
233
+ /**
234
+ * Parse paths from ApplyPatch command / patch body.
235
+ * Supports `*** Add|Update|Delete File:`, `*** Rename File: a -> b`, and `+++` lines.
236
+ */
237
+ export function pathsFromApplyPatchCommand(command) {
238
+ if (typeof command !== "string" || !command.trim())
239
+ return [];
240
+ const text = command.length > MAX_APPLY_PATCH_COMMAND_CHARS
241
+ ? command.slice(0, MAX_APPLY_PATCH_COMMAND_CHARS)
242
+ : command;
243
+ const found = [];
244
+ const seen = new Set();
245
+ const push = (raw) => {
246
+ if (found.length >= MAX_APPLY_PATCH_PATHS)
247
+ return;
248
+ let p = raw.trim();
249
+ if (!p || p === "/dev/null")
250
+ return;
251
+ if (/[\0\r\n]/.test(p))
252
+ return;
253
+ p = p.replace(/^[ab]\//, "");
254
+ if (!p || seen.has(p))
255
+ return;
256
+ seen.add(p);
257
+ found.push(p);
258
+ };
259
+ for (const line of text.split(/\r?\n/)) {
260
+ if (found.length >= MAX_APPLY_PATCH_PATHS)
261
+ break;
262
+ const rename = line.match(/^\*\*\*\s+Rename\s+File:\s*(.+?)\s*->\s*(.+?)\s*$/i);
263
+ if (rename?.[1] && rename[2]) {
264
+ push(rename[1]);
265
+ push(rename[2]);
266
+ continue;
267
+ }
268
+ const header = line.match(/^\*\*\*\s+(?:Add|Update|Delete)\s+File:\s*(.+?)\s*$/i);
269
+ if (header?.[1]) {
270
+ push(header[1]);
271
+ continue;
272
+ }
273
+ const plus = line.match(/^\+\+\+\s+(?:[ab]\/)?(.+?)\s*$/);
274
+ if (plus?.[1] && plus[1] !== "/dev/null") {
275
+ push(plus[1]);
276
+ }
277
+ }
278
+ return found;
279
+ }
280
+ function toolInputObject(payload) {
281
+ const input = payload.tool_input ?? payload.toolInput;
282
+ if (!input)
283
+ return null;
284
+ if (typeof input === "object" && !Array.isArray(input)) {
285
+ return input;
286
+ }
287
+ if (typeof input === "string") {
288
+ if (input.length > MAX_TOOL_ARGS_JSON_CHARS)
289
+ return null;
290
+ try {
291
+ const parsed = JSON.parse(input);
292
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
293
+ return parsed;
294
+ }
295
+ }
296
+ catch {
297
+ return null;
298
+ }
299
+ }
300
+ return null;
301
+ }
302
+ export function filePathsFromFactoryEdit(payload) {
303
+ const toolName = String(payload.tool_name ?? payload.toolName ?? "").trim();
304
+ const rawInput = payload.tool_input ?? payload.toolInput;
305
+ if (toolName === "ApplyPatch" || toolName === "apply_patch") {
306
+ if (typeof rawInput === "string") {
307
+ // Prefer patch-body parse; JSON object string falls through below.
308
+ const fromBody = pathsFromApplyPatchCommand(rawInput);
309
+ if (fromBody.length > 0)
310
+ return fromBody;
311
+ }
312
+ const input = toolInputObject(payload);
313
+ if (input) {
314
+ for (const key of ["command", "patch", "input"]) {
315
+ const v = input[key];
316
+ if (typeof v === "string") {
317
+ const fromCmd = pathsFromApplyPatchCommand(v);
318
+ if (fromCmd.length > 0)
319
+ return fromCmd;
320
+ }
321
+ }
322
+ }
323
+ // Fall through: some hosts put a plain path on ApplyPatch.
324
+ }
325
+ const input = toolInputObject(payload);
326
+ if (!input)
327
+ return [];
328
+ const candidates = [
329
+ input.file_path,
330
+ input.filePath,
331
+ input.path,
332
+ input.target_file,
333
+ input.targetFile,
334
+ ];
335
+ for (const c of candidates) {
336
+ if (typeof c === "string" && c.trim() && !/[\0\r\n]/.test(c)) {
337
+ return [c.trim()];
338
+ }
339
+ }
340
+ return [];
341
+ }
342
+ /** File-mutating tools Autopilot arms (shell → dirty-arm on Stop). */
343
+ export function isFactoryEditTool(toolName) {
344
+ const n = toolName.trim();
345
+ return (n === "Create" ||
346
+ n === "Edit" ||
347
+ n === "ApplyPatch" ||
348
+ n === "apply_patch");
349
+ }
350
+ function stampFactoryPlatform(store, conversationId, projectRoot) {
351
+ const session = store.getSession(conversationId);
352
+ if (!session || session.platform === FACTORY_PLATFORM)
353
+ return;
354
+ store.upsertSession({
355
+ conversation_id: conversationId,
356
+ project_root: session.project_root || projectRoot,
357
+ code_root: session.code_root || projectRoot,
358
+ platform: FACTORY_PLATFORM,
359
+ });
360
+ }
361
+ /**
362
+ * UserPromptSubmit → core triggers / FSM.
363
+ * Allow → empty-field object; **runner must emit zero-byte stdout** (Factory
364
+ * adds plain/JSON allow stdout to model context — never stringify `{}`).
365
+ * Prefer inject for needPick; fallback decision:block.
366
+ * Stop-reason re-entry: harness followups do not clear pending/chain.
367
+ */
368
+ export function handleUserPromptSubmit(store, payload, projectRoot, portConfig) {
369
+ try {
370
+ return handleUserPromptSubmitInner(store, payload, projectRoot, portConfig);
371
+ }
372
+ catch {
373
+ return {};
374
+ }
375
+ }
376
+ /** Aliased export for vendor (never collide with Claude bare names). */
377
+ export const handleFactoryUserPromptSubmit = handleUserPromptSubmit;
378
+ function handleUserPromptSubmitInner(store, payload, projectRoot, portConfig) {
379
+ const conversationId = sid(payload);
380
+ if (!conversationId)
381
+ return {};
382
+ const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
383
+ try {
384
+ store.clearPendingFollowupIf(conversationId, isRecoverOrStuckFollowupMessage);
385
+ }
386
+ catch {
387
+ /* best-effort */
388
+ }
389
+ const session = store.getSession(conversationId);
390
+ const hookCfg = loadProjectHookConfig(projectRoot);
391
+ const trigger = parseTrigger({
392
+ prompt,
393
+ conversationId,
394
+ projectRoot,
395
+ pendingAction: session?.pending_action,
396
+ triggers: hookCfg.triggers,
397
+ });
398
+ const actionConfig = {
399
+ ...portConfig?.phaseActions,
400
+ plansDir: portConfig?.phaseActions?.plansDir ?? hookCfg.plansDir,
401
+ };
402
+ const gateFallback = "Autopilot rejected this prompt. Check `npx autopilot-harness status`.";
403
+ if (trigger) {
404
+ if (trigger.kind === "off") {
405
+ applyOff(store, conversationId);
406
+ stampFactoryPlatform(store, conversationId, projectRoot);
407
+ return {};
408
+ }
409
+ if (trigger.kind === "on") {
410
+ const result = applyOn(store, conversationId, projectRoot, {
411
+ initialBrief: trigger.initialBrief,
412
+ slug: trigger.slug,
413
+ platform: FACTORY_PLATFORM,
414
+ });
415
+ if (!result.ok) {
416
+ stampFactoryPlatform(store, conversationId, projectRoot);
417
+ return blockSubmit(result.userMessage, gateFallback);
418
+ }
419
+ stampFactoryPlatform(store, conversationId, projectRoot);
420
+ return {};
421
+ }
422
+ if (trigger.kind === "resume") {
423
+ const result = applyResume(store, conversationId, {
424
+ slug: trigger.slug,
425
+ });
426
+ if (!result.ok) {
427
+ stampFactoryPlatform(store, conversationId, projectRoot);
428
+ return blockSubmit(result.userMessage, gateFallback);
429
+ }
430
+ stampFactoryPlatform(store, conversationId, projectRoot);
431
+ return {};
432
+ }
433
+ if (trigger.kind === "resume_review") {
434
+ applyResumeReview(store, conversationId);
435
+ stampFactoryPlatform(store, conversationId, projectRoot);
436
+ return {};
437
+ }
438
+ if (trigger.kind === "run") {
439
+ const result = applyRun(store, conversationId, projectRoot, {
440
+ slug: trigger.slug,
441
+ config: actionConfig,
442
+ platform: FACTORY_PLATFORM,
443
+ });
444
+ if (!result.ok) {
445
+ stampFactoryPlatform(store, conversationId, projectRoot);
446
+ if (isChannelANeedPick(result)) {
447
+ return injectNeedPickContext(result.userMessage, result.candidates);
448
+ }
449
+ return blockSubmit(result.userMessage, gateFallback);
450
+ }
451
+ stampFactoryPlatform(store, conversationId, projectRoot);
452
+ return {};
453
+ }
454
+ if (trigger.kind === "replan") {
455
+ const result = applyReplan(store, conversationId, projectRoot, {
456
+ slug: trigger.slug,
457
+ config: actionConfig,
458
+ platform: FACTORY_PLATFORM,
459
+ });
460
+ if (!result.ok) {
461
+ stampFactoryPlatform(store, conversationId, projectRoot);
462
+ if (isChannelANeedPick(result)) {
463
+ return injectNeedPickContext(result.userMessage, result.candidates);
464
+ }
465
+ return blockSubmit(result.userMessage, gateFallback);
466
+ }
467
+ stampFactoryPlatform(store, conversationId, projectRoot);
468
+ return {};
469
+ }
470
+ if (trigger.kind === "track_pick" && trigger.trackPick) {
471
+ const result = applyTrackPick(store, conversationId, projectRoot, trigger.trackPick, { config: actionConfig, platform: FACTORY_PLATFORM });
472
+ if (!result.ok) {
473
+ stampFactoryPlatform(store, conversationId, projectRoot);
474
+ if (isChannelANeedPick(result)) {
475
+ return injectNeedPickContext(result.userMessage, result.candidates);
476
+ }
477
+ return blockSubmit(result.userMessage, gateFallback);
478
+ }
479
+ stampFactoryPlatform(store, conversationId, projectRoot);
480
+ return {};
481
+ }
482
+ return {};
483
+ }
484
+ // Stop reason may re-enter UPS as prompt — harness-owned: do not clear pending.
485
+ if (!isHarnessFollowupMessage(prompt)) {
486
+ store.clearChainPending(conversationId);
487
+ }
488
+ stampFactoryPlatform(store, conversationId, projectRoot);
489
+ return {};
490
+ }
491
+ function armCodeEdited(store, conversationId, projectRoot) {
492
+ const cfg = loadProjectReviewConfig(projectRoot);
493
+ if (cfg.reviewScope === "project") {
494
+ ensureAmbientReviewSession(store, conversationId, projectRoot, cfg.reviewScope, FACTORY_PLATFORM);
495
+ }
496
+ stampFactoryPlatform(store, conversationId, projectRoot);
497
+ const session = store.getSession(conversationId);
498
+ const checklistPath = session?.checklist_path?.trim() ?? "";
499
+ let checklistSnap = null;
500
+ if (checklistPath) {
501
+ try {
502
+ checklistSnap = parseChecklist(checklistPath, { projectRoot });
503
+ }
504
+ catch {
505
+ /* still arm */
506
+ }
507
+ }
508
+ store.markCodeEdited(conversationId, (chain) => {
509
+ const fromPending = parseAdvanceNextItemId(chain.pending_followup);
510
+ if (checklistSnap) {
511
+ if (fromPending && effectiveReviewingItemId(checklistSnap, fromPending)) {
512
+ return fromPending;
513
+ }
514
+ return firstUnchecked(checklistSnap)?.id ?? null;
515
+ }
516
+ return fromPending;
517
+ });
518
+ }
519
+ /**
520
+ * PostToolUse → markCodeEdited for Create / Edit / ApplyPatch.
521
+ * Observe/arm only — never decision:block (would feed reason back to Droid).
522
+ */
523
+ export function handlePostToolUse(store, payload, projectRoot) {
524
+ try {
525
+ handlePostToolUseInner(store, payload, projectRoot);
526
+ }
527
+ catch {
528
+ /* fail-open */
529
+ }
530
+ }
531
+ export const handleFactoryPostToolUse = handlePostToolUse;
532
+ function handlePostToolUseInner(store, payload, projectRoot) {
533
+ const conversationId = sid(payload);
534
+ const toolName = String(payload.tool_name ?? payload.toolName ?? "").trim();
535
+ if (!conversationId || !isFactoryEditTool(toolName))
536
+ return;
537
+ const filePaths = filePathsFromFactoryEdit(payload);
538
+ if (filePaths.length === 0) {
539
+ stampFactoryPlatform(store, conversationId, projectRoot);
540
+ return;
541
+ }
542
+ let plansDir;
543
+ try {
544
+ plansDir = loadProjectHookConfig(projectRoot).plansDir;
545
+ }
546
+ catch {
547
+ plansDir = undefined;
548
+ }
549
+ let armed = false;
550
+ for (const filePath of filePaths) {
551
+ try {
552
+ notePlansDirEdit(store, conversationId, projectRoot, filePath, plansDir);
553
+ }
554
+ catch {
555
+ /* best-effort */
556
+ }
557
+ if (!isProductCodeEdit(filePath, { projectRoot }))
558
+ continue;
559
+ if (!armed) {
560
+ armCodeEdited(store, conversationId, projectRoot);
561
+ armed = true;
562
+ }
563
+ }
564
+ if (!armed) {
565
+ stampFactoryPlatform(store, conversationId, projectRoot);
566
+ }
567
+ }
568
+ /**
569
+ * Stop → ReviewEngine.
570
+ * Continue: decision:block + reason.
571
+ * When FACTORY_DROID_ALLOW_MULTI_BLOCK_WHEN_ACTIVE is false (degraded):
572
+ * allow stop if stop_hook_active (≤1 continue / natural Stop).
573
+ */
574
+ export function handleStop(engine, payload, opts) {
575
+ try {
576
+ return handleStopInner(engine, payload, opts);
577
+ }
578
+ catch {
579
+ return {};
580
+ }
581
+ }
582
+ export const handleFactoryStop = handleStop;
583
+ function handleStopInner(engine, payload, opts) {
584
+ const conversationId = sid(payload);
585
+ if (!conversationId)
586
+ return {};
587
+ if (!isFactoryStopCompletionReason(payload)) {
588
+ return {};
589
+ }
590
+ // Degraded ≤1: yield when already continuing from a prior Stop block.
591
+ if (shouldYieldFactoryStopWhenActive(payload)) {
592
+ return {};
593
+ }
594
+ const status = normalizeFactoryStopStatus(payload, opts);
595
+ const transcriptRaw = payload.transcript_path ?? payload.transcriptPath;
596
+ const transcriptTrimmed = typeof transcriptRaw === "string" ? transcriptRaw.trim() : "";
597
+ const transcriptPath = transcriptTrimmed && !/[\0\r\n]/.test(transcriptTrimmed)
598
+ ? transcriptTrimmed
599
+ : undefined;
600
+ const action = engine.handleStop({
601
+ conversationId,
602
+ status,
603
+ loopCount: loopCountFromStopHookActive(payload),
604
+ transcriptPath,
605
+ platform: FACTORY_PLATFORM,
606
+ });
607
+ if (!action?.message)
608
+ return {};
609
+ const reason = clipText(blockReason(action.message, "Autopilot followup"), MAX_HOOK_STDIO_CHARS);
610
+ if (!action.loop) {
611
+ // Hard-stop (stuck / deliver-once): continue:false + stopReason so the tip
612
+ // still reaches Droid. Do not use decision:block (would request another turn).
613
+ // True allow / no-followup stays {} → runner empty-body (Silence).
614
+ return {
615
+ continue: false,
616
+ stopReason: reason,
617
+ };
618
+ }
619
+ return {
620
+ decision: "block",
621
+ reason,
622
+ };
623
+ }
624
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@autopilot-harness/port-factory-droid",
3
+ "version": "0.8.0",
4
+ "description": "Autopilot harness host port for Factory Droid hooks (Stop block+reason; multi-block under stop_hook_active live-proved; degraded ≤1 if multi-block disabled)",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/mt2007/autopilot-harness.git",
9
+ "directory": "packages/ports/factory-droid"
10
+ },
11
+ "homepage": "https://github.com/mt2007/autopilot-harness#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/mt2007/autopilot-harness/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "dependencies": {
28
+ "@autopilot-harness/core": "0.8.0"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.8.2"
32
+ },
33
+ "engines": {
34
+ "node": ">=22"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "author": "mt2007 (https://github.com/mt2007)",
40
+ "keywords": [
41
+ "autopilot",
42
+ "harness",
43
+ "agent",
44
+ "ai",
45
+ "vibecoding",
46
+ "factory",
47
+ "factory-droid",
48
+ "droid",
49
+ "checklist",
50
+ "code-review"
51
+ ],
52
+ "scripts": {
53
+ "build": "tsc -p tsconfig.json",
54
+ "typecheck": "tsc -p tsconfig.json --noEmit"
55
+ }
56
+ }