@opentag/runner 0.1.0 → 0.2.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 +21 -0
- package/dist/claude-code.d.ts +11 -0
- package/dist/claude-code.d.ts.map +1 -0
- package/dist/codex.d.ts +3 -1
- package/dist/codex.d.ts.map +1 -1
- package/dist/command.d.ts +2 -0
- package/dist/command.d.ts.map +1 -1
- package/dist/echo.d.ts.map +1 -1
- package/dist/executor.d.ts +7 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/git.d.ts +34 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +597 -42
- package/dist/index.js.map +1 -1
- package/dist/result.d.ts +11 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/security.d.ts +32 -0
- package/dist/security.d.ts.map +1 -0
- package/package.json +6 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Amplift
|
|
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,11 @@
|
|
|
1
|
+
import { type CommandRunner } from "./command.js";
|
|
2
|
+
import { type ExecutorAdapter } from "./executor.js";
|
|
3
|
+
export type ClaudeCodeExecutorOptions = {
|
|
4
|
+
runner?: CommandRunner;
|
|
5
|
+
claudeCommand?: string;
|
|
6
|
+
model?: string;
|
|
7
|
+
permissionMode?: "acceptEdits" | "auto" | "bypassPermissions" | "default" | "plan";
|
|
8
|
+
dangerouslySkipPermissions?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function createClaudeCodeExecutor(options?: ClaudeCodeExecutorOptions): ExecutorAdapter;
|
|
11
|
+
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../src/claude-code.ts"],"names":[],"mappings":"AACA,OAAO,EAA6C,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAgC,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAInF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,mBAAmB,GAAG,SAAS,GAAG,MAAM,CAAC;IACnF,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC,CAAC;AA8BF,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,yBAA8B,GAAG,eAAe,CAiGjG"}
|
package/dist/codex.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type CommandRunner } from "./command.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type ExecutorAdapter } from "./executor.js";
|
|
3
|
+
import { type RunnerSecurityPolicy } from "./security.js";
|
|
3
4
|
export type CodexExecutorOptions = {
|
|
4
5
|
runner?: CommandRunner;
|
|
5
6
|
codexCommand?: string;
|
|
6
7
|
model?: string;
|
|
8
|
+
security?: RunnerSecurityPolicy;
|
|
7
9
|
};
|
|
8
10
|
export declare function createCodexExecutor(options?: CodexExecutorOptions): ExecutorAdapter;
|
|
9
11
|
//# sourceMappingURL=codex.d.ts.map
|
package/dist/codex.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../src/codex.ts"],"names":[],"mappings":"AACA,OAAO,EAA6C,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../src/codex.ts"],"names":[],"mappings":"AACA,OAAO,EAA6C,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAgC,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAYnF,OAAO,EAAoE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE5H,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC,CAAC;AA6BF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,eAAe,CAsKvF"}
|
package/dist/command.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ export type CommandResult = {
|
|
|
3
3
|
stdout: string;
|
|
4
4
|
stderr: string;
|
|
5
5
|
};
|
|
6
|
+
export type CommandEnvironment = Record<string, string | undefined>;
|
|
6
7
|
export type CommandRunner = {
|
|
7
8
|
run(command: string, args: string[], options?: {
|
|
8
9
|
cwd?: string;
|
|
9
10
|
input?: string;
|
|
11
|
+
env?: CommandEnvironment;
|
|
10
12
|
}): Promise<CommandResult>;
|
|
11
13
|
};
|
|
12
14
|
export declare const nodeCommandRunner: CommandRunner;
|
package/dist/command.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEpE,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,kBAAkB,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACpI,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,aA4B/B,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhG"}
|
package/dist/echo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../src/echo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAMrD,wBAAgB,kBAAkB,IAAI,eAAe,
|
|
1
|
+
{"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../src/echo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAMrD,wBAAgB,kBAAkB,IAAI,eAAe,CAsCpD"}
|
package/dist/executor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ContextPacket, type ContextPointer, type OpenTagCommand, type OpenTagRunResult, type PermissionGrant } from "@opentag/core";
|
|
2
2
|
export type ExecutorEvent = {
|
|
3
3
|
type: "executor.started" | "executor.progress" | "executor.completed" | "executor.failed";
|
|
4
4
|
message: string;
|
|
@@ -12,7 +12,13 @@ export type ExecutorRunInput = {
|
|
|
12
12
|
workspacePath: string;
|
|
13
13
|
command: OpenTagCommand;
|
|
14
14
|
context: ContextPointer[];
|
|
15
|
+
contextPacket?: ContextPacket;
|
|
16
|
+
permissions?: PermissionGrant[];
|
|
17
|
+
baseBranch?: string;
|
|
18
|
+
worktreeRoot?: string;
|
|
19
|
+
keepWorktree?: "always" | "on_failure" | "never";
|
|
15
20
|
};
|
|
21
|
+
export declare function renderContextPacketForPrompt(packet?: ContextPacket): string[];
|
|
16
22
|
export type ExecutorReadiness = {
|
|
17
23
|
ready: boolean;
|
|
18
24
|
reason?: string;
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAE/J,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,kBAAkB,GAAG,mBAAmB,GAAG,oBAAoB,GAAG,iBAAiB,CAAC;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;CAClD,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,EAAE,CAiC7E;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5D,GAAG,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjF,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC"}
|
package/dist/git.d.ts
CHANGED
|
@@ -11,6 +11,29 @@ export declare function createRunBranch(input: {
|
|
|
11
11
|
runner: CommandRunner;
|
|
12
12
|
workspacePath: string;
|
|
13
13
|
branchName: string;
|
|
14
|
+
startPoint?: string;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
export declare function worktreePathForRun(input: {
|
|
17
|
+
workspacePath: string;
|
|
18
|
+
runId: string;
|
|
19
|
+
worktreeRoot?: string;
|
|
20
|
+
}): string;
|
|
21
|
+
export declare function createRunWorktree(input: {
|
|
22
|
+
runner: CommandRunner;
|
|
23
|
+
workspacePath: string;
|
|
24
|
+
worktreePath: string;
|
|
25
|
+
branchName: string;
|
|
26
|
+
baseBranch: string;
|
|
27
|
+
}): Promise<void>;
|
|
28
|
+
export declare function removeRunWorktree(input: {
|
|
29
|
+
runner: CommandRunner;
|
|
30
|
+
workspacePath: string;
|
|
31
|
+
worktreePath: string;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
export declare function deleteRunBranch(input: {
|
|
34
|
+
runner: CommandRunner;
|
|
35
|
+
workspacePath: string;
|
|
36
|
+
branchName: string;
|
|
14
37
|
}): Promise<void>;
|
|
15
38
|
export declare function changedFiles(input: {
|
|
16
39
|
runner: CommandRunner;
|
|
@@ -20,6 +43,17 @@ export declare function cleanupInternalArtifacts(input: {
|
|
|
20
43
|
runner: CommandRunner;
|
|
21
44
|
workspacePath: string;
|
|
22
45
|
}): Promise<string[]>;
|
|
46
|
+
export declare function commitRunChanges(input: {
|
|
47
|
+
runner: CommandRunner;
|
|
48
|
+
workspacePath: string;
|
|
49
|
+
message: string;
|
|
50
|
+
}): Promise<boolean>;
|
|
51
|
+
export declare function commitChangedFiles(input: {
|
|
52
|
+
runner: CommandRunner;
|
|
53
|
+
workspacePath: string;
|
|
54
|
+
files: string[];
|
|
55
|
+
message: string;
|
|
56
|
+
}): Promise<void>;
|
|
23
57
|
export declare function pushBranch(input: {
|
|
24
58
|
runner: CommandRunner;
|
|
25
59
|
workspacePath: string;
|
package/dist/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAIF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,EAAE,CAUzE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAIhE;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAIT;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhB;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhI;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAI7G;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBzH;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC5C,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,OAAO,CAAC,CAcnB;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhB;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE;IACtC,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
export * from "./claude-code.js";
|
|
1
2
|
export * from "./codex.js";
|
|
2
3
|
export * from "./command.js";
|
|
3
4
|
export * from "./echo.js";
|
|
4
5
|
export * from "./executor.js";
|
|
5
6
|
export * from "./git.js";
|
|
7
|
+
export * from "./result.js";
|
|
8
|
+
export * from "./security.js";
|
|
6
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
// src/claude-code.ts
|
|
2
|
+
import { contextPointerLabel as contextPointerLabel2 } from "@opentag/core";
|
|
3
|
+
|
|
1
4
|
// src/command.ts
|
|
2
5
|
import { spawn } from "child_process";
|
|
3
6
|
var nodeCommandRunner = {
|
|
4
7
|
run(command, args, options = {}) {
|
|
5
|
-
return new Promise((
|
|
8
|
+
return new Promise((resolve2, reject) => {
|
|
6
9
|
const child = spawn(command, args, {
|
|
7
10
|
cwd: options.cwd,
|
|
11
|
+
env: options.env,
|
|
8
12
|
stdio: ["pipe", "pipe", "pipe"]
|
|
9
13
|
});
|
|
10
14
|
const stdout = [];
|
|
@@ -13,7 +17,7 @@ var nodeCommandRunner = {
|
|
|
13
17
|
child.stderr.on("data", (chunk) => stderr.push(chunk));
|
|
14
18
|
child.on("error", reject);
|
|
15
19
|
child.on("close", (exitCode) => {
|
|
16
|
-
|
|
20
|
+
resolve2({
|
|
17
21
|
exitCode: exitCode ?? 1,
|
|
18
22
|
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
19
23
|
stderr: Buffer.concat(stderr).toString("utf8")
|
|
@@ -32,7 +36,40 @@ async function assertCommandSucceeded(result, label) {
|
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
// src/executor.ts
|
|
40
|
+
import { contextPointerLabel } from "@opentag/core";
|
|
41
|
+
function renderContextPacketForPrompt(packet) {
|
|
42
|
+
if (!packet) return [];
|
|
43
|
+
const lines = ["OpenTag context packet:", `- summary: ${packet.summary}`];
|
|
44
|
+
if (packet.intent) {
|
|
45
|
+
lines.push(`- intent: ${packet.intent.normalizedIntent}`);
|
|
46
|
+
lines.push(`- requested by: ${packet.intent.requestedBy.provider}:${packet.intent.requestedBy.providerUserId}`);
|
|
47
|
+
}
|
|
48
|
+
if (packet.sources?.length) {
|
|
49
|
+
lines.push("- selected sources:");
|
|
50
|
+
for (const source of packet.sources) {
|
|
51
|
+
lines.push(` - [${source.role}] ${contextPointerLabel(source.pointer)}: ${source.pointer.uri}`);
|
|
52
|
+
lines.push(` reason: ${source.reason}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (packet.facts?.length) {
|
|
56
|
+
lines.push("- facts:");
|
|
57
|
+
for (const fact of packet.facts) {
|
|
58
|
+
lines.push(` - ${fact.text}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (packet.exclusions?.length) {
|
|
62
|
+
lines.push("- exclusions:");
|
|
63
|
+
for (const exclusion of packet.exclusions) {
|
|
64
|
+
lines.push(` - ${exclusion}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return lines;
|
|
68
|
+
}
|
|
69
|
+
|
|
35
70
|
// src/git.ts
|
|
71
|
+
import { mkdirSync } from "fs";
|
|
72
|
+
import { dirname } from "path";
|
|
36
73
|
var INTERNAL_ARTIFACT_ROOTS = [".omx", ".codex", ".claude"];
|
|
37
74
|
function branchNameForRun(runId) {
|
|
38
75
|
const safeRunId = runId.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
@@ -51,9 +88,35 @@ function parseChangedFiles(statusOutput) {
|
|
|
51
88
|
return parseStatusEntries(statusOutput).map((entry) => entry.path).filter((path) => !isInternalArtifactPath(path));
|
|
52
89
|
}
|
|
53
90
|
async function createRunBranch(input) {
|
|
54
|
-
const result = await input.runner.run("git", ["checkout", "-B", input.branchName], { cwd: input.workspacePath });
|
|
91
|
+
const result = await input.runner.run("git", ["checkout", "-B", input.branchName, ...input.startPoint ? [input.startPoint] : []], { cwd: input.workspacePath });
|
|
55
92
|
await assertCommandSucceeded(result, "create run branch");
|
|
56
93
|
}
|
|
94
|
+
function worktreePathForRun(input) {
|
|
95
|
+
const safeRunId = input.runId.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
96
|
+
const root = input.worktreeRoot ?? `${input.workspacePath.replace(/\/$/, "")}/.worktrees/opentag`;
|
|
97
|
+
return `${root.replace(/\/$/, "")}/${safeRunId}`;
|
|
98
|
+
}
|
|
99
|
+
async function createRunWorktree(input) {
|
|
100
|
+
mkdirSync(dirname(input.worktreePath), { recursive: true });
|
|
101
|
+
const result = await input.runner.run(
|
|
102
|
+
"git",
|
|
103
|
+
["worktree", "add", "-B", input.branchName, input.worktreePath, input.baseBranch],
|
|
104
|
+
{ cwd: input.workspacePath }
|
|
105
|
+
);
|
|
106
|
+
await assertCommandSucceeded(result, "create run worktree");
|
|
107
|
+
}
|
|
108
|
+
async function removeRunWorktree(input) {
|
|
109
|
+
const result = await input.runner.run("git", ["worktree", "remove", "--force", input.worktreePath], {
|
|
110
|
+
cwd: input.workspacePath
|
|
111
|
+
});
|
|
112
|
+
await assertCommandSucceeded(result, "remove run worktree");
|
|
113
|
+
}
|
|
114
|
+
async function deleteRunBranch(input) {
|
|
115
|
+
const result = await input.runner.run("git", ["branch", "-D", input.branchName], {
|
|
116
|
+
cwd: input.workspacePath
|
|
117
|
+
});
|
|
118
|
+
await assertCommandSucceeded(result, "delete empty run branch");
|
|
119
|
+
}
|
|
57
120
|
async function changedFiles(input) {
|
|
58
121
|
const result = await input.runner.run("git", ["status", "--porcelain"], { cwd: input.workspacePath });
|
|
59
122
|
await assertCommandSucceeded(result, "read changed files");
|
|
@@ -74,15 +137,103 @@ async function cleanupInternalArtifacts(input) {
|
|
|
74
137
|
await assertCommandSucceeded(cleanResult, "clean internal artifacts");
|
|
75
138
|
return untrackedRoots;
|
|
76
139
|
}
|
|
140
|
+
async function commitRunChanges(input) {
|
|
141
|
+
const files = await changedFiles({ runner: input.runner, workspacePath: input.workspacePath });
|
|
142
|
+
if (files.length === 0) return false;
|
|
143
|
+
const addResult = await input.runner.run("git", ["add", "--", ...files], {
|
|
144
|
+
cwd: input.workspacePath
|
|
145
|
+
});
|
|
146
|
+
await assertCommandSucceeded(addResult, "stage run changes");
|
|
147
|
+
const commitResult = await input.runner.run("git", ["commit", "-m", input.message], {
|
|
148
|
+
cwd: input.workspacePath
|
|
149
|
+
});
|
|
150
|
+
await assertCommandSucceeded(commitResult, "commit run changes");
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
async function commitChangedFiles(input) {
|
|
154
|
+
if (input.files.length === 0) return;
|
|
155
|
+
const addResult = await input.runner.run("git", ["add", "--", ...input.files], { cwd: input.workspacePath });
|
|
156
|
+
await assertCommandSucceeded(addResult, "stage changed files");
|
|
157
|
+
const commitResult = await input.runner.run("git", ["commit", "-m", input.message], { cwd: input.workspacePath });
|
|
158
|
+
await assertCommandSucceeded(commitResult, "commit changed files");
|
|
159
|
+
}
|
|
77
160
|
async function pushBranch(input) {
|
|
78
161
|
const result = await input.runner.run("git", ["push", "-u", input.remote, input.branchName], { cwd: input.workspacePath });
|
|
79
162
|
await assertCommandSucceeded(result, "push run branch");
|
|
80
163
|
}
|
|
81
164
|
|
|
82
|
-
// src/
|
|
165
|
+
// src/result.ts
|
|
166
|
+
function createExecutorRunResult(input) {
|
|
167
|
+
const proposalId = `proposal_${input.runId}`;
|
|
168
|
+
const summary = input.output.slice(-4e3);
|
|
169
|
+
const suggestedChanges = input.changedFiles.length > 0 ? [
|
|
170
|
+
{
|
|
171
|
+
proposalId,
|
|
172
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
173
|
+
sourceRunId: input.runId,
|
|
174
|
+
summary: `${input.executorName} changed ${input.changedFiles.length} file(s) on branch ${input.branchName}.`,
|
|
175
|
+
intents: [
|
|
176
|
+
{
|
|
177
|
+
intentId: `${proposalId}_create_pr`,
|
|
178
|
+
domain: "pull_request",
|
|
179
|
+
action: "create_pull_request",
|
|
180
|
+
summary: `Create a pull request for branch ${input.branchName}.`,
|
|
181
|
+
params: {
|
|
182
|
+
title: `OpenTag run ${input.runId}`,
|
|
183
|
+
body: [
|
|
184
|
+
"## Summary",
|
|
185
|
+
"",
|
|
186
|
+
summary
|
|
187
|
+
].join("\n"),
|
|
188
|
+
head: input.branchName,
|
|
189
|
+
base: input.baseBranch ?? "main",
|
|
190
|
+
changedFiles: input.changedFiles,
|
|
191
|
+
risks: ["Creates a pull request from the executor-produced branch; review the diff before merging."],
|
|
192
|
+
executorConditions: ["isolated branch exists"]
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
intentId: `${proposalId}_link_branch`,
|
|
197
|
+
domain: "artifact_links",
|
|
198
|
+
action: "link_artifact",
|
|
199
|
+
summary: `Link the run branch ${input.branchName} to the work item.`,
|
|
200
|
+
params: { title: "Run branch", uri: input.branchName }
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
intentId: `${proposalId}_request_review`,
|
|
204
|
+
domain: "review",
|
|
205
|
+
action: "request_review",
|
|
206
|
+
summary: "Request human review of the generated code changes.",
|
|
207
|
+
params: { changedFiles: input.changedFiles }
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
preconditions: ["The local branch was generated from the checkout state available to the runner."]
|
|
211
|
+
}
|
|
212
|
+
] : void 0;
|
|
213
|
+
return {
|
|
214
|
+
conclusion: "success",
|
|
215
|
+
summary,
|
|
216
|
+
changedFiles: input.changedFiles,
|
|
217
|
+
artifacts: [
|
|
218
|
+
...input.changedFiles.length > 0 ? [{ kind: "patch", title: "Run branch", uri: input.branchName }] : [],
|
|
219
|
+
...input.extraArtifacts ?? []
|
|
220
|
+
],
|
|
221
|
+
...suggestedChanges ? { suggestedChanges } : {},
|
|
222
|
+
nextAction: input.changedFiles.length > 0 ? {
|
|
223
|
+
summary: "Review the proposed pull request action and reply `apply 1` if the branch should become a PR.",
|
|
224
|
+
hint: {
|
|
225
|
+
kind: "create_pull_request",
|
|
226
|
+
targetId: proposalId,
|
|
227
|
+
selectedIntentIds: [`${proposalId}_create_pr`]
|
|
228
|
+
}
|
|
229
|
+
} : "No file changes were detected."
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/claude-code.ts
|
|
83
234
|
function contextLines(context) {
|
|
84
235
|
if (!context.length) return "No additional context pointers were provided.";
|
|
85
|
-
return context.map((pointer) => `- ${pointer
|
|
236
|
+
return context.map((pointer) => `- ${contextPointerLabel2(pointer)}: ${pointer.uri}`).join("\n");
|
|
86
237
|
}
|
|
87
238
|
function buildPrompt(input) {
|
|
88
239
|
return [
|
|
@@ -92,29 +243,36 @@ function buildPrompt(input) {
|
|
|
92
243
|
"User request:",
|
|
93
244
|
input.rawText,
|
|
94
245
|
"",
|
|
246
|
+
...renderContextPacketForPrompt(input.contextPacket),
|
|
247
|
+
...input.contextPacket ? [""] : [],
|
|
95
248
|
"Context pointers:",
|
|
96
249
|
contextLines(input.context),
|
|
97
250
|
"",
|
|
98
|
-
"Work autonomously but keep the change narrow. Run relevant verification if you modify files.
|
|
251
|
+
"Work autonomously but keep the change narrow. Run relevant verification if you modify files.",
|
|
252
|
+
"End with a concise summary of what changed, what was verified, and the recommended next action."
|
|
99
253
|
].join("\n");
|
|
100
254
|
}
|
|
101
|
-
function
|
|
255
|
+
function createClaudeCodeExecutor(options = {}) {
|
|
102
256
|
const runner = options.runner ?? nodeCommandRunner;
|
|
103
|
-
const
|
|
257
|
+
const claudeCommand = options.claudeCommand ?? "claude";
|
|
104
258
|
return {
|
|
105
|
-
id: "
|
|
106
|
-
displayName: "
|
|
259
|
+
id: "claude-code",
|
|
260
|
+
displayName: "Claude Code Executor",
|
|
107
261
|
async canRun(input) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
262
|
+
try {
|
|
263
|
+
const claudeVersion = await runner.run(claudeCommand, ["--version"], { cwd: input.workspacePath });
|
|
264
|
+
if (claudeVersion.exitCode !== 0) {
|
|
265
|
+
return { ready: false, reason: `Claude Code CLI is not available: ${claudeVersion.stderr || claudeVersion.stdout}` };
|
|
266
|
+
}
|
|
267
|
+
} catch (error) {
|
|
268
|
+
return { ready: false, reason: `Claude Code CLI is not available: ${error instanceof Error ? error.message : String(error)}` };
|
|
111
269
|
}
|
|
112
270
|
const gitStatus = await runner.run("git", ["status", "--porcelain"], { cwd: input.workspacePath });
|
|
113
271
|
if (gitStatus.exitCode !== 0) {
|
|
114
272
|
return { ready: false, reason: `Workspace is not a git checkout: ${gitStatus.stderr || gitStatus.stdout}` };
|
|
115
273
|
}
|
|
116
274
|
if (gitStatus.stdout.trim().length > 0) {
|
|
117
|
-
return { ready: false, reason: "Workspace has uncommitted changes; refusing to run
|
|
275
|
+
return { ready: false, reason: "Workspace has uncommitted changes; refusing to run Claude Code executor." };
|
|
118
276
|
}
|
|
119
277
|
return { ready: true };
|
|
120
278
|
},
|
|
@@ -125,30 +283,38 @@ function createCodexExecutor(options = {}) {
|
|
|
125
283
|
message: `Creating isolated branch ${branchName}`,
|
|
126
284
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
127
285
|
});
|
|
128
|
-
await createRunBranch({
|
|
286
|
+
await createRunBranch({
|
|
287
|
+
runner,
|
|
288
|
+
workspacePath: input.workspacePath,
|
|
289
|
+
branchName,
|
|
290
|
+
...input.baseBranch ? { startPoint: input.baseBranch } : {}
|
|
291
|
+
});
|
|
129
292
|
await sink.emit({
|
|
130
293
|
type: "executor.progress",
|
|
131
|
-
message: "Starting
|
|
294
|
+
message: "Starting claude --print",
|
|
132
295
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
133
296
|
});
|
|
134
297
|
const args = [
|
|
135
|
-
"
|
|
136
|
-
"--
|
|
137
|
-
|
|
138
|
-
"--
|
|
139
|
-
"
|
|
298
|
+
"--print",
|
|
299
|
+
"--input-format",
|
|
300
|
+
"text",
|
|
301
|
+
"--output-format",
|
|
302
|
+
"text",
|
|
303
|
+
"--no-session-persistence",
|
|
140
304
|
...options.model ? ["--model", options.model] : [],
|
|
141
|
-
"-"
|
|
305
|
+
...options.permissionMode ? ["--permission-mode", options.permissionMode] : [],
|
|
306
|
+
...options.dangerouslySkipPermissions ? ["--dangerously-skip-permissions"] : []
|
|
142
307
|
];
|
|
143
|
-
const
|
|
308
|
+
const claudeResult = await runner.run(claudeCommand, args, {
|
|
144
309
|
cwd: input.workspacePath,
|
|
145
310
|
input: buildPrompt({
|
|
146
311
|
runId: input.runId,
|
|
147
312
|
rawText: input.command.rawText,
|
|
148
|
-
context: input.context
|
|
313
|
+
context: input.context,
|
|
314
|
+
contextPacket: input.contextPacket
|
|
149
315
|
})
|
|
150
316
|
});
|
|
151
|
-
await assertCommandSucceeded(
|
|
317
|
+
await assertCommandSucceeded(claudeResult, "claude --print");
|
|
152
318
|
const cleanedArtifacts = await cleanupInternalArtifacts({ runner, workspacePath: input.workspacePath });
|
|
153
319
|
if (cleanedArtifacts.length > 0) {
|
|
154
320
|
await sink.emit({
|
|
@@ -160,24 +326,396 @@ function createCodexExecutor(options = {}) {
|
|
|
160
326
|
const files = await changedFiles({ runner, workspacePath: input.workspacePath });
|
|
161
327
|
await sink.emit({
|
|
162
328
|
type: "executor.completed",
|
|
163
|
-
message: `
|
|
329
|
+
message: `Claude Code executor completed with ${files.length} changed file(s)`,
|
|
164
330
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
165
331
|
});
|
|
166
|
-
const output =
|
|
167
|
-
return {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
332
|
+
const output = claudeResult.stdout.trim() || claudeResult.stderr.trim() || "Claude Code completed without textual output.";
|
|
333
|
+
return createExecutorRunResult({
|
|
334
|
+
executorName: "Claude Code",
|
|
335
|
+
runId: input.runId,
|
|
336
|
+
branchName,
|
|
337
|
+
...input.baseBranch ? { baseBranch: input.baseBranch } : {},
|
|
338
|
+
output,
|
|
339
|
+
changedFiles: files
|
|
340
|
+
});
|
|
341
|
+
},
|
|
342
|
+
async cancel() {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// src/codex.ts
|
|
349
|
+
import { contextPointerLabel as contextPointerLabel3 } from "@opentag/core";
|
|
350
|
+
|
|
351
|
+
// src/security.ts
|
|
352
|
+
import { fileURLToPath } from "url";
|
|
353
|
+
import { isAbsolute, relative, resolve } from "path";
|
|
354
|
+
var DEFAULT_SAFE_ENV_NAMES = [
|
|
355
|
+
"CI",
|
|
356
|
+
"COLORTERM",
|
|
357
|
+
"CODEX_HOME",
|
|
358
|
+
"FORCE_COLOR",
|
|
359
|
+
"HOME",
|
|
360
|
+
"LANG",
|
|
361
|
+
"LOGNAME",
|
|
362
|
+
"NO_COLOR",
|
|
363
|
+
"PATH",
|
|
364
|
+
"PWD",
|
|
365
|
+
"SHELL",
|
|
366
|
+
"SSL_CERT_DIR",
|
|
367
|
+
"SSL_CERT_FILE",
|
|
368
|
+
"TERM",
|
|
369
|
+
"TMP",
|
|
370
|
+
"TMPDIR",
|
|
371
|
+
"TEMP",
|
|
372
|
+
"USER",
|
|
373
|
+
"XDG_CACHE_HOME",
|
|
374
|
+
"XDG_CONFIG_HOME",
|
|
375
|
+
"XDG_DATA_HOME"
|
|
376
|
+
];
|
|
377
|
+
var SAFE_ENV_PREFIXES = ["LC_"];
|
|
378
|
+
var SENSITIVE_ENV_PATTERNS = [
|
|
379
|
+
/TOKEN/,
|
|
380
|
+
/SECRET/,
|
|
381
|
+
/PASSWORD/,
|
|
382
|
+
/PASS$/,
|
|
383
|
+
/API[_-]?KEY/,
|
|
384
|
+
/CREDENTIAL/,
|
|
385
|
+
/COOKIE/,
|
|
386
|
+
/SESSION/,
|
|
387
|
+
/AUTH/,
|
|
388
|
+
/^AWS_/,
|
|
389
|
+
/^AZURE_/,
|
|
390
|
+
/^GCP_/,
|
|
391
|
+
/^GOOGLE_/,
|
|
392
|
+
/^OPENAI_/,
|
|
393
|
+
/^ANTHROPIC_/,
|
|
394
|
+
/^SLACK_/,
|
|
395
|
+
/^GITHUB_TOKEN$/,
|
|
396
|
+
/^GH_TOKEN$/,
|
|
397
|
+
/^SSH_/
|
|
398
|
+
];
|
|
399
|
+
var HIGH_RISK_TEXT_PATTERNS = [
|
|
400
|
+
{
|
|
401
|
+
code: "prompt.instruction_override",
|
|
402
|
+
pattern: /\b(ignore|disregard|forget)\s+(all\s+)?(previous|prior|system|developer|safety)\s+instructions\b/i,
|
|
403
|
+
message: "Request contains an instruction override pattern commonly used in prompt injection."
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
code: "prompt.secret_exfiltration",
|
|
407
|
+
pattern: /\b(print|dump|show|reveal|exfiltrate|send|upload|post|copy)\b[\s\S]{0,100}\b(secret|token|password|api[\s_-]?key|credential|environment variables?|env vars?)\b/i,
|
|
408
|
+
message: "Request appears to ask the runner to expose secrets or environment variables."
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
code: "prompt.sensitive_file_access",
|
|
412
|
+
pattern: /\b(cat|open|read|print|dump)\b[\s\S]{0,80}(~\/\.ssh|~\/\.aws|\.env\b|id_rsa|known_hosts|credentials\b)/i,
|
|
413
|
+
message: "Request appears to ask the runner to read sensitive local credential files."
|
|
414
|
+
}
|
|
415
|
+
];
|
|
416
|
+
function securityMode(policy) {
|
|
417
|
+
return policy?.mode ?? "enforce";
|
|
418
|
+
}
|
|
419
|
+
function isPathInside(childPath, parentPath) {
|
|
420
|
+
const child = resolve(childPath);
|
|
421
|
+
const parent = resolve(parentPath);
|
|
422
|
+
const pathFromParent = relative(parent, child);
|
|
423
|
+
return pathFromParent === "" || !pathFromParent.startsWith("..") && !isAbsolute(pathFromParent);
|
|
424
|
+
}
|
|
425
|
+
function fileContextPath(pointer, workspacePath) {
|
|
426
|
+
if (pointer.kind !== "file") return null;
|
|
427
|
+
if (pointer.uri.startsWith("file://")) {
|
|
428
|
+
return fileURLToPath(pointer.uri);
|
|
429
|
+
}
|
|
430
|
+
if (isAbsolute(pointer.uri)) {
|
|
431
|
+
return pointer.uri;
|
|
432
|
+
}
|
|
433
|
+
return resolve(workspacePath, pointer.uri);
|
|
434
|
+
}
|
|
435
|
+
function hasPermission(permissions, scope) {
|
|
436
|
+
return permissions?.some((permission) => permission.scope === scope) ?? false;
|
|
437
|
+
}
|
|
438
|
+
function needsWritePermission(command, executorId) {
|
|
439
|
+
if (executorId === "echo") return false;
|
|
440
|
+
return command.intent === "fix" || command.intent === "run";
|
|
441
|
+
}
|
|
442
|
+
function scanTextForHighRiskPatterns(input) {
|
|
443
|
+
const sources = [
|
|
444
|
+
{ label: "command", text: input.command.rawText },
|
|
445
|
+
...input.context.filter((pointer) => pointer.kind === "text").map((pointer) => ({ label: pointer.title ?? "text context", text: pointer.uri }))
|
|
446
|
+
];
|
|
447
|
+
const findings = [];
|
|
448
|
+
for (const source of sources) {
|
|
449
|
+
for (const rule of HIGH_RISK_TEXT_PATTERNS) {
|
|
450
|
+
if (rule.pattern.test(source.text)) {
|
|
451
|
+
findings.push({
|
|
452
|
+
code: rule.code,
|
|
453
|
+
severity: "block",
|
|
454
|
+
message: `${rule.message} Source: ${source.label}.`
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return findings;
|
|
460
|
+
}
|
|
461
|
+
function assessRunnerSecurity(input) {
|
|
462
|
+
const mode = securityMode(input.policy);
|
|
463
|
+
if (mode === "off") {
|
|
464
|
+
return { allowed: true, mode, findings: [] };
|
|
465
|
+
}
|
|
466
|
+
const findings = [];
|
|
467
|
+
if (!isAbsolute(input.workspacePath)) {
|
|
468
|
+
findings.push({
|
|
469
|
+
code: "workspace.relative_path",
|
|
470
|
+
severity: "block",
|
|
471
|
+
message: "Workspace path must be absolute before a local executor can run."
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
const workspacePath = resolve(input.workspacePath);
|
|
475
|
+
const executionPath = resolve(input.executionPath ?? input.workspacePath);
|
|
476
|
+
if (input.policy?.allowedWorkspaceRoot && !isPathInside(workspacePath, input.policy.allowedWorkspaceRoot)) {
|
|
477
|
+
findings.push({
|
|
478
|
+
code: "workspace.outside_allowed_root",
|
|
479
|
+
severity: "block",
|
|
480
|
+
message: "Workspace path is outside the configured allowed workspace root."
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
if (input.policy?.allowedWorkspaceRoot && !isPathInside(executionPath, input.policy.allowedWorkspaceRoot)) {
|
|
484
|
+
findings.push({
|
|
485
|
+
code: "execution.outside_allowed_root",
|
|
486
|
+
severity: "block",
|
|
487
|
+
message: "Execution path is outside the configured allowed workspace root."
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
for (const pointer of input.context) {
|
|
491
|
+
const filePath = fileContextPath(pointer, workspacePath);
|
|
492
|
+
if (filePath && !isPathInside(filePath, workspacePath)) {
|
|
493
|
+
findings.push({
|
|
494
|
+
code: "context.file_outside_workspace",
|
|
495
|
+
severity: "block",
|
|
496
|
+
message: `File context is outside the mapped workspace: ${pointer.uri}`
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if (needsWritePermission(input.command, input.executorId) && !hasPermission(input.permissions, "repo:write")) {
|
|
501
|
+
findings.push({
|
|
502
|
+
code: "permission.repo_write_required",
|
|
503
|
+
severity: "block",
|
|
504
|
+
message: "Write-capable commands require an explicit repo:write permission grant."
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
if (!input.policy?.allowUnsafePrompts) {
|
|
508
|
+
findings.push(...scanTextForHighRiskPatterns({ command: input.command, context: input.context }));
|
|
509
|
+
}
|
|
510
|
+
const hasBlockingFinding = findings.some((finding) => finding.severity === "block");
|
|
511
|
+
return {
|
|
512
|
+
allowed: mode === "audit" || !hasBlockingFinding,
|
|
513
|
+
mode,
|
|
514
|
+
findings
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function isSensitiveEnvName(name) {
|
|
518
|
+
const upperName = name.toUpperCase();
|
|
519
|
+
return SENSITIVE_ENV_PATTERNS.some((pattern) => pattern.test(upperName));
|
|
520
|
+
}
|
|
521
|
+
function isSafeEnvName(name, policy) {
|
|
522
|
+
const upperName = name.toUpperCase();
|
|
523
|
+
const safeNames = new Set([...DEFAULT_SAFE_ENV_NAMES, ...policy?.extraSafeEnv ?? []].map((envName) => envName.toUpperCase()));
|
|
524
|
+
return safeNames.has(upperName) || SAFE_ENV_PREFIXES.some((prefix) => upperName.startsWith(prefix));
|
|
525
|
+
}
|
|
526
|
+
function scrubEnvironment(env = process.env, policy) {
|
|
527
|
+
if (securityMode(policy) === "off") return { ...env };
|
|
528
|
+
const scrubbed = {};
|
|
529
|
+
for (const [name, value] of Object.entries(env)) {
|
|
530
|
+
if (typeof value !== "string") continue;
|
|
531
|
+
if (isSensitiveEnvName(name)) continue;
|
|
532
|
+
if (!isSafeEnvName(name, policy)) continue;
|
|
533
|
+
scrubbed[name] = value;
|
|
534
|
+
}
|
|
535
|
+
return scrubbed;
|
|
536
|
+
}
|
|
537
|
+
function formatSecurityAssessment(assessment) {
|
|
538
|
+
if (assessment.findings.length === 0) {
|
|
539
|
+
return `OpenTag runner security assessment passed in ${assessment.mode} mode.`;
|
|
540
|
+
}
|
|
541
|
+
const prefix = assessment.allowed ? `OpenTag runner security assessment reported ${assessment.findings.length} finding(s) in ${assessment.mode} mode.` : "OpenTag runner security blocked this run.";
|
|
542
|
+
const details = assessment.findings.map((finding) => `${finding.code}: ${finding.message}`).join(" ");
|
|
543
|
+
return `${prefix} ${details}`;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// src/codex.ts
|
|
547
|
+
function contextLines2(context) {
|
|
548
|
+
if (!context.length) return "No additional context pointers were provided.";
|
|
549
|
+
return context.map((pointer) => `- ${contextPointerLabel3(pointer)}: ${pointer.uri}`).join("\n");
|
|
550
|
+
}
|
|
551
|
+
function buildPrompt2(input) {
|
|
552
|
+
return [
|
|
553
|
+
"You are executing an OpenTag run in a local checkout.",
|
|
554
|
+
`Run ID: ${input.runId}`,
|
|
555
|
+
"",
|
|
556
|
+
"User request:",
|
|
557
|
+
input.rawText,
|
|
558
|
+
"",
|
|
559
|
+
...renderContextPacketForPrompt(input.contextPacket),
|
|
560
|
+
...input.contextPacket ? [""] : [],
|
|
561
|
+
"Context pointers:",
|
|
562
|
+
contextLines2(input.context),
|
|
563
|
+
"",
|
|
564
|
+
"Work autonomously but keep the change narrow. Run relevant verification if you modify files. End with a concise summary."
|
|
565
|
+
].join("\n");
|
|
566
|
+
}
|
|
567
|
+
function createCodexExecutor(options = {}) {
|
|
568
|
+
const runner = options.runner ?? nodeCommandRunner;
|
|
569
|
+
const codexCommand = options.codexCommand ?? "codex";
|
|
570
|
+
return {
|
|
571
|
+
id: "codex",
|
|
572
|
+
displayName: "Codex Executor",
|
|
573
|
+
async canRun(input) {
|
|
574
|
+
const codexVersion = await runner.run(codexCommand, ["--version"], { cwd: input.workspacePath });
|
|
575
|
+
if (codexVersion.exitCode !== 0) {
|
|
576
|
+
return { ready: false, reason: `Codex CLI is not available: ${codexVersion.stderr || codexVersion.stdout}` };
|
|
577
|
+
}
|
|
578
|
+
const gitRepo = await runner.run("git", ["rev-parse", "--show-toplevel"], { cwd: input.workspacePath });
|
|
579
|
+
if (gitRepo.exitCode !== 0) {
|
|
580
|
+
return { ready: false, reason: `Workspace is not a git checkout: ${gitRepo.stderr || gitRepo.stdout}` };
|
|
581
|
+
}
|
|
582
|
+
const baseBranch = input.baseBranch ?? "main";
|
|
583
|
+
const baseRef = await runner.run("git", ["rev-parse", "--verify", `${baseBranch}^{commit}`], {
|
|
584
|
+
cwd: input.workspacePath
|
|
585
|
+
});
|
|
586
|
+
if (baseRef.exitCode !== 0) {
|
|
587
|
+
return { ready: false, reason: `Base branch '${baseBranch}' is not available: ${baseRef.stderr || baseRef.stdout}` };
|
|
588
|
+
}
|
|
589
|
+
return { ready: true };
|
|
590
|
+
},
|
|
591
|
+
async run(input, sink) {
|
|
592
|
+
const security = options.security;
|
|
593
|
+
const worktreePath = worktreePathForRun({
|
|
594
|
+
workspacePath: input.workspacePath,
|
|
595
|
+
runId: input.runId,
|
|
596
|
+
...input.worktreeRoot ? { worktreeRoot: input.worktreeRoot } : {}
|
|
597
|
+
});
|
|
598
|
+
const assessment = assessRunnerSecurity({
|
|
599
|
+
executorId: "codex",
|
|
600
|
+
workspacePath: input.workspacePath,
|
|
601
|
+
executionPath: worktreePath,
|
|
602
|
+
command: input.command,
|
|
603
|
+
context: input.context,
|
|
604
|
+
...input.permissions ? { permissions: input.permissions } : {},
|
|
605
|
+
...security ? { policy: security } : {}
|
|
606
|
+
});
|
|
607
|
+
if (assessment.findings.length > 0) {
|
|
608
|
+
await sink.emit({
|
|
609
|
+
type: assessment.allowed ? "executor.progress" : "executor.failed",
|
|
610
|
+
message: formatSecurityAssessment(assessment),
|
|
611
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
if (!assessment.allowed) {
|
|
615
|
+
return {
|
|
616
|
+
conclusion: "needs_human",
|
|
617
|
+
summary: formatSecurityAssessment(assessment),
|
|
618
|
+
nextAction: "Review the request and rerun with a narrower prompt or an explicit local policy override if appropriate."
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
const branchName = branchNameForRun(input.runId);
|
|
622
|
+
const baseBranch = input.baseBranch ?? "main";
|
|
623
|
+
const keepWorktree = input.keepWorktree ?? "on_failure";
|
|
624
|
+
let completed = false;
|
|
625
|
+
let changedFileCount;
|
|
626
|
+
await sink.emit({
|
|
627
|
+
type: "executor.started",
|
|
628
|
+
message: `Creating isolated worktree ${worktreePath} on ${branchName}`,
|
|
629
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
630
|
+
});
|
|
631
|
+
try {
|
|
632
|
+
await createRunWorktree({
|
|
633
|
+
runner,
|
|
634
|
+
workspacePath: input.workspacePath,
|
|
635
|
+
worktreePath,
|
|
636
|
+
branchName,
|
|
637
|
+
baseBranch
|
|
638
|
+
});
|
|
639
|
+
await sink.emit({
|
|
640
|
+
type: "executor.progress",
|
|
641
|
+
message: "Starting codex exec",
|
|
642
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
643
|
+
});
|
|
644
|
+
const args = [
|
|
645
|
+
"exec",
|
|
646
|
+
"--cd",
|
|
647
|
+
worktreePath,
|
|
648
|
+
"--full-auto",
|
|
649
|
+
"--ephemeral",
|
|
650
|
+
...options.model ? ["--model", options.model] : [],
|
|
651
|
+
"-"
|
|
652
|
+
];
|
|
653
|
+
const codexResult = await runner.run(codexCommand, args, {
|
|
654
|
+
cwd: worktreePath,
|
|
655
|
+
env: scrubEnvironment(void 0, security),
|
|
656
|
+
input: buildPrompt2({
|
|
657
|
+
runId: input.runId,
|
|
658
|
+
rawText: input.command.rawText,
|
|
659
|
+
context: input.context,
|
|
660
|
+
contextPacket: input.contextPacket
|
|
661
|
+
})
|
|
662
|
+
});
|
|
663
|
+
await assertCommandSucceeded(codexResult, "codex exec");
|
|
664
|
+
const cleanedArtifacts = await cleanupInternalArtifacts({ runner, workspacePath: worktreePath });
|
|
665
|
+
if (cleanedArtifacts.length > 0) {
|
|
666
|
+
await sink.emit({
|
|
667
|
+
type: "executor.progress",
|
|
668
|
+
message: `Cleaned internal artifacts: ${cleanedArtifacts.join(", ")}`,
|
|
669
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
const files = await changedFiles({ runner, workspacePath: worktreePath });
|
|
673
|
+
changedFileCount = files.length;
|
|
674
|
+
if (files.length > 0) {
|
|
675
|
+
await sink.emit({
|
|
676
|
+
type: "executor.progress",
|
|
677
|
+
message: `Committing ${files.length} changed file(s) to ${branchName}`,
|
|
678
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
679
|
+
});
|
|
680
|
+
await commitRunChanges({
|
|
681
|
+
runner,
|
|
682
|
+
workspacePath: worktreePath,
|
|
683
|
+
message: `OpenTag run ${input.runId}`
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
completed = true;
|
|
687
|
+
await sink.emit({
|
|
688
|
+
type: "executor.completed",
|
|
689
|
+
message: `Codex executor completed with ${files.length} changed file(s)`,
|
|
690
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
691
|
+
});
|
|
692
|
+
const output = codexResult.stdout.trim() || codexResult.stderr.trim() || "Codex completed without textual output.";
|
|
693
|
+
return createExecutorRunResult({
|
|
694
|
+
executorName: "Codex",
|
|
695
|
+
runId: input.runId,
|
|
696
|
+
branchName,
|
|
697
|
+
...input.baseBranch ? { baseBranch: input.baseBranch } : {},
|
|
698
|
+
output,
|
|
699
|
+
changedFiles: files,
|
|
700
|
+
extraArtifacts: keepWorktree === "always" ? [{ title: "Run worktree", uri: worktreePath }] : []
|
|
701
|
+
});
|
|
702
|
+
} finally {
|
|
703
|
+
const shouldRemove = keepWorktree === "never" || keepWorktree === "on_failure" && completed;
|
|
704
|
+
if (shouldRemove) {
|
|
705
|
+
try {
|
|
706
|
+
await removeRunWorktree({ runner, workspacePath: input.workspacePath, worktreePath });
|
|
707
|
+
if (completed && changedFileCount === 0) {
|
|
708
|
+
await deleteRunBranch({ runner, workspacePath: input.workspacePath, branchName });
|
|
709
|
+
}
|
|
710
|
+
} catch (error) {
|
|
711
|
+
await sink.emit({
|
|
712
|
+
type: "executor.progress",
|
|
713
|
+
message: `Could not clean up run worktree or branch for ${worktreePath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
714
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
715
|
+
});
|
|
177
716
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
};
|
|
717
|
+
}
|
|
718
|
+
}
|
|
181
719
|
},
|
|
182
720
|
async cancel() {
|
|
183
721
|
return;
|
|
@@ -216,7 +754,11 @@ function createEchoExecutor() {
|
|
|
216
754
|
outcome: "passed",
|
|
217
755
|
excerpt: input.command.rawText
|
|
218
756
|
}
|
|
219
|
-
]
|
|
757
|
+
],
|
|
758
|
+
nextAction: {
|
|
759
|
+
summary: "No external state change is suggested for the echo executor result.",
|
|
760
|
+
hint: { kind: "none" }
|
|
761
|
+
}
|
|
220
762
|
};
|
|
221
763
|
},
|
|
222
764
|
async cancel() {
|
|
@@ -225,17 +767,30 @@ function createEchoExecutor() {
|
|
|
225
767
|
};
|
|
226
768
|
}
|
|
227
769
|
export {
|
|
770
|
+
DEFAULT_SAFE_ENV_NAMES,
|
|
228
771
|
assertCommandSucceeded,
|
|
772
|
+
assessRunnerSecurity,
|
|
229
773
|
branchNameForRun,
|
|
230
774
|
changedFiles,
|
|
231
775
|
cleanupInternalArtifacts,
|
|
776
|
+
commitChangedFiles,
|
|
777
|
+
commitRunChanges,
|
|
778
|
+
createClaudeCodeExecutor,
|
|
232
779
|
createCodexExecutor,
|
|
233
780
|
createEchoExecutor,
|
|
781
|
+
createExecutorRunResult,
|
|
234
782
|
createRunBranch,
|
|
783
|
+
createRunWorktree,
|
|
784
|
+
deleteRunBranch,
|
|
785
|
+
formatSecurityAssessment,
|
|
235
786
|
isInternalArtifactPath,
|
|
236
787
|
nodeCommandRunner,
|
|
237
788
|
parseChangedFiles,
|
|
238
789
|
parseStatusEntries,
|
|
239
|
-
pushBranch
|
|
790
|
+
pushBranch,
|
|
791
|
+
removeRunWorktree,
|
|
792
|
+
renderContextPacketForPrompt,
|
|
793
|
+
scrubEnvironment,
|
|
794
|
+
worktreePathForRun
|
|
240
795
|
};
|
|
241
796
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/command.ts","../src/git.ts","../src/codex.ts","../src/echo.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\n\nexport type CommandResult = {\n exitCode: number;\n stdout: string;\n stderr: string;\n};\n\nexport type CommandRunner = {\n run(command: string, args: string[], options?: { cwd?: string; input?: string }): Promise<CommandResult>;\n};\n\nexport const nodeCommandRunner: CommandRunner = {\n run(command, args, options = {}) {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"]\n });\n const stdout: Buffer[] = [];\n const stderr: Buffer[] = [];\n\n child.stdout.on(\"data\", (chunk: Buffer) => stdout.push(chunk));\n child.stderr.on(\"data\", (chunk: Buffer) => stderr.push(chunk));\n child.on(\"error\", reject);\n child.on(\"close\", (exitCode) => {\n resolve({\n exitCode: exitCode ?? 1,\n stdout: Buffer.concat(stdout).toString(\"utf8\"),\n stderr: Buffer.concat(stderr).toString(\"utf8\")\n });\n });\n\n if (options.input) {\n child.stdin.write(options.input);\n }\n child.stdin.end();\n });\n }\n};\n\nexport async function assertCommandSucceeded(result: CommandResult, label: string): Promise<void> {\n if (result.exitCode !== 0) {\n throw new Error(`${label} failed with exit code ${result.exitCode}: ${result.stderr || result.stdout}`);\n }\n}\n","import type { CommandRunner } from \"./command.js\";\nimport { assertCommandSucceeded } from \"./command.js\";\n\nexport type GitStatusEntry = {\n status: string;\n path: string;\n};\n\nconst INTERNAL_ARTIFACT_ROOTS = [\".omx\", \".codex\", \".claude\"];\n\nexport function branchNameForRun(runId: string): string {\n const safeRunId = runId.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n return `opentag/${safeRunId}`;\n}\n\nexport function parseStatusEntries(statusOutput: string): GitStatusEntry[] {\n return statusOutput\n .split(\"\\n\")\n .map((line) => line.replace(/\\r$/, \"\"))\n .filter(Boolean)\n .map((line) => ({\n status: line.slice(0, 2),\n path: line.slice(3).trim()\n }))\n .filter((entry) => entry.path.length > 0);\n}\n\nexport function isInternalArtifactPath(path: string): boolean {\n return INTERNAL_ARTIFACT_ROOTS.some((root) => path === root || path.startsWith(`${root}/`));\n}\n\nexport function parseChangedFiles(statusOutput: string): string[] {\n return parseStatusEntries(statusOutput)\n .map((entry) => entry.path)\n .filter((path) => !isInternalArtifactPath(path));\n}\n\nexport async function createRunBranch(input: {\n runner: CommandRunner;\n workspacePath: string;\n branchName: string;\n}): Promise<void> {\n const result = await input.runner.run(\"git\", [\"checkout\", \"-B\", input.branchName], { cwd: input.workspacePath });\n await assertCommandSucceeded(result, \"create run branch\");\n}\n\nexport async function changedFiles(input: { runner: CommandRunner; workspacePath: string }): Promise<string[]> {\n const result = await input.runner.run(\"git\", [\"status\", \"--porcelain\"], { cwd: input.workspacePath });\n await assertCommandSucceeded(result, \"read changed files\");\n return parseChangedFiles(result.stdout);\n}\n\nexport async function cleanupInternalArtifacts(input: { runner: CommandRunner; workspacePath: string }): Promise<string[]> {\n const statusResult = await input.runner.run(\"git\", [\"status\", \"--porcelain\"], { cwd: input.workspacePath });\n await assertCommandSucceeded(statusResult, \"scan internal artifacts\");\n const untrackedRoots = Array.from(\n new Set(\n parseStatusEntries(statusResult.stdout)\n .filter((entry) => entry.status === \"??\" && isInternalArtifactPath(entry.path))\n .map((entry) => entry.path.split(\"/\", 1)[0] ?? entry.path)\n )\n );\n if (untrackedRoots.length === 0) return [];\n\n const cleanResult = await input.runner.run(\"git\", [\"clean\", \"-fd\", \"--\", ...untrackedRoots], {\n cwd: input.workspacePath\n });\n await assertCommandSucceeded(cleanResult, \"clean internal artifacts\");\n return untrackedRoots;\n}\n\nexport async function pushBranch(input: {\n runner: CommandRunner;\n workspacePath: string;\n remote: string;\n branchName: string;\n}): Promise<void> {\n const result = await input.runner.run(\"git\", [\"push\", \"-u\", input.remote, input.branchName], { cwd: input.workspacePath });\n await assertCommandSucceeded(result, \"push run branch\");\n}\n","import type { ContextPointer } from \"@opentag/core\";\nimport { assertCommandSucceeded, nodeCommandRunner, type CommandRunner } from \"./command.js\";\nimport type { ExecutorAdapter } from \"./executor.js\";\nimport { branchNameForRun, changedFiles, cleanupInternalArtifacts, createRunBranch } from \"./git.js\";\n\nexport type CodexExecutorOptions = {\n runner?: CommandRunner;\n codexCommand?: string;\n model?: string;\n};\n\nfunction contextLines(context: ContextPointer[]): string {\n if (!context.length) return \"No additional context pointers were provided.\";\n return context.map((pointer) => `- ${pointer.kind}: ${pointer.uri}`).join(\"\\n\");\n}\n\nfunction buildPrompt(input: {\n runId: string;\n rawText: string;\n context: ContextPointer[];\n}): string {\n return [\n \"You are executing an OpenTag run in a local checkout.\",\n `Run ID: ${input.runId}`,\n \"\",\n \"User request:\",\n input.rawText,\n \"\",\n \"Context pointers:\",\n contextLines(input.context),\n \"\",\n \"Work autonomously but keep the change narrow. Run relevant verification if you modify files. End with a concise summary.\"\n ].join(\"\\n\");\n}\n\nexport function createCodexExecutor(options: CodexExecutorOptions = {}): ExecutorAdapter {\n const runner = options.runner ?? nodeCommandRunner;\n const codexCommand = options.codexCommand ?? \"codex\";\n\n return {\n id: \"codex\",\n displayName: \"Codex Executor\",\n async canRun(input) {\n const codexVersion = await runner.run(codexCommand, [\"--version\"], { cwd: input.workspacePath });\n if (codexVersion.exitCode !== 0) {\n return { ready: false, reason: `Codex CLI is not available: ${codexVersion.stderr || codexVersion.stdout}` };\n }\n const gitStatus = await runner.run(\"git\", [\"status\", \"--porcelain\"], { cwd: input.workspacePath });\n if (gitStatus.exitCode !== 0) {\n return { ready: false, reason: `Workspace is not a git checkout: ${gitStatus.stderr || gitStatus.stdout}` };\n }\n if (gitStatus.stdout.trim().length > 0) {\n return { ready: false, reason: \"Workspace has uncommitted changes; refusing to run Codex executor.\" };\n }\n return { ready: true };\n },\n async run(input, sink) {\n const branchName = branchNameForRun(input.runId);\n await sink.emit({\n type: \"executor.started\",\n message: `Creating isolated branch ${branchName}`,\n at: new Date().toISOString()\n });\n await createRunBranch({ runner, workspacePath: input.workspacePath, branchName });\n\n await sink.emit({\n type: \"executor.progress\",\n message: \"Starting codex exec\",\n at: new Date().toISOString()\n });\n\n const args = [\n \"exec\",\n \"--cd\",\n input.workspacePath,\n \"--full-auto\",\n \"--ephemeral\",\n ...(options.model ? [\"--model\", options.model] : []),\n \"-\"\n ];\n const codexResult = await runner.run(codexCommand, args, {\n cwd: input.workspacePath,\n input: buildPrompt({\n runId: input.runId,\n rawText: input.command.rawText,\n context: input.context\n })\n });\n await assertCommandSucceeded(codexResult, \"codex exec\");\n\n const cleanedArtifacts = await cleanupInternalArtifacts({ runner, workspacePath: input.workspacePath });\n if (cleanedArtifacts.length > 0) {\n await sink.emit({\n type: \"executor.progress\",\n message: `Cleaned internal artifacts: ${cleanedArtifacts.join(\", \")}`,\n at: new Date().toISOString()\n });\n }\n\n const files = await changedFiles({ runner, workspacePath: input.workspacePath });\n await sink.emit({\n type: \"executor.completed\",\n message: `Codex executor completed with ${files.length} changed file(s)`,\n at: new Date().toISOString()\n });\n\n const output = codexResult.stdout.trim() || codexResult.stderr.trim() || \"Codex completed without textual output.\";\n return {\n conclusion: \"success\",\n summary: output.slice(-4000),\n changedFiles: files,\n artifacts: [{ title: \"Run branch\", uri: branchName }],\n verification: [\n {\n command: \"codex exec\",\n outcome: \"passed\",\n excerpt: output.slice(-1000)\n }\n ],\n nextAction: files.length > 0 ? \"Review the local branch and create a pull request.\" : \"No file changes were detected.\"\n };\n },\n async cancel() {\n return;\n }\n };\n}\n","import type { ExecutorAdapter } from \"./executor.js\";\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nexport function createEchoExecutor(): ExecutorAdapter {\n return {\n id: \"echo\",\n displayName: \"Echo Executor\",\n async canRun() {\n return { ready: true };\n },\n async run(input, sink) {\n await sink.emit({\n type: \"executor.started\",\n message: `Echo executor started for ${input.runId}`,\n at: nowIso()\n });\n await sink.emit({\n type: \"executor.completed\",\n message: `Echo executor completed for ${input.runId}`,\n at: nowIso()\n });\n return {\n conclusion: \"success\",\n summary: `Echoed OpenTag command: ${input.command.rawText}`,\n verification: [\n {\n command: \"echo\",\n outcome: \"passed\",\n excerpt: input.command.rawText\n }\n ]\n };\n },\n async cancel() {\n return;\n }\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/claude-code.ts","../src/command.ts","../src/executor.ts","../src/git.ts","../src/result.ts","../src/codex.ts","../src/security.ts","../src/echo.ts"],"sourcesContent":["import { contextPointerLabel, type ContextPacket, type ContextPointer } from \"@opentag/core\";\nimport { assertCommandSucceeded, nodeCommandRunner, type CommandRunner } from \"./command.js\";\nimport { renderContextPacketForPrompt, type ExecutorAdapter } from \"./executor.js\";\nimport { branchNameForRun, changedFiles, cleanupInternalArtifacts, createRunBranch } from \"./git.js\";\nimport { createExecutorRunResult } from \"./result.js\";\n\nexport type ClaudeCodeExecutorOptions = {\n runner?: CommandRunner;\n claudeCommand?: string;\n model?: string;\n permissionMode?: \"acceptEdits\" | \"auto\" | \"bypassPermissions\" | \"default\" | \"plan\";\n dangerouslySkipPermissions?: boolean;\n};\n\nfunction contextLines(context: ContextPointer[]): string {\n if (!context.length) return \"No additional context pointers were provided.\";\n return context.map((pointer) => `- ${contextPointerLabel(pointer)}: ${pointer.uri}`).join(\"\\n\");\n}\n\nfunction buildPrompt(input: {\n runId: string;\n rawText: string;\n context: ContextPointer[];\n contextPacket: ContextPacket | undefined;\n}): string {\n return [\n \"You are executing an OpenTag run in a local checkout.\",\n `Run ID: ${input.runId}`,\n \"\",\n \"User request:\",\n input.rawText,\n \"\",\n ...renderContextPacketForPrompt(input.contextPacket),\n ...(input.contextPacket ? [\"\"] : []),\n \"Context pointers:\",\n contextLines(input.context),\n \"\",\n \"Work autonomously but keep the change narrow. Run relevant verification if you modify files.\",\n \"End with a concise summary of what changed, what was verified, and the recommended next action.\"\n ].join(\"\\n\");\n}\n\nexport function createClaudeCodeExecutor(options: ClaudeCodeExecutorOptions = {}): ExecutorAdapter {\n const runner = options.runner ?? nodeCommandRunner;\n const claudeCommand = options.claudeCommand ?? \"claude\";\n\n return {\n id: \"claude-code\",\n displayName: \"Claude Code Executor\",\n async canRun(input) {\n try {\n const claudeVersion = await runner.run(claudeCommand, [\"--version\"], { cwd: input.workspacePath });\n if (claudeVersion.exitCode !== 0) {\n return { ready: false, reason: `Claude Code CLI is not available: ${claudeVersion.stderr || claudeVersion.stdout}` };\n }\n } catch (error) {\n return { ready: false, reason: `Claude Code CLI is not available: ${error instanceof Error ? error.message : String(error)}` };\n }\n const gitStatus = await runner.run(\"git\", [\"status\", \"--porcelain\"], { cwd: input.workspacePath });\n if (gitStatus.exitCode !== 0) {\n return { ready: false, reason: `Workspace is not a git checkout: ${gitStatus.stderr || gitStatus.stdout}` };\n }\n if (gitStatus.stdout.trim().length > 0) {\n return { ready: false, reason: \"Workspace has uncommitted changes; refusing to run Claude Code executor.\" };\n }\n return { ready: true };\n },\n async run(input, sink) {\n const branchName = branchNameForRun(input.runId);\n await sink.emit({\n type: \"executor.started\",\n message: `Creating isolated branch ${branchName}`,\n at: new Date().toISOString()\n });\n await createRunBranch({\n runner,\n workspacePath: input.workspacePath,\n branchName,\n ...(input.baseBranch ? { startPoint: input.baseBranch } : {})\n });\n\n await sink.emit({\n type: \"executor.progress\",\n message: \"Starting claude --print\",\n at: new Date().toISOString()\n });\n\n const args = [\n \"--print\",\n \"--input-format\",\n \"text\",\n \"--output-format\",\n \"text\",\n \"--no-session-persistence\",\n ...(options.model ? [\"--model\", options.model] : []),\n ...(options.permissionMode ? [\"--permission-mode\", options.permissionMode] : []),\n ...(options.dangerouslySkipPermissions ? [\"--dangerously-skip-permissions\"] : [])\n ];\n const claudeResult = await runner.run(claudeCommand, args, {\n cwd: input.workspacePath,\n input: buildPrompt({\n runId: input.runId,\n rawText: input.command.rawText,\n context: input.context,\n contextPacket: input.contextPacket\n })\n });\n await assertCommandSucceeded(claudeResult, \"claude --print\");\n\n const cleanedArtifacts = await cleanupInternalArtifacts({ runner, workspacePath: input.workspacePath });\n if (cleanedArtifacts.length > 0) {\n await sink.emit({\n type: \"executor.progress\",\n message: `Cleaned internal artifacts: ${cleanedArtifacts.join(\", \")}`,\n at: new Date().toISOString()\n });\n }\n\n const files = await changedFiles({ runner, workspacePath: input.workspacePath });\n await sink.emit({\n type: \"executor.completed\",\n message: `Claude Code executor completed with ${files.length} changed file(s)`,\n at: new Date().toISOString()\n });\n\n const output = claudeResult.stdout.trim() || claudeResult.stderr.trim() || \"Claude Code completed without textual output.\";\n return createExecutorRunResult({\n executorName: \"Claude Code\",\n runId: input.runId,\n branchName,\n ...(input.baseBranch ? { baseBranch: input.baseBranch } : {}),\n output,\n changedFiles: files\n });\n },\n async cancel() {\n return;\n }\n };\n}\n","import { spawn } from \"node:child_process\";\n\nexport type CommandResult = {\n exitCode: number;\n stdout: string;\n stderr: string;\n};\n\nexport type CommandEnvironment = Record<string, string | undefined>;\n\nexport type CommandRunner = {\n run(command: string, args: string[], options?: { cwd?: string; input?: string; env?: CommandEnvironment }): Promise<CommandResult>;\n};\n\nexport const nodeCommandRunner: CommandRunner = {\n run(command, args, options = {}) {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"]\n });\n const stdout: Buffer[] = [];\n const stderr: Buffer[] = [];\n\n child.stdout.on(\"data\", (chunk: Buffer) => stdout.push(chunk));\n child.stderr.on(\"data\", (chunk: Buffer) => stderr.push(chunk));\n child.on(\"error\", reject);\n child.on(\"close\", (exitCode) => {\n resolve({\n exitCode: exitCode ?? 1,\n stdout: Buffer.concat(stdout).toString(\"utf8\"),\n stderr: Buffer.concat(stderr).toString(\"utf8\")\n });\n });\n\n if (options.input) {\n child.stdin.write(options.input);\n }\n child.stdin.end();\n });\n }\n};\n\nexport async function assertCommandSucceeded(result: CommandResult, label: string): Promise<void> {\n if (result.exitCode !== 0) {\n throw new Error(`${label} failed with exit code ${result.exitCode}: ${result.stderr || result.stdout}`);\n }\n}\n","import { contextPointerLabel, type ContextPacket, type ContextPointer, type OpenTagCommand, type OpenTagRunResult, type PermissionGrant } from \"@opentag/core\";\n\nexport type ExecutorEvent = {\n type: \"executor.started\" | \"executor.progress\" | \"executor.completed\" | \"executor.failed\";\n message: string;\n at: string;\n};\n\nexport type ExecutorEventSink = {\n emit(event: ExecutorEvent): Promise<void>;\n};\n\nexport type ExecutorRunInput = {\n runId: string;\n workspacePath: string;\n command: OpenTagCommand;\n context: ContextPointer[];\n contextPacket?: ContextPacket;\n permissions?: PermissionGrant[];\n baseBranch?: string;\n worktreeRoot?: string;\n keepWorktree?: \"always\" | \"on_failure\" | \"never\";\n};\n\nexport function renderContextPacketForPrompt(packet?: ContextPacket): string[] {\n if (!packet) return [];\n\n const lines = [\"OpenTag context packet:\", `- summary: ${packet.summary}`];\n\n if (packet.intent) {\n lines.push(`- intent: ${packet.intent.normalizedIntent}`);\n lines.push(`- requested by: ${packet.intent.requestedBy.provider}:${packet.intent.requestedBy.providerUserId}`);\n }\n\n if (packet.sources?.length) {\n lines.push(\"- selected sources:\");\n for (const source of packet.sources) {\n lines.push(` - [${source.role}] ${contextPointerLabel(source.pointer)}: ${source.pointer.uri}`);\n lines.push(` reason: ${source.reason}`);\n }\n }\n\n if (packet.facts?.length) {\n lines.push(\"- facts:\");\n for (const fact of packet.facts) {\n lines.push(` - ${fact.text}`);\n }\n }\n\n if (packet.exclusions?.length) {\n lines.push(\"- exclusions:\");\n for (const exclusion of packet.exclusions) {\n lines.push(` - ${exclusion}`);\n }\n }\n\n return lines;\n}\n\nexport type ExecutorReadiness = {\n ready: boolean;\n reason?: string;\n};\n\nexport type ExecutorAdapter = {\n id: string;\n displayName: string;\n canRun(input: ExecutorRunInput): Promise<ExecutorReadiness>;\n run(input: ExecutorRunInput, sink: ExecutorEventSink): Promise<OpenTagRunResult>;\n cancel(runId: string): Promise<void>;\n};\n","import { mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { CommandRunner } from \"./command.js\";\nimport { assertCommandSucceeded } from \"./command.js\";\n\nexport type GitStatusEntry = {\n status: string;\n path: string;\n};\n\nconst INTERNAL_ARTIFACT_ROOTS = [\".omx\", \".codex\", \".claude\"];\n\nexport function branchNameForRun(runId: string): string {\n const safeRunId = runId.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n return `opentag/${safeRunId}`;\n}\n\nexport function parseStatusEntries(statusOutput: string): GitStatusEntry[] {\n return statusOutput\n .split(\"\\n\")\n .map((line) => line.replace(/\\r$/, \"\"))\n .filter(Boolean)\n .map((line) => ({\n status: line.slice(0, 2),\n path: line.slice(3).trim()\n }))\n .filter((entry) => entry.path.length > 0);\n}\n\nexport function isInternalArtifactPath(path: string): boolean {\n return INTERNAL_ARTIFACT_ROOTS.some((root) => path === root || path.startsWith(`${root}/`));\n}\n\nexport function parseChangedFiles(statusOutput: string): string[] {\n return parseStatusEntries(statusOutput)\n .map((entry) => entry.path)\n .filter((path) => !isInternalArtifactPath(path));\n}\n\nexport async function createRunBranch(input: {\n runner: CommandRunner;\n workspacePath: string;\n branchName: string;\n startPoint?: string;\n}): Promise<void> {\n const result = await input.runner.run(\"git\", [\"checkout\", \"-B\", input.branchName, ...(input.startPoint ? [input.startPoint] : [])], { cwd: input.workspacePath });\n await assertCommandSucceeded(result, \"create run branch\");\n}\n\nexport function worktreePathForRun(input: {\n workspacePath: string;\n runId: string;\n worktreeRoot?: string;\n}): string {\n const safeRunId = input.runId.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n const root = input.worktreeRoot ?? `${input.workspacePath.replace(/\\/$/, \"\")}/.worktrees/opentag`;\n return `${root.replace(/\\/$/, \"\")}/${safeRunId}`;\n}\n\nexport async function createRunWorktree(input: {\n runner: CommandRunner;\n workspacePath: string;\n worktreePath: string;\n branchName: string;\n baseBranch: string;\n}): Promise<void> {\n mkdirSync(dirname(input.worktreePath), { recursive: true });\n const result = await input.runner.run(\n \"git\",\n [\"worktree\", \"add\", \"-B\", input.branchName, input.worktreePath, input.baseBranch],\n { cwd: input.workspacePath }\n );\n await assertCommandSucceeded(result, \"create run worktree\");\n}\n\nexport async function removeRunWorktree(input: {\n runner: CommandRunner;\n workspacePath: string;\n worktreePath: string;\n}): Promise<void> {\n const result = await input.runner.run(\"git\", [\"worktree\", \"remove\", \"--force\", input.worktreePath], {\n cwd: input.workspacePath\n });\n await assertCommandSucceeded(result, \"remove run worktree\");\n}\n\nexport async function deleteRunBranch(input: { runner: CommandRunner; workspacePath: string; branchName: string }): Promise<void> {\n const result = await input.runner.run(\"git\", [\"branch\", \"-D\", input.branchName], {\n cwd: input.workspacePath\n });\n await assertCommandSucceeded(result, \"delete empty run branch\");\n}\n\nexport async function changedFiles(input: { runner: CommandRunner; workspacePath: string }): Promise<string[]> {\n const result = await input.runner.run(\"git\", [\"status\", \"--porcelain\"], { cwd: input.workspacePath });\n await assertCommandSucceeded(result, \"read changed files\");\n return parseChangedFiles(result.stdout);\n}\n\nexport async function cleanupInternalArtifacts(input: { runner: CommandRunner; workspacePath: string }): Promise<string[]> {\n const statusResult = await input.runner.run(\"git\", [\"status\", \"--porcelain\"], { cwd: input.workspacePath });\n await assertCommandSucceeded(statusResult, \"scan internal artifacts\");\n const untrackedRoots = Array.from(\n new Set(\n parseStatusEntries(statusResult.stdout)\n .filter((entry) => entry.status === \"??\" && isInternalArtifactPath(entry.path))\n .map((entry) => entry.path.split(\"/\", 1)[0] ?? entry.path)\n )\n );\n if (untrackedRoots.length === 0) return [];\n\n const cleanResult = await input.runner.run(\"git\", [\"clean\", \"-fd\", \"--\", ...untrackedRoots], {\n cwd: input.workspacePath\n });\n await assertCommandSucceeded(cleanResult, \"clean internal artifacts\");\n return untrackedRoots;\n}\n\nexport async function commitRunChanges(input: {\n runner: CommandRunner;\n workspacePath: string;\n message: string;\n}): Promise<boolean> {\n const files = await changedFiles({ runner: input.runner, workspacePath: input.workspacePath });\n if (files.length === 0) return false;\n\n const addResult = await input.runner.run(\"git\", [\"add\", \"--\", ...files], {\n cwd: input.workspacePath\n });\n await assertCommandSucceeded(addResult, \"stage run changes\");\n\n const commitResult = await input.runner.run(\"git\", [\"commit\", \"-m\", input.message], {\n cwd: input.workspacePath\n });\n await assertCommandSucceeded(commitResult, \"commit run changes\");\n return true;\n}\n\nexport async function commitChangedFiles(input: {\n runner: CommandRunner;\n workspacePath: string;\n files: string[];\n message: string;\n}): Promise<void> {\n if (input.files.length === 0) return;\n const addResult = await input.runner.run(\"git\", [\"add\", \"--\", ...input.files], { cwd: input.workspacePath });\n await assertCommandSucceeded(addResult, \"stage changed files\");\n const commitResult = await input.runner.run(\"git\", [\"commit\", \"-m\", input.message], { cwd: input.workspacePath });\n await assertCommandSucceeded(commitResult, \"commit changed files\");\n}\n\nexport async function pushBranch(input: {\n runner: CommandRunner;\n workspacePath: string;\n remote: string;\n branchName: string;\n}): Promise<void> {\n const result = await input.runner.run(\"git\", [\"push\", \"-u\", input.remote, input.branchName], { cwd: input.workspacePath });\n await assertCommandSucceeded(result, \"push run branch\");\n}\n","import type { OpenTagRunResult } from \"@opentag/core\";\n\nexport function createExecutorRunResult(input: {\n executorName: string;\n runId: string;\n branchName: string;\n baseBranch?: string;\n output: string;\n changedFiles: string[];\n extraArtifacts?: NonNullable<OpenTagRunResult[\"artifacts\"]>;\n}): OpenTagRunResult {\n const proposalId = `proposal_${input.runId}`;\n const summary = input.output.slice(-4000);\n const suggestedChanges =\n input.changedFiles.length > 0\n ? [\n {\n proposalId,\n createdAt: new Date().toISOString(),\n sourceRunId: input.runId,\n summary: `${input.executorName} changed ${input.changedFiles.length} file(s) on branch ${input.branchName}.`,\n intents: [\n {\n intentId: `${proposalId}_create_pr`,\n domain: \"pull_request\" as const,\n action: \"create_pull_request\",\n summary: `Create a pull request for branch ${input.branchName}.`,\n params: {\n title: `OpenTag run ${input.runId}`,\n body: [\n \"## Summary\",\n \"\",\n summary\n ].join(\"\\n\"),\n head: input.branchName,\n base: input.baseBranch ?? \"main\",\n changedFiles: input.changedFiles,\n risks: [\"Creates a pull request from the executor-produced branch; review the diff before merging.\"],\n executorConditions: [\"isolated branch exists\"]\n }\n },\n {\n intentId: `${proposalId}_link_branch`,\n domain: \"artifact_links\" as const,\n action: \"link_artifact\",\n summary: `Link the run branch ${input.branchName} to the work item.`,\n params: { title: \"Run branch\", uri: input.branchName }\n },\n {\n intentId: `${proposalId}_request_review`,\n domain: \"review\" as const,\n action: \"request_review\",\n summary: \"Request human review of the generated code changes.\",\n params: { changedFiles: input.changedFiles }\n }\n ],\n preconditions: [\"The local branch was generated from the checkout state available to the runner.\"]\n }\n ]\n : undefined;\n\n return {\n conclusion: \"success\",\n summary,\n changedFiles: input.changedFiles,\n artifacts: [\n ...(input.changedFiles.length > 0 ? [{ kind: \"patch\" as const, title: \"Run branch\", uri: input.branchName }] : []),\n ...(input.extraArtifacts ?? [])\n ],\n ...(suggestedChanges ? { suggestedChanges } : {}),\n nextAction:\n input.changedFiles.length > 0\n ? {\n summary: \"Review the proposed pull request action and reply `apply 1` if the branch should become a PR.\",\n hint: {\n kind: \"create_pull_request\",\n targetId: proposalId,\n selectedIntentIds: [`${proposalId}_create_pr`]\n }\n }\n : \"No file changes were detected.\"\n };\n}\n","import { contextPointerLabel, type ContextPacket, type ContextPointer } from \"@opentag/core\";\nimport { assertCommandSucceeded, nodeCommandRunner, type CommandRunner } from \"./command.js\";\nimport { renderContextPacketForPrompt, type ExecutorAdapter } from \"./executor.js\";\nimport {\n branchNameForRun,\n changedFiles,\n cleanupInternalArtifacts,\n commitRunChanges,\n createRunWorktree,\n deleteRunBranch,\n removeRunWorktree,\n worktreePathForRun\n} from \"./git.js\";\nimport { createExecutorRunResult } from \"./result.js\";\nimport { assessRunnerSecurity, formatSecurityAssessment, scrubEnvironment, type RunnerSecurityPolicy } from \"./security.js\";\n\nexport type CodexExecutorOptions = {\n runner?: CommandRunner;\n codexCommand?: string;\n model?: string;\n security?: RunnerSecurityPolicy;\n};\n\nfunction contextLines(context: ContextPointer[]): string {\n if (!context.length) return \"No additional context pointers were provided.\";\n return context.map((pointer) => `- ${contextPointerLabel(pointer)}: ${pointer.uri}`).join(\"\\n\");\n}\n\nfunction buildPrompt(input: {\n runId: string;\n rawText: string;\n context: ContextPointer[];\n contextPacket: ContextPacket | undefined;\n}): string {\n return [\n \"You are executing an OpenTag run in a local checkout.\",\n `Run ID: ${input.runId}`,\n \"\",\n \"User request:\",\n input.rawText,\n \"\",\n ...renderContextPacketForPrompt(input.contextPacket),\n ...(input.contextPacket ? [\"\"] : []),\n \"Context pointers:\",\n contextLines(input.context),\n \"\",\n \"Work autonomously but keep the change narrow. Run relevant verification if you modify files. End with a concise summary.\"\n ].join(\"\\n\");\n}\n\nexport function createCodexExecutor(options: CodexExecutorOptions = {}): ExecutorAdapter {\n const runner = options.runner ?? nodeCommandRunner;\n const codexCommand = options.codexCommand ?? \"codex\";\n\n return {\n id: \"codex\",\n displayName: \"Codex Executor\",\n async canRun(input) {\n const codexVersion = await runner.run(codexCommand, [\"--version\"], { cwd: input.workspacePath });\n if (codexVersion.exitCode !== 0) {\n return { ready: false, reason: `Codex CLI is not available: ${codexVersion.stderr || codexVersion.stdout}` };\n }\n const gitRepo = await runner.run(\"git\", [\"rev-parse\", \"--show-toplevel\"], { cwd: input.workspacePath });\n if (gitRepo.exitCode !== 0) {\n return { ready: false, reason: `Workspace is not a git checkout: ${gitRepo.stderr || gitRepo.stdout}` };\n }\n const baseBranch = input.baseBranch ?? \"main\";\n const baseRef = await runner.run(\"git\", [\"rev-parse\", \"--verify\", `${baseBranch}^{commit}`], {\n cwd: input.workspacePath\n });\n if (baseRef.exitCode !== 0) {\n return { ready: false, reason: `Base branch '${baseBranch}' is not available: ${baseRef.stderr || baseRef.stdout}` };\n }\n return { ready: true };\n },\n async run(input, sink) {\n const security = options.security;\n const worktreePath = worktreePathForRun({\n workspacePath: input.workspacePath,\n runId: input.runId,\n ...(input.worktreeRoot ? { worktreeRoot: input.worktreeRoot } : {})\n });\n const assessment = assessRunnerSecurity({\n executorId: \"codex\",\n workspacePath: input.workspacePath,\n executionPath: worktreePath,\n command: input.command,\n context: input.context,\n ...(input.permissions ? { permissions: input.permissions } : {}),\n ...(security ? { policy: security } : {})\n });\n if (assessment.findings.length > 0) {\n await sink.emit({\n type: assessment.allowed ? \"executor.progress\" : \"executor.failed\",\n message: formatSecurityAssessment(assessment),\n at: new Date().toISOString()\n });\n }\n if (!assessment.allowed) {\n return {\n conclusion: \"needs_human\",\n summary: formatSecurityAssessment(assessment),\n nextAction: \"Review the request and rerun with a narrower prompt or an explicit local policy override if appropriate.\"\n };\n }\n\n const branchName = branchNameForRun(input.runId);\n const baseBranch = input.baseBranch ?? \"main\";\n const keepWorktree = input.keepWorktree ?? \"on_failure\";\n let completed = false;\n let changedFileCount: number | undefined;\n\n await sink.emit({\n type: \"executor.started\",\n message: `Creating isolated worktree ${worktreePath} on ${branchName}`,\n at: new Date().toISOString()\n });\n try {\n await createRunWorktree({\n runner,\n workspacePath: input.workspacePath,\n worktreePath,\n branchName,\n baseBranch\n });\n\n await sink.emit({\n type: \"executor.progress\",\n message: \"Starting codex exec\",\n at: new Date().toISOString()\n });\n\n const args = [\n \"exec\",\n \"--cd\",\n worktreePath,\n \"--full-auto\",\n \"--ephemeral\",\n ...(options.model ? [\"--model\", options.model] : []),\n \"-\"\n ];\n const codexResult = await runner.run(codexCommand, args, {\n cwd: worktreePath,\n env: scrubEnvironment(undefined, security),\n input: buildPrompt({\n runId: input.runId,\n rawText: input.command.rawText,\n context: input.context,\n contextPacket: input.contextPacket\n })\n });\n await assertCommandSucceeded(codexResult, \"codex exec\");\n\n const cleanedArtifacts = await cleanupInternalArtifacts({ runner, workspacePath: worktreePath });\n if (cleanedArtifacts.length > 0) {\n await sink.emit({\n type: \"executor.progress\",\n message: `Cleaned internal artifacts: ${cleanedArtifacts.join(\", \")}`,\n at: new Date().toISOString()\n });\n }\n\n const files = await changedFiles({ runner, workspacePath: worktreePath });\n changedFileCount = files.length;\n if (files.length > 0) {\n await sink.emit({\n type: \"executor.progress\",\n message: `Committing ${files.length} changed file(s) to ${branchName}`,\n at: new Date().toISOString()\n });\n await commitRunChanges({\n runner,\n workspacePath: worktreePath,\n message: `OpenTag run ${input.runId}`\n });\n }\n completed = true;\n\n await sink.emit({\n type: \"executor.completed\",\n message: `Codex executor completed with ${files.length} changed file(s)`,\n at: new Date().toISOString()\n });\n\n const output = codexResult.stdout.trim() || codexResult.stderr.trim() || \"Codex completed without textual output.\";\n return createExecutorRunResult({\n executorName: \"Codex\",\n runId: input.runId,\n branchName,\n ...(input.baseBranch ? { baseBranch: input.baseBranch } : {}),\n output,\n changedFiles: files,\n extraArtifacts: keepWorktree === \"always\" ? [{ title: \"Run worktree\", uri: worktreePath }] : []\n });\n } finally {\n const shouldRemove = keepWorktree === \"never\" || (keepWorktree === \"on_failure\" && completed);\n if (shouldRemove) {\n try {\n await removeRunWorktree({ runner, workspacePath: input.workspacePath, worktreePath });\n if (completed && changedFileCount === 0) {\n await deleteRunBranch({ runner, workspacePath: input.workspacePath, branchName });\n }\n } catch (error) {\n await sink.emit({\n type: \"executor.progress\",\n message: `Could not clean up run worktree or branch for ${worktreePath}: ${error instanceof Error ? error.message : String(error)}`,\n at: new Date().toISOString()\n });\n }\n }\n }\n },\n async cancel() {\n return;\n }\n };\n}\n","import { fileURLToPath } from \"node:url\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { ContextPointer, OpenTagCommand, PermissionGrant } from \"@opentag/core\";\nimport type { CommandEnvironment } from \"./command.js\";\n\nexport type RunnerSecurityMode = \"enforce\" | \"audit\" | \"off\";\n\nexport type RunnerSecurityPolicy = {\n mode?: RunnerSecurityMode;\n allowedWorkspaceRoot?: string;\n allowUnsafePrompts?: boolean;\n extraSafeEnv?: string[];\n};\n\nexport type RunnerSecurityFinding = {\n code: string;\n severity: \"block\" | \"warn\";\n message: string;\n};\n\nexport type RunnerSecurityAssessment = {\n allowed: boolean;\n mode: RunnerSecurityMode;\n findings: RunnerSecurityFinding[];\n};\n\nexport const DEFAULT_SAFE_ENV_NAMES = [\n \"CI\",\n \"COLORTERM\",\n \"CODEX_HOME\",\n \"FORCE_COLOR\",\n \"HOME\",\n \"LANG\",\n \"LOGNAME\",\n \"NO_COLOR\",\n \"PATH\",\n \"PWD\",\n \"SHELL\",\n \"SSL_CERT_DIR\",\n \"SSL_CERT_FILE\",\n \"TERM\",\n \"TMP\",\n \"TMPDIR\",\n \"TEMP\",\n \"USER\",\n \"XDG_CACHE_HOME\",\n \"XDG_CONFIG_HOME\",\n \"XDG_DATA_HOME\"\n];\n\nconst SAFE_ENV_PREFIXES = [\"LC_\"];\n\nconst SENSITIVE_ENV_PATTERNS = [\n /TOKEN/,\n /SECRET/,\n /PASSWORD/,\n /PASS$/,\n /API[_-]?KEY/,\n /CREDENTIAL/,\n /COOKIE/,\n /SESSION/,\n /AUTH/,\n /^AWS_/,\n /^AZURE_/,\n /^GCP_/,\n /^GOOGLE_/,\n /^OPENAI_/,\n /^ANTHROPIC_/,\n /^SLACK_/,\n /^GITHUB_TOKEN$/,\n /^GH_TOKEN$/,\n /^SSH_/\n];\n\nconst HIGH_RISK_TEXT_PATTERNS: Array<{ code: string; pattern: RegExp; message: string }> = [\n {\n code: \"prompt.instruction_override\",\n pattern: /\\b(ignore|disregard|forget)\\s+(all\\s+)?(previous|prior|system|developer|safety)\\s+instructions\\b/i,\n message: \"Request contains an instruction override pattern commonly used in prompt injection.\"\n },\n {\n code: \"prompt.secret_exfiltration\",\n pattern:\n /\\b(print|dump|show|reveal|exfiltrate|send|upload|post|copy)\\b[\\s\\S]{0,100}\\b(secret|token|password|api[\\s_-]?key|credential|environment variables?|env vars?)\\b/i,\n message: \"Request appears to ask the runner to expose secrets or environment variables.\"\n },\n {\n code: \"prompt.sensitive_file_access\",\n pattern: /\\b(cat|open|read|print|dump)\\b[\\s\\S]{0,80}(~\\/\\.ssh|~\\/\\.aws|\\.env\\b|id_rsa|known_hosts|credentials\\b)/i,\n message: \"Request appears to ask the runner to read sensitive local credential files.\"\n }\n];\n\nfunction securityMode(policy: RunnerSecurityPolicy | undefined): RunnerSecurityMode {\n return policy?.mode ?? \"enforce\";\n}\n\nfunction isPathInside(childPath: string, parentPath: string): boolean {\n const child = resolve(childPath);\n const parent = resolve(parentPath);\n const pathFromParent = relative(parent, child);\n return pathFromParent === \"\" || (!pathFromParent.startsWith(\"..\") && !isAbsolute(pathFromParent));\n}\n\nfunction fileContextPath(pointer: ContextPointer, workspacePath: string): string | null {\n if (pointer.kind !== \"file\") return null;\n if (pointer.uri.startsWith(\"file://\")) {\n return fileURLToPath(pointer.uri);\n }\n if (isAbsolute(pointer.uri)) {\n return pointer.uri;\n }\n return resolve(workspacePath, pointer.uri);\n}\n\nfunction hasPermission(permissions: PermissionGrant[] | undefined, scope: string): boolean {\n return permissions?.some((permission) => permission.scope === scope) ?? false;\n}\n\nfunction needsWritePermission(command: OpenTagCommand, executorId: string): boolean {\n if (executorId === \"echo\") return false;\n return command.intent === \"fix\" || command.intent === \"run\";\n}\n\nfunction scanTextForHighRiskPatterns(input: { command: OpenTagCommand; context: ContextPointer[] }): RunnerSecurityFinding[] {\n const sources = [\n { label: \"command\", text: input.command.rawText },\n ...input.context\n .filter((pointer) => pointer.kind === \"text\")\n .map((pointer) => ({ label: pointer.title ?? \"text context\", text: pointer.uri }))\n ];\n\n const findings: RunnerSecurityFinding[] = [];\n for (const source of sources) {\n for (const rule of HIGH_RISK_TEXT_PATTERNS) {\n if (rule.pattern.test(source.text)) {\n findings.push({\n code: rule.code,\n severity: \"block\",\n message: `${rule.message} Source: ${source.label}.`\n });\n }\n }\n }\n return findings;\n}\n\nexport function assessRunnerSecurity(input: {\n executorId: string;\n workspacePath: string;\n executionPath?: string;\n command: OpenTagCommand;\n context: ContextPointer[];\n permissions?: PermissionGrant[];\n policy?: RunnerSecurityPolicy;\n}): RunnerSecurityAssessment {\n const mode = securityMode(input.policy);\n if (mode === \"off\") {\n return { allowed: true, mode, findings: [] };\n }\n\n const findings: RunnerSecurityFinding[] = [];\n if (!isAbsolute(input.workspacePath)) {\n findings.push({\n code: \"workspace.relative_path\",\n severity: \"block\",\n message: \"Workspace path must be absolute before a local executor can run.\"\n });\n }\n\n const workspacePath = resolve(input.workspacePath);\n const executionPath = resolve(input.executionPath ?? input.workspacePath);\n if (input.policy?.allowedWorkspaceRoot && !isPathInside(workspacePath, input.policy.allowedWorkspaceRoot)) {\n findings.push({\n code: \"workspace.outside_allowed_root\",\n severity: \"block\",\n message: \"Workspace path is outside the configured allowed workspace root.\"\n });\n }\n if (input.policy?.allowedWorkspaceRoot && !isPathInside(executionPath, input.policy.allowedWorkspaceRoot)) {\n findings.push({\n code: \"execution.outside_allowed_root\",\n severity: \"block\",\n message: \"Execution path is outside the configured allowed workspace root.\"\n });\n }\n\n for (const pointer of input.context) {\n const filePath = fileContextPath(pointer, workspacePath);\n if (filePath && !isPathInside(filePath, workspacePath)) {\n findings.push({\n code: \"context.file_outside_workspace\",\n severity: \"block\",\n message: `File context is outside the mapped workspace: ${pointer.uri}`\n });\n }\n }\n\n if (needsWritePermission(input.command, input.executorId) && !hasPermission(input.permissions, \"repo:write\")) {\n findings.push({\n code: \"permission.repo_write_required\",\n severity: \"block\",\n message: \"Write-capable commands require an explicit repo:write permission grant.\"\n });\n }\n\n if (!input.policy?.allowUnsafePrompts) {\n findings.push(...scanTextForHighRiskPatterns({ command: input.command, context: input.context }));\n }\n\n const hasBlockingFinding = findings.some((finding) => finding.severity === \"block\");\n return {\n allowed: mode === \"audit\" || !hasBlockingFinding,\n mode,\n findings\n };\n}\n\nfunction isSensitiveEnvName(name: string): boolean {\n const upperName = name.toUpperCase();\n return SENSITIVE_ENV_PATTERNS.some((pattern) => pattern.test(upperName));\n}\n\nfunction isSafeEnvName(name: string, policy: RunnerSecurityPolicy | undefined): boolean {\n const upperName = name.toUpperCase();\n const safeNames = new Set([...DEFAULT_SAFE_ENV_NAMES, ...(policy?.extraSafeEnv ?? [])].map((envName) => envName.toUpperCase()));\n return safeNames.has(upperName) || SAFE_ENV_PREFIXES.some((prefix) => upperName.startsWith(prefix));\n}\n\nexport function scrubEnvironment(env: CommandEnvironment = process.env, policy?: RunnerSecurityPolicy): CommandEnvironment {\n if (securityMode(policy) === \"off\") return { ...env };\n\n const scrubbed: CommandEnvironment = {};\n for (const [name, value] of Object.entries(env)) {\n if (typeof value !== \"string\") continue;\n if (isSensitiveEnvName(name)) continue;\n if (!isSafeEnvName(name, policy)) continue;\n scrubbed[name] = value;\n }\n return scrubbed;\n}\n\nexport function formatSecurityAssessment(assessment: RunnerSecurityAssessment): string {\n if (assessment.findings.length === 0) {\n return `OpenTag runner security assessment passed in ${assessment.mode} mode.`;\n }\n\n const prefix = assessment.allowed\n ? `OpenTag runner security assessment reported ${assessment.findings.length} finding(s) in ${assessment.mode} mode.`\n : \"OpenTag runner security blocked this run.\";\n const details = assessment.findings.map((finding) => `${finding.code}: ${finding.message}`).join(\" \");\n return `${prefix} ${details}`;\n}\n","import type { ExecutorAdapter } from \"./executor.js\";\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nexport function createEchoExecutor(): ExecutorAdapter {\n return {\n id: \"echo\",\n displayName: \"Echo Executor\",\n async canRun() {\n return { ready: true };\n },\n async run(input, sink) {\n await sink.emit({\n type: \"executor.started\",\n message: `Echo executor started for ${input.runId}`,\n at: nowIso()\n });\n await sink.emit({\n type: \"executor.completed\",\n message: `Echo executor completed for ${input.runId}`,\n at: nowIso()\n });\n return {\n conclusion: \"success\",\n summary: `Echoed OpenTag command: ${input.command.rawText}`,\n verification: [\n {\n command: \"echo\",\n outcome: \"passed\",\n excerpt: input.command.rawText\n }\n ],\n nextAction: {\n summary: \"No external state change is suggested for the echo executor result.\",\n hint: { kind: \"none\" }\n }\n };\n },\n async cancel() {\n return;\n }\n };\n}\n"],"mappings":"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","names":["contextPointerLabel","resolve","contextPointerLabel","contextPointerLabel","contextLines","contextPointerLabel","buildPrompt"]}
|
package/dist/result.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OpenTagRunResult } from "@opentag/core";
|
|
2
|
+
export declare function createExecutorRunResult(input: {
|
|
3
|
+
executorName: string;
|
|
4
|
+
runId: string;
|
|
5
|
+
branchName: string;
|
|
6
|
+
baseBranch?: string;
|
|
7
|
+
output: string;
|
|
8
|
+
changedFiles: string[];
|
|
9
|
+
extraArtifacts?: NonNullable<OpenTagRunResult["artifacts"]>;
|
|
10
|
+
}): OpenTagRunResult;
|
|
11
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC;CAC7D,GAAG,gBAAgB,CAwEnB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ContextPointer, OpenTagCommand, PermissionGrant } from "@opentag/core";
|
|
2
|
+
import type { CommandEnvironment } from "./command.js";
|
|
3
|
+
export type RunnerSecurityMode = "enforce" | "audit" | "off";
|
|
4
|
+
export type RunnerSecurityPolicy = {
|
|
5
|
+
mode?: RunnerSecurityMode;
|
|
6
|
+
allowedWorkspaceRoot?: string;
|
|
7
|
+
allowUnsafePrompts?: boolean;
|
|
8
|
+
extraSafeEnv?: string[];
|
|
9
|
+
};
|
|
10
|
+
export type RunnerSecurityFinding = {
|
|
11
|
+
code: string;
|
|
12
|
+
severity: "block" | "warn";
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
export type RunnerSecurityAssessment = {
|
|
16
|
+
allowed: boolean;
|
|
17
|
+
mode: RunnerSecurityMode;
|
|
18
|
+
findings: RunnerSecurityFinding[];
|
|
19
|
+
};
|
|
20
|
+
export declare const DEFAULT_SAFE_ENV_NAMES: string[];
|
|
21
|
+
export declare function assessRunnerSecurity(input: {
|
|
22
|
+
executorId: string;
|
|
23
|
+
workspacePath: string;
|
|
24
|
+
executionPath?: string;
|
|
25
|
+
command: OpenTagCommand;
|
|
26
|
+
context: ContextPointer[];
|
|
27
|
+
permissions?: PermissionGrant[];
|
|
28
|
+
policy?: RunnerSecurityPolicy;
|
|
29
|
+
}): RunnerSecurityAssessment;
|
|
30
|
+
export declare function scrubEnvironment(env?: CommandEnvironment, policy?: RunnerSecurityPolicy): CommandEnvironment;
|
|
31
|
+
export declare function formatSecurityAssessment(assessment: RunnerSecurityAssessment): string;
|
|
32
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,GAAG,KAAK,CAAC;AAE7D,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,sBAAsB,UAsBlC,CAAC;AAmGF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B,GAAG,wBAAwB,CA6D3B;AAaD,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,kBAAgC,EAAE,MAAM,CAAC,EAAE,oBAAoB,GAAG,kBAAkB,CAWzH;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,wBAAwB,GAAG,MAAM,CAUrF"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentag/runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Executor contracts and built-in runner adapters for OpenTag.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20"
|
|
8
|
+
},
|
|
6
9
|
"main": "./dist/index.js",
|
|
7
10
|
"types": "./dist/index.d.ts",
|
|
8
11
|
"exports": {
|
|
@@ -26,9 +29,9 @@
|
|
|
26
29
|
"codex",
|
|
27
30
|
"agents"
|
|
28
31
|
],
|
|
29
|
-
"license": "
|
|
32
|
+
"license": "MIT",
|
|
30
33
|
"dependencies": {
|
|
31
|
-
"@opentag/core": "0.
|
|
34
|
+
"@opentag/core": "0.2.0"
|
|
32
35
|
},
|
|
33
36
|
"devDependencies": {
|
|
34
37
|
"tsup": "^8.3.5",
|