pullfrog 0.0.201 → 0.0.203

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Logging utilities that work well in both local and GitHub Actions environments
3
3
  */
4
- import type { AgentUsage } from "../agents/shared.ts";
4
+ import { type AgentUsage } from "../agents/shared.ts";
5
5
  /** run `fn` with every log line prefixed by `prefix` (e.g. "[task-label]") in magenta */
6
6
  export declare function withLogPrefix<T>(prefix: string, fn: () => Promise<T>): Promise<T>;
7
7
  /**
@@ -86,7 +86,18 @@ export declare function formatJsonValue(value: unknown): string;
86
86
  */
87
87
  export declare function formatIndentedField(label: string, content: string): string;
88
88
  /**
89
- * format aggregated usage data as a markdown table for the GitHub step summary
89
+ * format aggregated usage data as a markdown table for the GitHub step summary.
90
+ *
91
+ * columns mirror the per-run stdout token table emitted by `logTokenTable`
92
+ * (Input / Cache Read / Cache Write / Output / Total / Cost ($)) so the job
93
+ * summary and the in-run logs can be compared row-for-row.
94
+ *
95
+ * notes:
96
+ * - `AgentUsage.inputTokens` is the sum of non-cached input + cache read
97
+ * + cache write (set that way by both agent harnesses' `buildUsage`),
98
+ * so the non-cached Input column is recovered by subtracting cache fields.
99
+ * - `costUsd` is sourced from models.dev (OpenCode) or `total_cost_usd`
100
+ * (Claude CLI). absent rows show `—` so per-agent coverage is obvious.
90
101
  */
91
102
  export declare function formatUsageSummary(entries: AgentUsage[]): string;
92
103
  export {};
@@ -1,6 +1,29 @@
1
+ import type { AgentUsage } from "../agents/shared.ts";
1
2
  import type { ToolContext } from "../mcp/server.ts";
2
- /** Keys accepted by PATCH /api/workflow-run/[runId] — keep in sync with `ALLOWED_FIELDS` in `app/api/workflow-run/[runId]/route.ts`. */
3
+ /**
4
+ * Artifact tracking fields — one-off PATCHes from MCP tools as GitHub entities
5
+ * are created during the run. Strings only (GraphQL node IDs).
6
+ * Keep in sync with `STRING_FIELDS` in `app/api/workflow-run/[runId]/route.ts`.
7
+ */
3
8
  export type WorkflowRunArtifactPatchKey = "prNodeId" | "issueNodeId" | "reviewNodeId" | "planCommentNodeId" | "summaryCommentNodeId";
4
- export type WorkflowRunArtifactPatch = Partial<Record<WorkflowRunArtifactPatchKey, string>>;
5
- /** PATCH workflow-run artifact fields (Pullfrog JWT, not GitHub). */
6
- export declare function patchWorkflowRunFields(ctx: ToolContext, fields: WorkflowRunArtifactPatch): Promise<void>;
9
+ /**
10
+ * Usage fields aggregated across all agent calls and PATCHed once at
11
+ * end-of-run. Token counts are Int4 on the DB side (ample for any realistic
12
+ * run); `costUsd` is a Decimal populated by provider-reported dollar amounts.
13
+ * Keep in sync with `INT_FIELDS` + `DECIMAL_FIELDS` in the server route.
14
+ */
15
+ export type WorkflowRunUsagePatchKey = "inputTokens" | "outputTokens" | "cacheReadTokens" | "cacheWriteTokens" | "costUsd";
16
+ export type WorkflowRunPatch = Partial<Record<WorkflowRunArtifactPatchKey, string>> & Partial<Record<WorkflowRunUsagePatchKey, number>>;
17
+ /** PATCH workflow-run fields (Pullfrog JWT, not GitHub). */
18
+ export declare function patchWorkflowRunFields(ctx: ToolContext, fields: WorkflowRunPatch): Promise<void>;
19
+ /**
20
+ * Sum per-agent usage entries into a single WorkflowRunPatch payload.
21
+ * Returns an empty object when there's nothing to report, which causes
22
+ * `patchWorkflowRunFields` to no-op — safe to call unconditionally from
23
+ * end-of-run paths. Zero-valued fields are dropped so the DB only stores
24
+ * positive sums (and NULL means "not reported").
25
+ *
26
+ * Token sums are clamped to INT4_MAX to guarantee the payload the server
27
+ * sees is always self-consistent across all numeric columns.
28
+ */
29
+ export declare function aggregateUsage(entries: AgentUsage[]): WorkflowRunPatch;
@@ -12,11 +12,13 @@ export interface RepoSettings {
12
12
  setupScript: string | null;
13
13
  postCheckoutScript: string | null;
14
14
  prepushScript: string | null;
15
+ stopScript: string | null;
15
16
  push: PushPermission;
16
17
  shell: ShellPermission;
17
18
  prApproveEnabled: boolean;
18
19
  modeInstructions: Record<string, string>;
19
20
  learnings: string | null;
21
+ envAllowlist: string | null;
20
22
  }
