Fix repo slug
This commit is contained in:
committed by
pullfrog[bot]
parent
5604cf1868
commit
3fa309853b
@@ -80,18 +80,18 @@ jobs:
|
|||||||
tag_name: ${{ steps.version.outputs.tag }}
|
tag_name: ${{ steps.version.outputs.tag }}
|
||||||
release_name: "${{ steps.version.outputs.tag }}"
|
release_name: "${{ steps.version.outputs.tag }}"
|
||||||
body: |
|
body: |
|
||||||
## 📦 @pullfrog/action ${{ steps.version.outputs.version }}
|
## 📦 @pullfrog/pullfrog ${{ steps.version.outputs.version }}
|
||||||
|
|
||||||
### Usage in GitHub Actions
|
### Usage in GitHub Actions
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: pullfrog/action@${{ steps.version.outputs.major_tag }}
|
- uses: pullfrog/pullfrog@${{ steps.version.outputs.major_tag }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installation via npm
|
### Installation via npm
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @pullfrog/action@${{ steps.version.outputs.version }}
|
npm install @pullfrog/pullfrog@${{ steps.version.outputs.version }}
|
||||||
```
|
```
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
@@ -118,5 +118,5 @@ jobs:
|
|||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### 📦 Published to" >> $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 "- 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
|
fi
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Run agent
|
- name: Run agent
|
||||||
uses: pullfrog/action@main
|
uses: pullfrog/pullfrog@main
|
||||||
with:
|
with:
|
||||||
prompt: ${{ inputs.prompt }}
|
prompt: ${{ inputs.prompt }}
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Dispatch "action-repo-updated" event
|
- name: Dispatch "action-repo-updated" event
|
||||||
run: |
|
run: |
|
||||||
gh api repos/pullfrog/pullfrog/dispatches \
|
gh api repos/pullfrog/app/dispatches \
|
||||||
-f event_type="action-repo-updated" \
|
-f event_type="action-repo-updated" \
|
||||||
-f client_payload='{
|
-f client_payload='{
|
||||||
"before": "${{ github.event.before }}",
|
"before": "${{ github.event.before }}",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ Install the Pullfrog GitHub App on your personal or organization account. During
|
|||||||
<details>
|
<details>
|
||||||
<summary><strong>Manual setup instructions</strong></summary>
|
<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).
|
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
|
# - uses: actions/setup-node@v6
|
||||||
|
|
||||||
- name: Run agent
|
- name: Run agent
|
||||||
uses: pullfrog/action@v0
|
uses: pullfrog/pullfrog@v0
|
||||||
with:
|
with:
|
||||||
prompt: ${{ inputs.prompt }}
|
prompt: ${{ inputs.prompt }}
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -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
File diff suppressed because one or more lines are too long
@@ -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();
|
||||||
@@ -74360,12 +74360,11 @@ var init_index_CLFto6T2 = __esm({
|
|||||||
|
|
||||||
// entry.ts
|
// entry.ts
|
||||||
var core4 = __toESM(require_core(), 1);
|
var core4 = __toESM(require_core(), 1);
|
||||||
import { resolve, isAbsolute } from "path";
|
|
||||||
|
|
||||||
// main.ts
|
// main.ts
|
||||||
import { mkdtemp as mkdtemp2 } from "node:fs/promises";
|
import { mkdtemp as mkdtemp2 } from "node:fs/promises";
|
||||||
import { tmpdir as tmpdir2 } from "node:os";
|
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
|
// node_modules/.pnpm/@ark+util@0.53.0/node_modules/@ark/util/out/arrays.js
|
||||||
var append = (to, value2, opts) => {
|
var append = (to, value2, opts) => {
|
||||||
@@ -99967,7 +99966,7 @@ function query({
|
|||||||
|
|
||||||
// package.json
|
// package.json
|
||||||
var package_default = {
|
var package_default = {
|
||||||
name: "@pullfrog/action",
|
name: "@pullfrog/pullfrog",
|
||||||
version: "0.0.157",
|
version: "0.0.157",
|
||||||
type: "module",
|
type: "module",
|
||||||
files: [
|
files: [
|
||||||
@@ -100020,15 +100019,15 @@ var package_default = {
|
|||||||
},
|
},
|
||||||
repository: {
|
repository: {
|
||||||
type: "git",
|
type: "git",
|
||||||
url: "git+https://github.com/pullfrog/action.git"
|
url: "git+https://github.com/pullfrog/pullfrog.git"
|
||||||
},
|
},
|
||||||
keywords: [],
|
keywords: [],
|
||||||
author: "",
|
author: "",
|
||||||
license: "MIT",
|
license: "MIT",
|
||||||
bugs: {
|
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: {
|
zshy: {
|
||||||
exports: "./index.ts"
|
exports: "./index.ts"
|
||||||
},
|
},
|
||||||
@@ -100346,6 +100345,11 @@ var AgentName = type.enumerated(...Object.keys(agentsManifest));
|
|||||||
var Effort = type.enumerated("nothink", "think", "max");
|
var Effort = type.enumerated("nothink", "think", "max");
|
||||||
|
|
||||||
// modes.ts
|
// 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 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
|
var dependencyInstallationGuidance = `## Dependency Installation
|
||||||
|
|
||||||
@@ -138403,11 +138407,28 @@ var Timer = class {
|
|||||||
// main.ts
|
// main.ts
|
||||||
var Inputs = type({
|
var Inputs = type({
|
||||||
prompt: "string",
|
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) {
|
async function main(inputs) {
|
||||||
var _stack2 = [];
|
var _stack2 = [];
|
||||||
try {
|
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 timer = new Timer();
|
||||||
const tokenRef = __using(_stack2, await setupGitHubInstallationToken(), true);
|
const tokenRef = __using(_stack2, await setupGitHubInstallationToken(), true);
|
||||||
let payload;
|
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}`;
|
Alternatively, configure Pullfrog to use a different agent at ${settingsUrl}`;
|
||||||
}
|
}
|
||||||
async function initializeGitHub(token) {
|
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 { owner, name } = parseRepoContext();
|
||||||
const octokit = createOctokit(token);
|
const octokit = createOctokit(token);
|
||||||
const [repoResponse, repoSettings] = await Promise.all([
|
const [repoResponse, repoSettings] = await Promise.all([
|
||||||
@@ -138650,6 +138671,22 @@ async function createTempDirectory() {
|
|||||||
return sharedTempDir;
|
return sharedTempDir;
|
||||||
}
|
}
|
||||||
function parsePayload(inputs) {
|
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 {
|
try {
|
||||||
const parsedPrompt = JSON.parse(inputs.prompt);
|
const parsedPrompt = JSON.parse(inputs.prompt);
|
||||||
if (!("~pullfrog" in parsedPrompt)) {
|
if (!("~pullfrog" in parsedPrompt)) {
|
||||||
@@ -138662,13 +138699,14 @@ function parsePayload(inputs) {
|
|||||||
} catch {
|
} catch {
|
||||||
return {
|
return {
|
||||||
"~pullfrog": true,
|
"~pullfrog": true,
|
||||||
agent: null,
|
agent: agent2,
|
||||||
prompt: inputs.prompt,
|
prompt: inputs.prompt,
|
||||||
event: {
|
event: {
|
||||||
trigger: "unknown"
|
trigger: "unknown"
|
||||||
},
|
},
|
||||||
modes,
|
modes: inputs.modes ?? modes,
|
||||||
effort: inputs.effort ?? "think"
|
effort: inputs.effort ?? "think",
|
||||||
|
sandbox: inputs.sandbox
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138754,19 +138792,11 @@ async function handleAgentResult(result) {
|
|||||||
|
|
||||||
// entry.ts
|
// entry.ts
|
||||||
async function run() {
|
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 {
|
try {
|
||||||
const inputs = Inputs.assert({
|
const inputs = Inputs.assert({
|
||||||
prompt: core4.getInput("prompt", { required: true }),
|
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);
|
const result = await main(inputs);
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
|
|||||||
@@ -1,34 +1,18 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point for GitHub Action
|
* entry point for pullfrog/pullfrog - main action
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import { resolve, isAbsolute } from "path";
|
|
||||||
import { Inputs, main } from "./main.ts";
|
import { Inputs, main } from "./main.ts";
|
||||||
import { log } from "./utils/cli.ts";
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
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 {
|
try {
|
||||||
const inputs = Inputs.assert({
|
const inputs = Inputs.assert({
|
||||||
prompt: core.getInput("prompt", { required: true }),
|
prompt: core.getInput("prompt", { required: true }),
|
||||||
effort: core.getInput("effort") || "think",
|
effort: core.getInput("effort") || "think",
|
||||||
|
cwd: core.getInput("cwd") || undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await main(inputs);
|
const result = await main(inputs);
|
||||||
|
|||||||
@@ -75,4 +75,20 @@ await build({
|
|||||||
plugins: [stripShebangPlugin],
|
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!");
|
console.log("✅ Build completed successfully!");
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { mkdtemp } from "node:fs/promises";
|
import { mkdtemp } from "node:fs/promises";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { join } from "node:path";
|
import { isAbsolute, join, resolve } from "node:path";
|
||||||
import { flatMorph } from "@ark/util";
|
import { flatMorph } from "@ark/util";
|
||||||
import type { Octokit } from "@octokit/rest";
|
import type { Octokit } from "@octokit/rest";
|
||||||
import { encode as toonEncode } from "@toon-format/toon";
|
import { encode as toonEncode } from "@toon-format/toon";
|
||||||
import { type } from "arktype";
|
import { type } from "arktype";
|
||||||
import { type Agent, agents } from "./agents/index.ts";
|
import { type Agent, agents } from "./agents/index.ts";
|
||||||
import type { AgentResult } from "./agents/shared.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 { ensureProgressCommentUpdated, reportProgress } from "./mcp/comment.ts";
|
||||||
import { createMcpConfigs } from "./mcp/config.ts";
|
import { createMcpConfigs } from "./mcp/config.ts";
|
||||||
import { startMcpHttpServer } from "./mcp/server.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 packageJson from "./package.json" with { type: "json" };
|
||||||
import type { PrepResult } from "./prep/index.ts";
|
import type { PrepResult } from "./prep/index.ts";
|
||||||
import { fetchRepoSettings, fetchWorkflowRunInfo, type RepoSettings } from "./utils/api.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 { setupGitAuth, setupGitConfig } from "./utils/setup.ts";
|
||||||
import { Timer } from "./utils/timer.ts";
|
import { Timer } from "./utils/timer.ts";
|
||||||
|
|
||||||
|
// inputs schema - mirrors Payload fields without the discriminated union for event
|
||||||
export const Inputs = type({
|
export const Inputs = type({
|
||||||
prompt: "string",
|
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",
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Inputs = typeof Inputs.infer;
|
export type Inputs = typeof Inputs.infer;
|
||||||
@@ -48,6 +58,17 @@ type ApiKeySetup =
|
|||||||
| { success: false; error: string };
|
| { success: false; error: string };
|
||||||
|
|
||||||
export async function main(inputs: Inputs): Promise<MainResult> {
|
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();
|
const timer = new Timer();
|
||||||
// `await using` ensures the token is automatically revoked when the function exits
|
// `await using` ensures the token is automatically revoked when the function exits
|
||||||
await using tokenRef = await setupGitHubInstallationToken();
|
await using tokenRef = await setupGitHubInstallationToken();
|
||||||
@@ -316,7 +337,7 @@ export interface ToolState {
|
|||||||
* Initialize GitHub connection: token, octokit, repo data, settings
|
* Initialize GitHub connection: token, octokit, repo data, settings
|
||||||
*/
|
*/
|
||||||
async function initializeGitHub(token: string): Promise<GitHubSetup> {
|
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();
|
const { owner, name } = parseRepoContext();
|
||||||
|
|
||||||
@@ -397,6 +418,28 @@ async function createTempDirectory(): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parsePayload(inputs: Inputs): Payload {
|
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 {
|
try {
|
||||||
const parsedPrompt = JSON.parse(inputs.prompt);
|
const parsedPrompt = JSON.parse(inputs.prompt);
|
||||||
if (!("~pullfrog" in parsedPrompt)) {
|
if (!("~pullfrog" in parsedPrompt)) {
|
||||||
@@ -411,14 +454,15 @@ function parsePayload(inputs: Inputs): Payload {
|
|||||||
// external invocation: use effort from input
|
// external invocation: use effort from input
|
||||||
return {
|
return {
|
||||||
"~pullfrog": true,
|
"~pullfrog": true,
|
||||||
agent: null,
|
agent,
|
||||||
prompt: inputs.prompt,
|
prompt: inputs.prompt,
|
||||||
event: {
|
event: {
|
||||||
trigger: "unknown",
|
trigger: "unknown",
|
||||||
},
|
},
|
||||||
modes,
|
modes: inputs.modes ?? modes,
|
||||||
effort: inputs.effort ?? "think",
|
effort: inputs.effort ?? "think",
|
||||||
};
|
sandbox: inputs.sandbox,
|
||||||
|
} as Payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { type } from "arktype";
|
||||||
import { ghPullfrogMcpName } from "./external.ts";
|
import { ghPullfrogMcpName } from "./external.ts";
|
||||||
|
|
||||||
export interface Mode {
|
export interface Mode {
|
||||||
@@ -6,6 +7,13 @@ export interface Mode {
|
|||||||
prompt: string;
|
prompt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// arktype schema for Mode validation
|
||||||
|
export const ModeSchema = type({
|
||||||
|
name: "string",
|
||||||
|
description: "string",
|
||||||
|
prompt: "string",
|
||||||
|
});
|
||||||
|
|
||||||
export interface GetModesParams {
|
export interface GetModesParams {
|
||||||
disableProgressComment: true | undefined;
|
disableProgressComment: true | undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@pullfrog/action",
|
"name": "@pullfrog/pullfrog",
|
||||||
"version": "0.0.157",
|
"version": "0.0.157",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
@@ -52,15 +52,15 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/pullfrog/action.git"
|
"url": "git+https://github.com/pullfrog/pullfrog.git"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"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": {
|
"zshy": {
|
||||||
"exports": "./index.ts"
|
"exports": "./index.ts"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -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();
|
||||||
Reference in New Issue
Block a user