@phamvuhoang/otto-core 0.1.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/README.md +53 -0
- package/dist/branch.d.ts +61 -0
- package/dist/branch.d.ts.map +1 -0
- package/dist/branch.js +215 -0
- package/dist/branch.js.map +1 -0
- package/dist/cli-help.d.ts +68 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +365 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/detach.d.ts +36 -0
- package/dist/detach.d.ts.map +1 -0
- package/dist/detach.js +52 -0
- package/dist/detach.js.map +1 -0
- package/dist/gh-main.d.ts +5 -0
- package/dist/gh-main.d.ts.map +1 -0
- package/dist/gh-main.js +16 -0
- package/dist/gh-main.js.map +1 -0
- package/dist/git.d.ts +14 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +50 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/keepalive.d.ts +24 -0
- package/dist/keepalive.d.ts.map +1 -0
- package/dist/keepalive.js +138 -0
- package/dist/keepalive.js.map +1 -0
- package/dist/loop.d.ts +42 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +238 -0
- package/dist/loop.js.map +1 -0
- package/dist/main.d.ts +5 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +16 -0
- package/dist/main.js.map +1 -0
- package/dist/notify.d.ts +28 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +119 -0
- package/dist/notify.js.map +1 -0
- package/dist/pacing.d.ts +8 -0
- package/dist/pacing.d.ts.map +1 -0
- package/dist/pacing.js +33 -0
- package/dist/pacing.js.map +1 -0
- package/dist/panel.d.ts +24 -0
- package/dist/panel.d.ts.map +1 -0
- package/dist/panel.js +202 -0
- package/dist/panel.js.map +1 -0
- package/dist/rate-limit.d.ts +16 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +35 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/render.d.ts +8 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +130 -0
- package/dist/render.js.map +1 -0
- package/dist/retry.d.ts +17 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +34 -0
- package/dist/retry.js.map +1 -0
- package/dist/run-bin.d.ts +35 -0
- package/dist/run-bin.d.ts.map +1 -0
- package/dist/run-bin.js +241 -0
- package/dist/run-bin.js.map +1 -0
- package/dist/runner.d.ts +55 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +297 -0
- package/dist/runner.js.map +1 -0
- package/dist/stage-exec.d.ts +16 -0
- package/dist/stage-exec.d.ts.map +1 -0
- package/dist/stage-exec.js +35 -0
- package/dist/stage-exec.js.map +1 -0
- package/dist/stages.d.ts +38 -0
- package/dist/stages.d.ts.map +1 -0
- package/dist/stages.js +38 -0
- package/dist/stages.js.map +1 -0
- package/dist/state.d.ts +25 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +30 -0
- package/dist/state.js.map +1 -0
- package/dist/stream-render.d.ts +68 -0
- package/dist/stream-render.d.ts.map +1 -0
- package/dist/stream-render.js +162 -0
- package/dist/stream-render.js.map +1 -0
- package/dist/watch.d.ts +22 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +93 -0
- package/dist/watch.js.map +1 -0
- package/package.json +67 -0
- package/templates/afk.md +21 -0
- package/templates/apply-review.md +71 -0
- package/templates/ghafk-issue.md +29 -0
- package/templates/ghafk.md +29 -0
- package/templates/ghprompt-workflow.md +83 -0
- package/templates/ghprompt.md +39 -0
- package/templates/prompt.md +97 -0
- package/templates/review-lens.md +41 -0
- package/templates/review-synth.md +29 -0
- package/templates/review-verify.md +52 -0
- package/templates/review.md +62 -0
- package/templates/superpowers.md +70 -0
- package/templates/verify.md +74 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @phamvuhoang/otto-core
|
|
2
|
+
|
|
3
|
+
Library half of **[Otto](https://github.com/phamvuhoang/otto)** — a harness that drives the
|
|
4
|
+
[Claude Code](https://docs.anthropic.com/claude/docs/claude-code) CLI against a target
|
|
5
|
+
repository in an iterating implementer → reviewer loop, running directly on the host OS.
|
|
6
|
+
|
|
7
|
+
This package is the engine: the iteration loop driver, the runner + NDJSON stream
|
|
8
|
+
renderer, the prompt-template renderer, and the stage registry. The user-facing CLI lives in
|
|
9
|
+
**[`@phamvuhoang/otto`](https://www.npmjs.com/package/@phamvuhoang/otto)** (`otto-afk` / `otto-ghafk`).
|
|
10
|
+
|
|
11
|
+
> **Security:** Otto runs Claude with `--permission-mode bypassPermissions`. Point it
|
|
12
|
+
> only at repositories and prompts you trust. See the repo's
|
|
13
|
+
> [SECURITY.md](https://github.com/phamvuhoang/otto/blob/main/SECURITY.md).
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm i @phamvuhoang/otto-core
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Use
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
runAfk,
|
|
26
|
+
runGhAfk,
|
|
27
|
+
runLoop,
|
|
28
|
+
STAGES,
|
|
29
|
+
renderTemplate,
|
|
30
|
+
} from "@phamvuhoang/otto-core";
|
|
31
|
+
|
|
32
|
+
// Drive the plan/PRD loop from argv (same entry the otto-afk bin uses):
|
|
33
|
+
await runAfk(["<plan-and-prd>", "5"]);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Public surface: `runAfk`, `runGhAfk`, `runLoop`, `STAGES`, `Stage`, `renderTemplate`,
|
|
37
|
+
`runStage`. Subpath exports: `./loop`, `./runner`, `./stages`.
|
|
38
|
+
|
|
39
|
+
`runStage` spawns `claude` directly on the host with `cwd` set to the workspace directory.
|
|
40
|
+
By default (`OTTO_RUNNER=sandbox`) it writes a transient `--settings` JSON that enables
|
|
41
|
+
the native OS sandbox, confining writes to the workspace. Set `OTTO_RUNNER=host` to run
|
|
42
|
+
unsandboxed. Credentials (`~/.claude`, `~/.config/gh`) are read natively — no bind-mounts
|
|
43
|
+
required. The `templates/` directory (prompt playbooks) ships in the tarball.
|
|
44
|
+
|
|
45
|
+
## Docs
|
|
46
|
+
|
|
47
|
+
Full usage, setup, environment variables, and architecture are in the
|
|
48
|
+
**[main README](https://github.com/phamvuhoang/otto#readme)** and
|
|
49
|
+
**[docs/ARCHITECTURE.md](https://github.com/phamvuhoang/otto/blob/main/docs/ARCHITECTURE.md)**.
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
[MIT](https://github.com/phamvuhoang/otto/blob/main/LICENSE) © Henry Pham.
|
package/dist/branch.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export type BranchStrategy = "current" | "branch" | "worktree";
|
|
2
|
+
export type BranchConfig = {
|
|
3
|
+
branchStrategy?: BranchStrategy;
|
|
4
|
+
branchPrefix?: string;
|
|
5
|
+
};
|
|
6
|
+
export type ResolvedBranch = {
|
|
7
|
+
strategy: BranchStrategy;
|
|
8
|
+
branchName: string | null;
|
|
9
|
+
effectiveWorkspaceDir: string;
|
|
10
|
+
worktreePath?: string;
|
|
11
|
+
summaryLine: string;
|
|
12
|
+
};
|
|
13
|
+
export type BranchPromptResult = {
|
|
14
|
+
strategy: BranchStrategy;
|
|
15
|
+
remember: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type ResolveBranchOptions = {
|
|
18
|
+
workspaceDir: string;
|
|
19
|
+
inputs: string;
|
|
20
|
+
isTTY: boolean;
|
|
21
|
+
flagStrategy?: BranchStrategy;
|
|
22
|
+
flagPrefix?: string;
|
|
23
|
+
/** Injectable for tests; defaults to a readline prompt. Only called when isTTY && unresolved. */
|
|
24
|
+
prompt?: () => Promise<BranchPromptResult>;
|
|
25
|
+
/** Injectable clock for the timestamp slug (test seam). */
|
|
26
|
+
now?: () => string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Derive a branch slug from an inputs string. Uses the basename (sans extension)
|
|
30
|
+
* of the first whitespace-separated token, lowercased, with non-alphanumerics
|
|
31
|
+
* collapsed to single dashes and capped at 40 chars. "" when there is nothing usable.
|
|
32
|
+
*/
|
|
33
|
+
export declare function slugify(inputs: string): string;
|
|
34
|
+
/** Read .otto/config.json. Absent or malformed → {} (never throws). */
|
|
35
|
+
export declare function readBranchConfig(workspaceDir: string): BranchConfig;
|
|
36
|
+
/** Merge `patch` into .otto/config.json, preserving unknown keys. Creates .otto/ if needed. */
|
|
37
|
+
export declare function writeBranchConfig(workspaceDir: string, patch: BranchConfig): void;
|
|
38
|
+
/**
|
|
39
|
+
* Resolve the branch strategy once at startup and perform its one-time git side
|
|
40
|
+
* effect. Precedence: flagStrategy → .otto/config.json → TTY prompt → "current".
|
|
41
|
+
* Returns the effective workspace dir the loop should run in (the worktree path
|
|
42
|
+
* in worktree mode, else the original workspaceDir).
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveBranch(opts: ResolveBranchOptions): Promise<ResolvedBranch>;
|
|
45
|
+
/**
|
|
46
|
+
* Ensure `.otto-tmp/` is gitignored in the workspace. No-op outside a git repo
|
|
47
|
+
* or when a `.otto-tmp` entry already exists. Creates .gitignore if absent.
|
|
48
|
+
* Never ignores `.otto/` (LEARNINGS.md + config.json are durable, git-tracked
|
|
49
|
+
* memory).
|
|
50
|
+
*
|
|
51
|
+
* Idempotency is checked by scanning .gitignore text — NOT `git check-ignore`,
|
|
52
|
+
* which only matches a trailing-slash dir pattern once the dir exists on disk.
|
|
53
|
+
*/
|
|
54
|
+
export declare function ensureTmpIgnored(workspaceDir: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Returns a warning string if `strategy` keeps work in the current checkout AND
|
|
57
|
+
* the tree has uncommitted tracked changes (which disables the review panel's
|
|
58
|
+
* read-only reset enforcement). null when there is nothing to warn about.
|
|
59
|
+
*/
|
|
60
|
+
export declare function dirtyTreeWarning(workspaceDir: string, strategy: BranchStrategy): string | null;
|
|
61
|
+
//# sourceMappingURL=branch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../src/branch.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC3C,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,CAAC;AAKF;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU9C;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAmBnE;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,YAAY,GAClB,IAAI,CAgBN;AA0CD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,cAAc,CAAC,CAmFzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAgB3D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,cAAc,GACvB,MAAM,GAAG,IAAI,CAKf"}
|
package/dist/branch.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { appendFileSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { basename, join } from "node:path";
|
|
4
|
+
import { git, hasUncommittedTrackedChanges, isGitRepo, refExists, } from "./git.js";
|
|
5
|
+
const DEFAULT_PREFIX = "otto/";
|
|
6
|
+
const CONFIG_REL = join(".otto", "config.json");
|
|
7
|
+
/**
|
|
8
|
+
* Derive a branch slug from an inputs string. Uses the basename (sans extension)
|
|
9
|
+
* of the first whitespace-separated token, lowercased, with non-alphanumerics
|
|
10
|
+
* collapsed to single dashes and capped at 40 chars. "" when there is nothing usable.
|
|
11
|
+
*/
|
|
12
|
+
export function slugify(inputs) {
|
|
13
|
+
const first = inputs.trim().split(/\s+/)[0] ?? "";
|
|
14
|
+
if (!first)
|
|
15
|
+
return "";
|
|
16
|
+
const baseName = basename(first).replace(/\.[^.]+$/, "");
|
|
17
|
+
return baseName
|
|
18
|
+
.toLowerCase()
|
|
19
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
20
|
+
.replace(/^-+|-+$/g, "")
|
|
21
|
+
.slice(0, 40)
|
|
22
|
+
.replace(/-+$/g, "");
|
|
23
|
+
}
|
|
24
|
+
/** Read .otto/config.json. Absent or malformed → {} (never throws). */
|
|
25
|
+
export function readBranchConfig(workspaceDir) {
|
|
26
|
+
try {
|
|
27
|
+
const raw = JSON.parse(readFileSync(join(workspaceDir, CONFIG_REL), "utf8"));
|
|
28
|
+
const out = {};
|
|
29
|
+
if (raw.branchStrategy === "current" ||
|
|
30
|
+
raw.branchStrategy === "branch" ||
|
|
31
|
+
raw.branchStrategy === "worktree") {
|
|
32
|
+
out.branchStrategy = raw.branchStrategy;
|
|
33
|
+
}
|
|
34
|
+
if (typeof raw.branchPrefix === "string")
|
|
35
|
+
out.branchPrefix = raw.branchPrefix;
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Merge `patch` into .otto/config.json, preserving unknown keys. Creates .otto/ if needed. */
|
|
43
|
+
export function writeBranchConfig(workspaceDir, patch) {
|
|
44
|
+
const path = join(workspaceDir, CONFIG_REL);
|
|
45
|
+
let existing = {};
|
|
46
|
+
try {
|
|
47
|
+
existing = JSON.parse(readFileSync(path, "utf8"));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
existing = {};
|
|
51
|
+
}
|
|
52
|
+
mkdirSync(join(workspaceDir, ".otto"), { recursive: true });
|
|
53
|
+
writeFileSync(path, JSON.stringify({ ...existing, ...patch }, null, 2) + "\n");
|
|
54
|
+
}
|
|
55
|
+
/** Default readline prompt (only used in a TTY). */
|
|
56
|
+
async function defaultPrompt() {
|
|
57
|
+
const { createInterface } = await import("node:readline/promises");
|
|
58
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
59
|
+
try {
|
|
60
|
+
const ans = (await rl.question("Branch strategy [current/branch/worktree] (current): "))
|
|
61
|
+
.trim()
|
|
62
|
+
.toLowerCase();
|
|
63
|
+
const strategy = ans === "branch" || ans === "worktree" ? ans : "current";
|
|
64
|
+
let remember = false;
|
|
65
|
+
if (strategy !== "current") {
|
|
66
|
+
const r = (await rl.question("Remember for this repo? [y/N]: "))
|
|
67
|
+
.trim()
|
|
68
|
+
.toLowerCase();
|
|
69
|
+
remember = r === "y" || r === "yes";
|
|
70
|
+
}
|
|
71
|
+
return { strategy, remember };
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
rl.close();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function defaultNow() {
|
|
78
|
+
const d = new Date();
|
|
79
|
+
const p = (x) => String(x).padStart(2, "0");
|
|
80
|
+
return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}`;
|
|
81
|
+
}
|
|
82
|
+
/** Append -2, -3, … until the branch name is free. */
|
|
83
|
+
function uniqueBranchName(workspaceDir, name) {
|
|
84
|
+
if (!refExists(workspaceDir, name))
|
|
85
|
+
return name;
|
|
86
|
+
for (let n = 2;; n++) {
|
|
87
|
+
const candidate = `${name}-${n}`;
|
|
88
|
+
if (!refExists(workspaceDir, candidate))
|
|
89
|
+
return candidate;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Resolve the branch strategy once at startup and perform its one-time git side
|
|
94
|
+
* effect. Precedence: flagStrategy → .otto/config.json → TTY prompt → "current".
|
|
95
|
+
* Returns the effective workspace dir the loop should run in (the worktree path
|
|
96
|
+
* in worktree mode, else the original workspaceDir).
|
|
97
|
+
*/
|
|
98
|
+
export async function resolveBranch(opts) {
|
|
99
|
+
const { workspaceDir, inputs, isTTY } = opts;
|
|
100
|
+
const now = opts.now ?? defaultNow;
|
|
101
|
+
const config = readBranchConfig(workspaceDir);
|
|
102
|
+
const prefix = opts.flagPrefix ?? config.branchPrefix ?? DEFAULT_PREFIX;
|
|
103
|
+
let strategy;
|
|
104
|
+
if (opts.flagStrategy) {
|
|
105
|
+
strategy = opts.flagStrategy;
|
|
106
|
+
}
|
|
107
|
+
else if (config.branchStrategy) {
|
|
108
|
+
strategy = config.branchStrategy;
|
|
109
|
+
}
|
|
110
|
+
else if (isTTY) {
|
|
111
|
+
const res = await (opts.prompt ?? defaultPrompt)();
|
|
112
|
+
strategy = res.strategy;
|
|
113
|
+
if (res.remember && strategy !== "current") {
|
|
114
|
+
writeBranchConfig(workspaceDir, {
|
|
115
|
+
branchStrategy: strategy,
|
|
116
|
+
branchPrefix: prefix,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
strategy = "current";
|
|
122
|
+
}
|
|
123
|
+
if (strategy === "current") {
|
|
124
|
+
return {
|
|
125
|
+
strategy,
|
|
126
|
+
branchName: null,
|
|
127
|
+
effectiveWorkspaceDir: workspaceDir,
|
|
128
|
+
summaryLine: "branch strategy: current (committing on the current branch)",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (!isGitRepo(workspaceDir)) {
|
|
132
|
+
throw new Error(`branch strategy "${strategy}" requires a git repo, but ${workspaceDir} is not a git work tree`);
|
|
133
|
+
}
|
|
134
|
+
const slug = slugify(inputs) || now();
|
|
135
|
+
const branchName = uniqueBranchName(workspaceDir, prefix + slug);
|
|
136
|
+
if (strategy === "branch") {
|
|
137
|
+
const current = git(["branch", "--show-current"], workspaceDir);
|
|
138
|
+
if (current === branchName) {
|
|
139
|
+
return {
|
|
140
|
+
strategy,
|
|
141
|
+
branchName,
|
|
142
|
+
effectiveWorkspaceDir: workspaceDir,
|
|
143
|
+
summaryLine: `branch strategy: branch (already on ${branchName})`,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
execFileSync("git", ["switch", "-c", branchName], {
|
|
147
|
+
cwd: workspaceDir,
|
|
148
|
+
stdio: "ignore",
|
|
149
|
+
});
|
|
150
|
+
return {
|
|
151
|
+
strategy,
|
|
152
|
+
branchName,
|
|
153
|
+
effectiveWorkspaceDir: workspaceDir,
|
|
154
|
+
summaryLine: `branch strategy: branch (created + switched to ${branchName})`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// worktree
|
|
158
|
+
const worktreePath = join(workspaceDir, ".otto-tmp", "worktrees", slug);
|
|
159
|
+
mkdirSync(join(workspaceDir, ".otto-tmp", "worktrees"), { recursive: true });
|
|
160
|
+
execFileSync("git", ["worktree", "add", "-b", branchName, worktreePath, "HEAD"], { cwd: workspaceDir, stdio: "ignore" });
|
|
161
|
+
const dirtyNote = hasUncommittedTrackedChanges(workspaceDir)
|
|
162
|
+
? " (uncommitted changes left in the main checkout)"
|
|
163
|
+
: "";
|
|
164
|
+
return {
|
|
165
|
+
strategy,
|
|
166
|
+
branchName,
|
|
167
|
+
effectiveWorkspaceDir: worktreePath,
|
|
168
|
+
worktreePath,
|
|
169
|
+
summaryLine: `branch strategy: worktree (${branchName} at ${worktreePath})${dirtyNote}`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Ensure `.otto-tmp/` is gitignored in the workspace. No-op outside a git repo
|
|
174
|
+
* or when a `.otto-tmp` entry already exists. Creates .gitignore if absent.
|
|
175
|
+
* Never ignores `.otto/` (LEARNINGS.md + config.json are durable, git-tracked
|
|
176
|
+
* memory).
|
|
177
|
+
*
|
|
178
|
+
* Idempotency is checked by scanning .gitignore text — NOT `git check-ignore`,
|
|
179
|
+
* which only matches a trailing-slash dir pattern once the dir exists on disk.
|
|
180
|
+
*/
|
|
181
|
+
export function ensureTmpIgnored(workspaceDir) {
|
|
182
|
+
if (!isGitRepo(workspaceDir))
|
|
183
|
+
return;
|
|
184
|
+
const path = join(workspaceDir, ".gitignore");
|
|
185
|
+
let text = "";
|
|
186
|
+
try {
|
|
187
|
+
text = readFileSync(path, "utf8");
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
text = "";
|
|
191
|
+
}
|
|
192
|
+
const already = text
|
|
193
|
+
.split("\n")
|
|
194
|
+
.map((l) => l.trim())
|
|
195
|
+
.some((l) => l === ".otto-tmp" || l === ".otto-tmp/");
|
|
196
|
+
if (already)
|
|
197
|
+
return;
|
|
198
|
+
const needsNl = text.length > 0 && !text.endsWith("\n");
|
|
199
|
+
appendFileSync(path, `${needsNl ? "\n" : ""}.otto-tmp/\n`);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Returns a warning string if `strategy` keeps work in the current checkout AND
|
|
203
|
+
* the tree has uncommitted tracked changes (which disables the review panel's
|
|
204
|
+
* read-only reset enforcement). null when there is nothing to warn about.
|
|
205
|
+
*/
|
|
206
|
+
export function dirtyTreeWarning(workspaceDir, strategy) {
|
|
207
|
+
if (strategy === "worktree")
|
|
208
|
+
return null; // worktree starts clean by construction
|
|
209
|
+
if (!isGitRepo(workspaceDir))
|
|
210
|
+
return null;
|
|
211
|
+
if (!hasUncommittedTrackedChanges(workspaceDir))
|
|
212
|
+
return null;
|
|
213
|
+
return "working tree has uncommitted changes — review-panel read-only enforcement will be disabled; consider committing/stashing or using --branch worktree";
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=branch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch.js","sourceRoot":"","sources":["../src/branch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export type CliFlags = {
|
|
2
|
+
help: boolean;
|
|
3
|
+
version: boolean;
|
|
4
|
+
printConfig: boolean;
|
|
5
|
+
noKeepAlive: boolean;
|
|
6
|
+
maxRetries?: number;
|
|
7
|
+
detach: boolean;
|
|
8
|
+
log?: string;
|
|
9
|
+
notify: boolean;
|
|
10
|
+
budget?: number;
|
|
11
|
+
cooldownMs?: number;
|
|
12
|
+
reviewPanel: boolean;
|
|
13
|
+
watch: boolean;
|
|
14
|
+
watchIntervalSec?: number;
|
|
15
|
+
issue?: number;
|
|
16
|
+
maxWaitMs?: number;
|
|
17
|
+
fresh: boolean;
|
|
18
|
+
verify: boolean;
|
|
19
|
+
applyReview?: string;
|
|
20
|
+
branch?: "current" | "branch" | "worktree";
|
|
21
|
+
branchPrefix?: string;
|
|
22
|
+
rest: string[];
|
|
23
|
+
};
|
|
24
|
+
/** Parse a duration: bare integer = seconds; suffix s/m/h supported. Throws on invalid. */
|
|
25
|
+
export declare function parseDurationMs(raw: string): number;
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a user-supplied issue reference to a positive integer.
|
|
28
|
+
* Accepts: `42`, `#42`, `owner/repo#42`, and GitHub issue URLs
|
|
29
|
+
* (`https://github.com/owner/repo/issues/42[#anchor]`). A repo component is
|
|
30
|
+
* ignored — only the number is used (gh resolves the repo from the workspace).
|
|
31
|
+
* Throws on anything that is not a positive integer.
|
|
32
|
+
*
|
|
33
|
+
* SECURITY: the returned integer is the ONLY part of the ref that may reach a
|
|
34
|
+
* shell (via the OTTO_ISSUE env var read by a static template command). Never
|
|
35
|
+
* pass the raw ref to a shell. See render.ts security invariant.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseIssueRef(raw: string): number;
|
|
38
|
+
export declare function parseFlags(argv: string[]): CliFlags;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the @phamvuhoang/otto-core version by reading the package.json that
|
|
41
|
+
* sits two levels up from the compiled cli-help.js (packages/core/dist/ →
|
|
42
|
+
* packages/core/package.json). Returns "?" if unreadable so version reporting
|
|
43
|
+
* never crashes the bin.
|
|
44
|
+
*/
|
|
45
|
+
export declare function readCoreVersion(): string;
|
|
46
|
+
export declare function printVersion(bin: string, cliVersion?: string): void;
|
|
47
|
+
export declare function printHelp(bin: string, usage: string, description: string): void;
|
|
48
|
+
export type PrintConfigOptions = {
|
|
49
|
+
cliVersion?: string;
|
|
50
|
+
noKeepAlive?: boolean;
|
|
51
|
+
maxRetries?: number;
|
|
52
|
+
detach?: boolean;
|
|
53
|
+
detachLogPath?: string;
|
|
54
|
+
notify?: boolean;
|
|
55
|
+
budget?: number;
|
|
56
|
+
cooldownMs?: number;
|
|
57
|
+
/** Resolved review lenses (empty array = single reviewer). */
|
|
58
|
+
reviewLenses?: string[];
|
|
59
|
+
watch?: boolean;
|
|
60
|
+
watchIntervalSec?: number;
|
|
61
|
+
issue?: number;
|
|
62
|
+
maxWaitMs?: number;
|
|
63
|
+
mode?: string;
|
|
64
|
+
branchStrategy?: "current" | "branch" | "worktree";
|
|
65
|
+
branchPrefix?: string;
|
|
66
|
+
};
|
|
67
|
+
export declare function printConfig(bin: string, workspaceDir: string, packageDir: string, opts?: PrintConfigOptions): void;
|
|
68
|
+
//# sourceMappingURL=cli-help.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-help.d.ts","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAEF,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAmBjD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,CA2LnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAWxC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAInE;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,IAAI,CA+CN;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,kBAAuB,GAC5B,IAAI,CA0EN"}
|