21
23
  export interface RunContext {
22
24
  settings: RepoSettings;
@@ -1,14 +1,21 @@
1
1
  /**
2
2
  * Secret detection and env filtering utilities
3
+ *
4
+ * subprocess env filtering: default-deny allowlist model.
5
+ * only vars in the safe set or user allowlist are passed to child processes.
6
+ *
7
+ * log redaction: SENSITIVE_PATTERNS are used to identify secret values
8
+ * for redaction in logs and GHA masking (independent of subprocess filtering).
3
9
  */
4
10
  export declare const SENSITIVE_PATTERNS: RegExp[];
5
11
  export declare function isSensitiveEnvName(key: string): boolean;
6
- /** filter env vars, removing sensitive values (tokens, keys, secrets) */
12
+ export declare function setEnvAllowlist(raw: string): void;
13
+ /** filter env vars using default-deny allowlist: safe set + user allowlist */
7
14
  export declare function filterEnv(): Record<string, string>;
8
15
  export type EnvMode = "restricted" | "inherit" | Record<string, string>;
9
16
  /**
10
17
  * resolve env mode to actual env object
11
- * - "restricted" (default): filterEnv() to prevent secret leakage
18
+ * - "restricted" (default): filterEnv() only safe set + user allowlist
12
19
  * - "inherit": full process.env
13
20
  * - object: custom env merged with restricted base
14
21
  */
@@ -12,6 +12,19 @@ export declare function createTempDirectory(): string;
12
12
  * Setup the test repository for running actions
13
13
  */
14
14
  export declare function setupTestRepo(options: SetupOptions): void;
15
+ /**
16
+ * remove any `[includeIf ...]` entries from the local git config so that
17
+ * actions/checkout-persisted credentials don't ride alongside ASKPASS-provided
18
+ * auth for subsequent git operations.
19
+ *
20
+ * SECURITY: git config subsection values can contain arbitrary characters
21
+ * including `$(...)` command substitutions, and `${IFS}` spacing tricks defeat
22
+ * naive split-on-space filtering. we read keys via the `-z` (null-terminated)
23
+ * output format and feed them to a spawn-array `git config --unset-all` so
24
+ * the shell never interpolates key contents — closing the RCE path that a
25
+ * string-interpolated `execSync(...)` would expose.
26
+ */
27
+ export declare function removeIncludeIfEntries(repoDir: string): void;
15
28
  export interface GitContext {
16
29
  gitToken: string;
17
30
  owner: string;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * write all bundled skills into the fake HOME so OpenCode / Claude Code discover
3
+ * them via their auto-scan directories.
4
+ *
5
+ * called once per agent run from each agent's `run()`. cheap (small file
6
+ * writes), no network, idempotent.
7
+ */
8
+ export declare function installBundledSkills(params: {
9
+ home: string;
10
+ }): void;
1
11
  /**
2
12
  * install a skill globally via the `skills` CLI.
3
13
  *
@@ -3,6 +3,12 @@ export type TrackChildOptions = {
3
3
  child: ChildProcess;
4
4
  killGroup?: boolean;
5
5
  };
6
+ export declare const SPAWN_TIMEOUT_CODE = "E_SPAWN_TIMEOUT";
7
+ export declare const SPAWN_ACTIVITY_TIMEOUT_CODE = "E_SPAWN_ACTIVITY_TIMEOUT";
8
+ export declare class SpawnTimeoutError extends Error {
9
+ readonly code: typeof SPAWN_TIMEOUT_CODE | typeof SPAWN_ACTIVITY_TIMEOUT_CODE;
10
+ constructor(message: string, code: typeof SPAWN_TIMEOUT_CODE | typeof SPAWN_ACTIVITY_TIMEOUT_CODE);
11
+ }
6
12
  export type SignalHandler = (signal: NodeJS.Signals) => void;
7
13
  export declare function trackChild(options: TrackChildOptions): void;
8
14
  export declare function untrackChild(child: ChildProcess): void;
@@ -15,6 +21,7 @@ export interface SpawnOptions {
15
21
  input?: string;
16
22
  timeout?: number;
17
23
  activityTimeout?: number;
24
+ onActivityTimeout?: (() => void) | undefined;
18
25
  cwd?: string;
19
26
  stdio?: ("pipe" | "ignore" | "inherit")[];
20
27
  onStdout?: (chunk: string) => void;
@@ -12,3 +12,4 @@ export declare function parseTimeString(input: string): number | null;
12
12
  * check if a string is a valid time format.
13
13
  */
14
14
  export declare function isValidTimeString(input: string): boolean;
15
+ export declare function resolveTimeoutMs(input: string | undefined): number | null;
@@ -6,7 +6,9 @@ export type TodoTracker = {
6
6
  settled: () => Promise<void>;
7
7
  /** mark in-progress items as completed (for final snapshot before review/progress post) */
8
8
  completeInProgress: () => void;
9
- renderCollapsible: () => string;
9
+ renderCollapsible: (options?: {
10
+ completeInProgress?: boolean;
11
+ }) => string;
10
12
  readonly enabled: boolean;
11
13
  /** true after the tracker has successfully called onUpdate at least once */
12
14
  readonly hasPublished: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.0.201",
3
+ "version": "0.0.203",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pullfrog": "dist/cli.mjs",
@@ -12,6 +12,7 @@
12
12
  ],
13
13
  "scripts": {
14
14
  "test": "vitest",
15
+ "test:catalog": "vitest run --config vitest.main.config.ts",
15
16
  "typecheck": "tsc --noEmit",
16
17
  "build": "node esbuild.config.js && tsc -p tsconfig.exports.json",
17
18
  "check:entrypoints": "node scripts/check-entrypoint-imports.ts",
@@ -24,7 +25,7 @@
24
25
  },
25
26
  "devDependencies": {
26
27
  "@actions/core": "^1.11.1",
27
- "@anthropic-ai/claude-code": "2.1.85",
28
+ "@anthropic-ai/claude-code": "2.1.112",
28
29
  "@ark/fs": "0.56.0",
29
30
  "@ark/util": "0.56.0",
30
31
  "@clack/prompts": "^1.2.0",