pullfrog 0.1.1 → 0.1.3

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.
@@ -0,0 +1,109 @@
1
+ import type { AgentUsage } from "./agents/shared.ts";
2
+ import type { PrepResult } from "./prep/types.ts";
3
+ import type { DiffCoverageState } from "./utils/diffCoverage.ts";
4
+ import { type ProgressComment, type ProgressCommentType } from "./utils/progressComment.ts";
5
+ import type { TodoTracker } from "./utils/todoTracking.ts";
6
+ export type BackgroundProcess = {
7
+ pid: number;
8
+ outputPath: string;
9
+ pidPath: string;
10
+ };
11
+ export type BrowserDaemon = {
12
+ binDir: string;
13
+ error?: never;
14
+ } | {
15
+ binDir?: never;
16
+ error: string;
17
+ };
18
+ export type StoredPushDest = {
19
+ remoteName: string;
20
+ remoteBranch: string;
21
+ localBranch: string;
22
+ };
23
+ /**
24
+ * Valid inline-comment anchor lines per side at a particular checkout SHA.
25
+ * Lives here (not in `mcp/review.ts`) so `ToolState` — which caches
26
+ * `Map<path, CommentableLines>` per checkout — does not pull the MCP server
27
+ * graph into every consumer of run state (the action's main loop, agent
28
+ * harnesses, cf-worker indexing).
29
+ */
30
+ export type CommentableLines = {
31
+ RIGHT: Set<number>;
32
+ LEFT: Set<number>;
33
+ };
34
+ /**
35
+ * mutable per-run record of facts that occurred during execution. shared
36
+ * between the action process and the MCP server (one process — toolState is
37
+ * just a JS object passed by reference into both surfaces).
38
+ *
39
+ * design rule: ToolState is LITERAL. each field records a thing that
40
+ * happened — `review` is set when `create_pull_request_review` succeeded,
41
+ * `finalSummaryWritten` flips when `report_progress` wrote a non-plan body,
42
+ * `selectedMode` is set when `select_mode` was called. fields should never
43
+ * encode the absence of an event ("unsubmittedReview", "missingArtifact"),
44
+ * speculative state, or values derived from other fields.
45
+ *
46
+ * any predicate the rest of the code needs ("the agent picked review mode but
47
+ * never produced a review or progress write") is computed inline at the call
48
+ * site, not stored. derived state in this struct invariably drifts from the
49
+ * literal fields under refactors and is the wrong layer for the check.
50
+ *
51
+ * write narrowly: prefer adding state inside the tool that mutates it (e.g.
52
+ * `create_pull_request_review` populates `toolState.review`) and reading
53
+ * narrowly elsewhere. don't introduce flags from main.ts that mirror what an
54
+ * MCP tool already records.
55
+ */
56
+ export interface ToolState {
57
+ pushUrl?: string;
58
+ pushDest?: StoredPushDest;
59
+ issueNumber?: number;
60
+ checkoutSha?: string;
61
+ commentableLinesByFile?: Map<string, CommentableLines>;
62
+ commentableLinesPullNumber?: number;
63
+ commentableLinesCheckoutSha?: string | undefined;
64
+ beforeSha?: string;
65
+ selectedMode?: string;
66
+ backgroundProcesses: Map<string, BackgroundProcess>;
67
+ browserDaemon?: BrowserDaemon | undefined;
68
+ review?: {
69
+ id: number;
70
+ nodeId: string;
71
+ reviewedSha: string | undefined;
72
+ };
73
+ reviewReplies?: Map<number, {
74
+ commentId: number;
75
+ url: string | undefined;
76
+ bodyWithFooter: string;
77
+ }>;
78
+ dependencyInstallation?: {
79
+ status: "not_started" | "in_progress" | "completed" | "failed";
80
+ promise: Promise<PrepResult[]> | undefined;
81
+ results: PrepResult[] | undefined;
82
+ };
83
+ progressComment: ProgressComment | null | undefined;
84
+ hadProgressComment: boolean;
85
+ lastProgressBody?: string;
86
+ wasUpdated?: boolean;
87
+ finalSummaryWritten?: boolean;
88
+ existingPlanCommentId?: number;
89
+ previousPlanBody?: string;
90
+ summaryFilePath?: string;
91
+ summarySeed?: string;
92
+ summaryPersistAttempted?: boolean;
93
+ learningsFilePath?: string;
94
+ learningsSeed?: string;
95
+ learningsPersistAttempted?: boolean;
96
+ output?: string;
97
+ usageEntries: AgentUsage[];
98
+ model?: string | undefined;
99
+ todoTracker?: TodoTracker | undefined;
100
+ diffCoverage?: DiffCoverageState | undefined;
101
+ }
102
+ interface InitToolStateParams {
103
+ progressComment: {
104
+ id: string;
105
+ type: ProgressCommentType;
106
+ } | undefined;
107
+ }
108
+ export declare function initToolState(params: InitToolStateParams): ToolState;
109
+ export {};
@@ -7,3 +7,11 @@
7
7
  * enforces https:// for non-local URLs to prevent cleartext credential transmission.
