Fix repo slug

This commit is contained in:
Colin McDonnell
2026-01-14 01:44:30 +00:00
committed by pullfrog[bot]
parent 5604cf1868
commit 3fa309853b
16 changed files with 278033 additions and 58 deletions
+4 -4
View File
@@ -80,18 +80,18 @@ jobs:
tag_name: ${{ steps.version.outputs.tag }}
release_name: "${{ steps.version.outputs.tag }}"
body: |
## 📦 @pullfrog/action ${{ steps.version.outputs.version }}
## 📦 @pullfrog/pullfrog ${{ steps.version.outputs.version }}
### Usage in GitHub Actions
```yaml
- uses: pullfrog/action@${{ steps.version.outputs.major_tag }}
- uses: pullfrog/pullfrog@${{ steps.version.outputs.major_tag }}
```
### Installation via npm
```bash
npm install @pullfrog/action@${{ steps.version.outputs.version }}
npm install @pullfrog/pullfrog@${{ steps.version.outputs.version }}
```
draft: false
prerelease: false
@@ -118,5 +118,5 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Published to" >> $GITHUB_STEP_SUMMARY
echo "- GitHub Release: [View Release](https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.tag }})" >> $GITHUB_STEP_SUMMARY
echo "- npm Registry: [@pullfrog/action@${{ steps.version.outputs.version }}](https://www.npmjs.com/package/@pullfrog/action/v/${{ steps.version.outputs.version }})" >> $GITHUB_STEP_SUMMARY
echo "- npm Registry: [@pullfrog/pullfrog@${{ steps.version.outputs.version }}](https://www.npmjs.com/package/@pullfrog/pullfrog/v/${{ steps.version.outputs.version }})" >> $GITHUB_STEP_SUMMARY
fi
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v4
- name: Run agent
uses: pullfrog/action@main
uses: pullfrog/pullfrog@main
with:
prompt: ${{ inputs.prompt }}
env:
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
- name: Dispatch "action-repo-updated" event
run: |
gh api repos/pullfrog/pullfrog/dispatches \
gh api repos/pullfrog/app/dispatches \
-f event_type="action-repo-updated" \
-f client_payload='{
"before": "${{ github.event.before }}",
+2 -2
View File
@@ -52,7 +52,7 @@ Install the Pullfrog GitHub App on your personal or organization account. During
<details>
<summary><strong>Manual setup instructions</strong></summary>
You can also use the `pullfrog/action` Action without a GitHub App installation. This is more time-consuming to set up, and it places limitations on the actions your Agent will be capable of performing.
You can also use the `pullfrog/pullfrog` Action without a GitHub App installation. This is more time-consuming to set up, and it places limitations on the actions your Agent will be capable of performing.
To manually set up the Pullfrog action, you need to set up two workflow files in your repository: `pullfrog.yml` (the execution logic) and `triggers.yml` (the event triggers).
@@ -94,7 +94,7 @@ jobs:
# - uses: actions/setup-node@v6
- name: Run agent
uses: pullfrog/action@v0
uses: pullfrog/pullfrog@v0
with:
prompt: ${{ inputs.prompt }}
env:
+19
View File
@@ -0,0 +1,19 @@
name: "Pullfrog Action (Dispatch)"
description: "Execute coding agents with JSON payload input"
author: "Pullfrog"
inputs:
payload:
description: "JSON payload containing prompt, event, and other configuration"
required: true
cwd:
description: "Working directory for the agent (defaults to GITHUB_WORKSPACE)"
required: false
runs:
using: "node24"
main: "entry"
branding:
icon: "code"
color: "green"
Executable
+138885
View File
File diff suppressed because one or more lines are too long
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env node
/**
* entry point for pullfrog/pullfrog/dispatch - JSON payload input for internal use
*/
import * as core from "@actions/core";
import { Inputs, main } from "../main.ts";
async function run(): Promise<void> {
try {
const payloadStr = core.getInput("payload", { required: true });
// parse JSON payload
let payload: unknown;
try {
payload = JSON.parse(payloadStr);
} catch {
throw new Error(`failed to parse payload as JSON: ${payloadStr.slice(0, 100)}...`);
}
// validate and convert to Inputs
if (typeof payload !== "object" || payload === null) {
throw new Error("payload must be a JSON object");
}
const payloadObj = payload as Record<string, unknown>;
// build inputs from payload fields
const inputs = Inputs.assert({
prompt: payloadObj.prompt,
effort: payloadObj.effort,
agent: payloadObj.agent,
event: payloadObj.event,
modes: payloadObj.modes,
sandbox: payloadObj.sandbox,
disableProgressComment: payloadObj.disableProgressComment,
comment_id: payloadObj.comment_id,
issue_id: payloadObj.issue_id,
pr_id: payloadObj.pr_id,
cwd: core.getInput("cwd") || undefined,
});
const result = await main(inputs);
if (!result.success) {
throw new Error(result.error || "Agent execution failed");
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
core.setFailed(`Action failed: ${errorMessage}`);
}
}
await run();
+51 -21
View File
@@ -74360,12 +74360,11 @@ var init_index_CLFto6T2 = __esm({
// entry.ts
var core4 = __toESM(require_core(), 1);
import { resolve, isAbsolute } from "path";
// main.ts
import { mkdtemp as mkdtemp2 } from "node:fs/promises";
import { tmpdir as tmpdir2 } from "node:os";
import { join as join13 } from "node:path";
import { isAbsolute, join as join13, resolve } from "node:path";
// node_modules/.pnpm/@ark+util@0.53.0/node_modules/@ark/util/out/arrays.js
var append = (to, value2, opts) => {
@@ -99967,7 +99966,7 @@ function query({
// package.json
var package_default = {
name: "@pullfrog/action",
name: "@pullfrog/pullfrog",
version: "0.0.157",
type: "module",
files: [
@@ -100020,15 +100019,15 @@ var package_default = {
},
repository: {
type: "git",
url: "git+https://github.com/pullfrog/action.git"
url: "git+https://github.com/pullfrog/pullfrog.git"
},
keywords: [],
author: "",
license: "MIT",
bugs: {
url: "https://github.com/pullfrog/action/issues"
url: "https://github.com/pullfrog/pullfrog/issues"
},
homepage: "https://github.com/pullfrog/action#readme",
homepage: "https://github.com/pullfrog/pullfrog#readme",
zshy: {
exports: "./index.ts"
},
@@ -100346,6 +100345,11 @@ var AgentName = type.enumerated(...Object.keys(agentsManifest));
var Effort = type.enumerated("nothink", "think", "max");
// modes.ts
var ModeSchema = type({
name: "string",
description: "string",
prompt: "string"
});
var reportProgressInstruction = `Use ${ghPullfrogMcpName}/report_progress to share progress and results. Continue calling it as you make progress - it will update the same comment. Never create additional comments manually.`;
var dependencyInstallationGuidance = `## Dependency Installation
@@ -138403,11 +138407,28 @@ var Timer = class {
// main.ts
var Inputs = type({
prompt: "string",
"effort?": Effort
"effort?": Effort,
"agent?": AgentName.or("null"),
"event?": "object",
"modes?": ModeSchema.array(),
"sandbox?": "boolean",
"disableProgressComment?": "true",
"comment_id?": "number|null",
"issue_id?": "number|null",
"pr_id?": "number|null",
"cwd?": "string"
});
async function main(inputs) {
var _stack2 = [];
try {
let cwd2 = inputs.cwd || process.env.GITHUB_WORKSPACE;
if (inputs.cwd && !isAbsolute(inputs.cwd) && process.env.GITHUB_WORKSPACE) {
cwd2 = resolve(process.env.GITHUB_WORKSPACE, inputs.cwd);
}
if (cwd2 && process.cwd() !== cwd2) {
log.debug(`changing to working directory: ${cwd2}`);
process.chdir(cwd2);
}
const timer = new Timer();
const tokenRef = __using(_stack2, await setupGitHubInstallationToken(), true);
let payload;
@@ -138592,7 +138613,7 @@ To fix this, add the required secret to your GitHub repository:
Alternatively, configure Pullfrog to use a different agent at ${settingsUrl}`;
}
async function initializeGitHub(token) {
log.info(`\u{1F438} Running pullfrog/action@${package_default.version}...`);
log.info(`\u{1F438} Running pullfrog/pullfrog@${package_default.version}...`);
const { owner, name } = parseRepoContext();
const octokit = createOctokit(token);
const [repoResponse, repoSettings] = await Promise.all([
@@ -138650,6 +138671,22 @@ async function createTempDirectory() {
return sharedTempDir;
}
function parsePayload(inputs) {
const agent2 = inputs.agent === void 0 || inputs.agent === "null" ? null : inputs.agent;
if (inputs.event) {
return {
"~pullfrog": true,
agent: agent2,
prompt: inputs.prompt,
event: inputs.event,
modes: inputs.modes ?? modes,
effort: inputs.effort ?? "think",
sandbox: inputs.sandbox,
disableProgressComment: inputs.disableProgressComment,
comment_id: inputs.comment_id,
issue_id: inputs.issue_id,
pr_id: inputs.pr_id
};
}
try {
const parsedPrompt = JSON.parse(inputs.prompt);
if (!("~pullfrog" in parsedPrompt)) {
@@ -138662,13 +138699,14 @@ function parsePayload(inputs) {
} catch {
return {
"~pullfrog": true,
agent: null,
agent: agent2,
prompt: inputs.prompt,
event: {
trigger: "unknown"
},
modes,
effort: inputs.effort ?? "think"
modes: inputs.modes ?? modes,
effort: inputs.effort ?? "think",
sandbox: inputs.sandbox
};
}
}
@@ -138754,19 +138792,11 @@ async function handleAgentResult(result) {
// entry.ts
async function run() {
const cwdInput = core4.getInput("cwd");
let cwd2 = cwdInput || process.env.GITHUB_WORKSPACE;
if (cwdInput && !isAbsolute(cwdInput) && process.env.GITHUB_WORKSPACE) {
cwd2 = resolve(process.env.GITHUB_WORKSPACE, cwdInput);
}
if (cwd2 && process.cwd() !== cwd2) {
log.debug(`changing to working directory: ${cwd2}`);
process.chdir(cwd2);
}
try {
const inputs = Inputs.assert({
prompt: core4.getInput("prompt", { required: true }),
effort: core4.getInput("effort") || "think"
effort: core4.getInput("effort") || "think",
cwd: core4.getInput("cwd") || void 0
});
const result = await main(inputs);
if (!result.success) {
+2 -18
View File
@@ -1,34 +1,18 @@
#!/usr/bin/env node
/**
* Entry point for GitHub Action
* entry point for pullfrog/pullfrog - main action
*/
import * as core from "@actions/core";
import { resolve, isAbsolute } from "path";
import { Inputs, main } from "./main.ts";
import { log } from "./utils/cli.ts";
async function run(): Promise<void> {
// Change to cwd input or GITHUB_WORKSPACE (where actions/checkout puts the repo)
// JavaScript actions run from the action's directory, not the checked out repo
const cwdInput = core.getInput("cwd");
let cwd = cwdInput || process.env.GITHUB_WORKSPACE;
// resolve relative paths against GITHUB_WORKSPACE
if (cwdInput && !isAbsolute(cwdInput) && process.env.GITHUB_WORKSPACE) {
cwd = resolve(process.env.GITHUB_WORKSPACE, cwdInput);
}
if (cwd && process.cwd() !== cwd) {
log.debug(`changing to working directory: ${cwd}`);
process.chdir(cwd);
}
try {
const inputs = Inputs.assert({
prompt: core.getInput("prompt", { required: true }),
effort: core.getInput("effort") || "think",
cwd: core.getInput("cwd") || undefined,
});
const result = await main(inputs);
+16
View File
@@ -75,4 +75,20 @@ await build({
plugins: [stripShebangPlugin],
});
// Build the run sub-action
await build({
...sharedConfig,
entryPoints: ["./run/entry.ts"],
outfile: "./run/entry",
plugins: [stripShebangPlugin],
});
// Build the dispatch sub-action
await build({
...sharedConfig,
entryPoints: ["./dispatch/entry.ts"],
outfile: "./dispatch/entry",
plugins: [stripShebangPlugin],
});
console.log("✅ Build completed successfully!");
+51 -7
View File
@@ -1,17 +1,17 @@
import { mkdtemp } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { isAbsolute, join, resolve } from "node:path";
import { flatMorph } from "@ark/util";
import type { Octokit } from "@octokit/rest";
import { encode as toonEncode } from "@toon-format/toon";
import { type } from "arktype";
import { type Agent, agents } from "./agents/index.ts";
import type { AgentResult } from "./agents/shared.ts";
import { type AgentName, agentsManifest, Effort, type Payload } from "./external.ts";
import { AgentName, agentsManifest, Effort, type Payload } from "./external.ts";
import { ensureProgressCommentUpdated, reportProgress } from "./mcp/comment.ts";
import { createMcpConfigs } from "./mcp/config.ts";
import { startMcpHttpServer } from "./mcp/server.ts";
import { getModes, type Mode, modes } from "./modes.ts";
import { getModes, type Mode, ModeSchema, modes } from "./modes.ts";
import packageJson from "./package.json" with { type: "json" };
import type { PrepResult } from "./prep/index.ts";
import { fetchRepoSettings, fetchWorkflowRunInfo, type RepoSettings } from "./utils/api.ts";
@@ -21,9 +21,19 @@ import { createOctokit, parseRepoContext, setupGitHubInstallationToken } from ".
import { setupGitAuth, setupGitConfig } from "./utils/setup.ts";
import { Timer } from "./utils/timer.ts";
// inputs schema - mirrors Payload fields without the discriminated union for event
export const Inputs = type({
prompt: "string",
"effort?": Effort,
"agent?": AgentName.or("null"),
"event?": "object",
"modes?": ModeSchema.array(),
"sandbox?": "boolean",
"disableProgressComment?": "true",
"comment_id?": "number|null",
"issue_id?": "number|null",
"pr_id?": "number|null",
"cwd?": "string",
});
export type Inputs = typeof Inputs.infer;
@@ -48,6 +58,17 @@ type ApiKeySetup =
| { success: false; error: string };
export async function main(inputs: Inputs): Promise<MainResult> {
// change to cwd input or GITHUB_WORKSPACE (where actions/checkout puts the repo)
// JavaScript actions run from the action's directory, not the checked out repo
let cwd = inputs.cwd || process.env.GITHUB_WORKSPACE;
if (inputs.cwd && !isAbsolute(inputs.cwd) && process.env.GITHUB_WORKSPACE) {
cwd = resolve(process.env.GITHUB_WORKSPACE, inputs.cwd);
}
if (cwd && process.cwd() !== cwd) {
log.debug(`changing to working directory: ${cwd}`);
process.chdir(cwd);
}
const timer = new Timer();
// `await using` ensures the token is automatically revoked when the function exits
await using tokenRef = await setupGitHubInstallationToken();
@@ -316,7 +337,7 @@ export interface ToolState {
* Initialize GitHub connection: token, octokit, repo data, settings
*/
async function initializeGitHub(token: string): Promise<GitHubSetup> {
log.info(`🐸 Running pullfrog/action@${packageJson.version}...`);
log.info(`🐸 Running pullfrog/pullfrog@${packageJson.version}...`);
const { owner, name } = parseRepoContext();
@@ -397,6 +418,28 @@ async function createTempDirectory(): Promise<string> {
}
function parsePayload(inputs: Inputs): Payload {
// helper to convert "null" string to null, with proper type narrowing
const agent =
inputs.agent === undefined || inputs.agent === "null" ? null : (inputs.agent as AgentName);
// dispatch action provides structured inputs directly (event, modes, etc.)
if (inputs.event) {
return {
"~pullfrog": true,
agent,
prompt: inputs.prompt,
event: inputs.event as Payload["event"],
modes: inputs.modes ?? modes,
effort: inputs.effort ?? "think",
sandbox: inputs.sandbox,
disableProgressComment: inputs.disableProgressComment,
comment_id: inputs.comment_id,
issue_id: inputs.issue_id,
pr_id: inputs.pr_id,
} as Payload;
}
// run action: try to parse prompt as JSON (legacy internal invocation)
try {
const parsedPrompt = JSON.parse(inputs.prompt);
if (!("~pullfrog" in parsedPrompt)) {
@@ -411,14 +454,15 @@ function parsePayload(inputs: Inputs): Payload {
// external invocation: use effort from input
return {
"~pullfrog": true,
agent: null,
agent,
prompt: inputs.prompt,
event: {
trigger: "unknown",
},
modes,
modes: inputs.modes ?? modes,
effort: inputs.effort ?? "think",
};
sandbox: inputs.sandbox,
} as Payload;
}
}
+8
View File
@@ -1,3 +1,4 @@
import { type } from "arktype";
import { ghPullfrogMcpName } from "./external.ts";
export interface Mode {
@@ -6,6 +7,13 @@ export interface Mode {
prompt: string;
}
// arktype schema for Mode validation
export const ModeSchema = type({
name: "string",
description: "string",
prompt: "string",
});
export interface GetModesParams {
disableProgressComment: true | undefined;
}
+4 -4
View File
@@ -1,5 +1,5 @@
{
"name": "@pullfrog/action",
"name": "@pullfrog/pullfrog",
"version": "0.0.157",
"type": "module",
"files": [
@@ -52,15 +52,15 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/pullfrog/action.git"
"url": "git+https://github.com/pullfrog/pullfrog.git"
},
"keywords": [],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/pullfrog/action/issues"
"url": "https://github.com/pullfrog/pullfrog/issues"
},
"homepage": "https://github.com/pullfrog/action#readme",
"homepage": "https://github.com/pullfrog/pullfrog#readme",
"zshy": {
"exports": "./index.ts"
},
+35
View File
@@ -0,0 +1,35 @@
# pullfrog/pullfrog/run
# pullfrog/pullfrog (alias)
# pullfrog/pullfrog/dispatch <- accepts json
name: "Pullfrog Action (Run)"
description: "Execute coding agents with itemized inputs"
author: "Pullfrog"
inputs:
prompt:
description: "Prompt to send to the agent"
required: true
effort:
description: "Effort level: nothink (fast), think (default), max (most capable)"
required: false
default: "think"
agent:
description: "Agent to use: claude, codex, gemini, cursor, opencode"
required: false
cwd:
description: "Working directory for the agent (defaults to GITHUB_WORKSPACE)"
required: false
sandbox:
description: "Sandbox mode: restricts agent to read-only operations"
required: false
runs:
using: "node24"
main: "entry"
branding:
icon: "code"
color: "green"
Executable
+138868
View File
File diff suppressed because one or more lines are too long
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env node
/**
* entry point for pullfrog/pullfrog/run - itemized inputs for external users
*/
import * as core from "@actions/core";
import { Inputs, main } from "../main.ts";
async function run(): Promise<void> {
try {
const inputs = Inputs.assert({
prompt: core.getInput("prompt", { required: true }),
effort: core.getInput("effort") || "think",
agent: core.getInput("agent") || null,
sandbox: core.getInput("sandbox") === "true" ? true : undefined,
cwd: core.getInput("cwd") || undefined,
});
const result = await main(inputs);
if (!result.success) {
throw new Error(result.error || "Agent execution failed");
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
core.setFailed(`Action failed: ${errorMessage}`);
}
}
await run();