8
8
  */
9
9
  export declare function getApiUrl(): string;
10
+ /**
11
+ * true when the action is configured to talk to a localhost API server (i.e.
12
+ * `pnpm dev` running on the developer's box). signals we can use dev-only
13
+ * affordances like the `x-dev-repo` proxy-token bypass — the corresponding
14
+ * server-side dev gates (`NODE_ENV === "development"`) ensure these paths
15
+ * never activate against prod regardless of what the action does.
16
+ */
17
+ export declare function isLocalApiUrl(): boolean;
@@ -1,4 +1,4 @@
1
- import type { ToolState } from "../mcp/server.ts";
1
+ import type { ToolState } from "../toolState.ts";
2
2
  /**
3
3
  * ensure the agent-browser daemon is running by issuing a real command.
4
4
  *
@@ -1,4 +1,4 @@
1
- import type { ToolState } from "../mcp/server.ts";
1
+ import type { ToolState } from "../toolState.ts";
2
2
  interface ReportErrorParams {
3
3
  toolState: ToolState;
4
4
  error: string;
@@ -8,7 +8,10 @@ interface InstructionsContext {
8
8
  modes: Mode[];
9
9
  agentId: AgentId;
10
10
  outputSchema?: Record<string, unknown> | undefined;
11
- learnings: string | null;
11
+ /** absolute path to the seeded learnings tmpfile, or null when the file
12
+ * couldn't be seeded for some reason. main.ts always seeds, so in
13
+ * practice this is always set; the null case keeps the type honest. */
14
+ learningsFilePath: string | null;
12
15
  }
13
16
  export interface ResolvedInstructions {
14
17
  full: string;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Repo-level learnings — operational facts about a repo (setup steps, test
3
+ * commands, conventions, gotchas) that accumulate across agent runs and feed
4
+ * back into future runs as durable context. Modeled on the PR-summary tmpfile
5
+ * pattern (see action/utils/prSummary.ts):
6
+ *
7
+ * 1. server seeds `pullfrog-learnings.md` from `Repo.learnings` (or empty
8
+ * when the repo has none yet)
9
+ * 2. the agent reads the file at startup as part of its context, and may
10
+ * edit it in place at end-of-run when prompted by the reflection turn
11
+ * 3. main.ts reads the file back at end-of-run and PATCHes
12
+ * `/api/repo/[owner]/[repo]/learnings` if it changed (byte-trim equality
13
+ * against the seed determines change detection)
14
+ *
15
+ * Edit-in-place avoids stuffing the entire learnings list into both the
16
+ * prompt context and an `update_learnings` MCP tool call (which previously
17
+ * required passing the FULL merged list as a string parameter — an
18
+ * output-token tax that grew linearly with the learnings size).
19
+ */
20
+ export declare const LEARNINGS_FILE_NAME = "pullfrog-learnings.md";
21
+ export declare function learningsFilePath(tmpdir: string): string;
22
+ /** seed the learnings file with the repo's current learnings, or an empty
23
+ * file when the repo has none yet. returns the absolute path. */
24
+ export declare function seedLearningsFile(params: {
25
+ tmpdir: string;
26
+ current: string | null;
27
+ }): Promise<string>;
28
+ /** read the agent-edited learnings file. returns null when the file is
29
+ * missing or unreadable (treated as "no change"). caps content at the
30
+ * server's max length to avoid a 400 round-trip. */
31
+ export declare function readLearningsFile(path: string): Promise<string | null>;
@@ -1,6 +1,6 @@
1
1
  import type { AgentResult } from "../agents/shared.ts";
2
2
  import type { MainResult } from "../main.ts";
3
- import type { ToolState } from "../mcp/server.ts";
3
+ import type { ToolState } from "../toolState.ts";
4
4
  export interface HandleAgentResultParams {
5
5
  result: AgentResult;
6
6
  toolState: ToolState;
@@ -1,5 +1,5 @@
1
1
  import type { ShellPermission } from "../external.ts";
2
- import type { ToolState } from "../mcp/server.ts";
2
+ import type { ToolState } from "../toolState.ts";
3
3
  import type { OctokitWithPlugins } from "./github.ts";
4
4
  export interface SetupOptions {
5
5
  tempDir: string;
@@ -27,7 +27,6 @@ export interface SpawnOptions {
27
27
  onStdout?: (chunk: string) => void;
28
28
  onStderr?: (chunk: string) => void;
29
29
  killGroup?: boolean;
30
- isPausedExternally?: () => boolean;
31
30
  }
32
31
  export interface SpawnResult {
33
32
  stdout: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pullfrog": "dist/cli.mjs",
@@ -1,6 +0,0 @@
1
- import type { ToolContext } from "./server.ts";
2
- export declare function UpdateLearningsTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
3
- learnings: string;
4
- }, {
5
- learnings: string;
6
- }>>;