git-vibe-setup 2.0.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 +11 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +41 -0
- package/dist/install.d.ts +14 -0
- package/dist/install.js +94 -0
- package/dist/instructions.d.ts +1 -0
- package/dist/instructions.js +25 -0
- package/dist/releases.d.ts +11 -0
- package/dist/releases.js +65 -0
- package/package.json +25 -0
- package/templates/.git-vibe/role-group/correctness.md +7 -0
- package/templates/.git-vibe/role-group/maintainability.md +7 -0
- package/templates/.git-vibe/role-group/security.md +7 -0
- package/templates/.github/git-vibe.yml +105 -0
- package/templates/.github/workflows/address-feedback.yml +34 -0
- package/templates/.github/workflows/decompose.yml +34 -0
- package/templates/.github/workflows/develop.yml +39 -0
- package/templates/.github/workflows/investigate.yml +34 -0
- package/templates/.github/workflows/materialize.yml +34 -0
- package/templates/.github/workflows/validate.yml +41 -0
- package/templates/GITVIBE_AI_ENV_JSON.example.json +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# git-vibe-setup
|
|
2
|
+
|
|
3
|
+
Local initializer for GitVibe consumer repositories.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx --package=git-vibe-setup git-vibe-setup
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The command writes `.github` and `.git-vibe` starter files, pins reusable
|
|
10
|
+
workflow refs to the latest stable `markhuangai/git-vibe` release, and fails
|
|
11
|
+
before writing if release lookup or target-file validation fails.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface SetupCliRuntime {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
error?: (message: string) => void;
|
|
5
|
+
fetchImpl?: typeof fetch;
|
|
6
|
+
log?: (message: string) => void;
|
|
7
|
+
repositoryRoot?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function runSetup(runtime?: SetupCliRuntime): Promise<void>;
|
|
10
|
+
export declare function setupCli(runtime?: SetupCliRuntime): Promise<number>;
|
|
11
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { blockingInstallPaths, buildInstallFiles, existingFilesError, installFiles, } from "./install.js";
|
|
6
|
+
import { renderManualSetupInstructions } from "./instructions.js";
|
|
7
|
+
import { latestStableReleaseTag } from "./releases.js";
|
|
8
|
+
export async function runSetup(runtime = {}) {
|
|
9
|
+
const cwd = runtime.cwd || process.cwd();
|
|
10
|
+
const repositoryRoot = runtime.repositoryRoot || packageRoot();
|
|
11
|
+
const releaseTag = await latestStableReleaseTag(runtime.fetchImpl || fetch);
|
|
12
|
+
const files = buildInstallFiles({ cwd, releaseTag, repositoryRoot });
|
|
13
|
+
const blockingPaths = blockingInstallPaths(files);
|
|
14
|
+
if (blockingPaths.length > 0)
|
|
15
|
+
throw existingFilesError(blockingPaths, cwd);
|
|
16
|
+
installFiles(files);
|
|
17
|
+
(runtime.log || console.log)(renderManualSetupInstructions(releaseTag));
|
|
18
|
+
}
|
|
19
|
+
export async function setupCli(runtime = {}) {
|
|
20
|
+
try {
|
|
21
|
+
await runSetup(runtime);
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
26
|
+
(runtime.error || console.error)(message);
|
|
27
|
+
return 1;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function packageRoot() {
|
|
31
|
+
return fileURLToPath(new URL("../", import.meta.url));
|
|
32
|
+
}
|
|
33
|
+
/* c8 ignore start */
|
|
34
|
+
if (isDirectRun(import.meta.url)) {
|
|
35
|
+
const exitCode = await setupCli();
|
|
36
|
+
process.exitCode = exitCode;
|
|
37
|
+
}
|
|
38
|
+
/* c8 ignore stop */
|
|
39
|
+
function isDirectRun(moduleUrl, entrypoint = process.argv[1]) {
|
|
40
|
+
return Boolean(entrypoint && moduleUrl === pathToFileURL(resolve(entrypoint)).href);
|
|
41
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface InstallFile {
|
|
2
|
+
content: string;
|
|
3
|
+
sourcePath: string;
|
|
4
|
+
targetPath: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function buildInstallFiles(options: {
|
|
7
|
+
cwd: string;
|
|
8
|
+
releaseTag: string;
|
|
9
|
+
repositoryRoot: string;
|
|
10
|
+
}): InstallFile[];
|
|
11
|
+
export declare function blockingInstallPaths(files: InstallFile[]): string[];
|
|
12
|
+
export declare function installFiles(files: InstallFile[]): void;
|
|
13
|
+
export declare function existingFilesError(paths: string[], cwd: string): Error;
|
|
14
|
+
export declare function pinWorkflowReleaseRefs(content: string, releaseTag: string): string;
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join, relative } from "node:path";
|
|
3
|
+
export function buildInstallFiles(options) {
|
|
4
|
+
return installSources(options.repositoryRoot).flatMap((source) => listRelativeFiles(source.sourceDirectory).map((relativePath) => {
|
|
5
|
+
const sourcePath = join(source.sourceDirectory, relativePath);
|
|
6
|
+
const targetPath = join(options.cwd, source.targetDirectory, relativePath);
|
|
7
|
+
const content = readFileSync(sourcePath, "utf8");
|
|
8
|
+
return {
|
|
9
|
+
content: pinWorkflowReleaseRefs(content, options.releaseTag),
|
|
10
|
+
sourcePath,
|
|
11
|
+
targetPath,
|
|
12
|
+
};
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
export function blockingInstallPaths(files) {
|
|
16
|
+
return files
|
|
17
|
+
.map((file) => file.targetPath)
|
|
18
|
+
.filter((targetPath) => existsSync(targetPath))
|
|
19
|
+
.sort();
|
|
20
|
+
}
|
|
21
|
+
export function installFiles(files) {
|
|
22
|
+
const createdDirectories = [];
|
|
23
|
+
const createdFiles = [];
|
|
24
|
+
try {
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
ensureDirectory(dirname(file.targetPath), createdDirectories);
|
|
27
|
+
writeFileSync(file.targetPath, file.content, { flag: "wx" });
|
|
28
|
+
createdFiles.push(file.targetPath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
rollbackInstall(createdFiles, createdDirectories);
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function existingFilesError(paths, cwd) {
|
|
37
|
+
const listed = paths.map((path) => `- ${relative(cwd, path) || path}`).join("\n");
|
|
38
|
+
return new Error(`git-vibe-setup found existing GitVibe files and did not overwrite them:\n${listed}\nRemove the listed files before running setup again.`);
|
|
39
|
+
}
|
|
40
|
+
export function pinWorkflowReleaseRefs(content, releaseTag) {
|
|
41
|
+
return content.replace(/(uses:\s*markhuangai\/git-vibe\/\.github\/workflows\/[^\s@]+)@[^\s]+/g, (_match, workflowReference) => `${workflowReference}@${releaseTag}`);
|
|
42
|
+
}
|
|
43
|
+
function installSources(repositoryRoot) {
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
sourceDirectory: join(repositoryRoot, "templates", ".github"),
|
|
47
|
+
targetDirectory: ".github",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
sourceDirectory: join(repositoryRoot, "templates", ".git-vibe"),
|
|
51
|
+
targetDirectory: ".git-vibe",
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
function listRelativeFiles(directory) {
|
|
56
|
+
return readdirSync(directory, { withFileTypes: true })
|
|
57
|
+
.flatMap((entry) => {
|
|
58
|
+
const entryPath = join(directory, entry.name);
|
|
59
|
+
if (entry.isDirectory()) {
|
|
60
|
+
return listRelativeFiles(entryPath).map((path) => join(entry.name, path));
|
|
61
|
+
}
|
|
62
|
+
/* c8 ignore next */
|
|
63
|
+
return entry.isFile() ? [entry.name] : [];
|
|
64
|
+
})
|
|
65
|
+
.sort();
|
|
66
|
+
}
|
|
67
|
+
function ensureDirectory(directory, createdDirectories) {
|
|
68
|
+
const missing = missingDirectories(directory);
|
|
69
|
+
for (const path of missing) {
|
|
70
|
+
mkdirSync(path);
|
|
71
|
+
createdDirectories.push(path);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function missingDirectories(directory) {
|
|
75
|
+
const missing = [];
|
|
76
|
+
let current = directory;
|
|
77
|
+
while (!existsSync(current)) {
|
|
78
|
+
missing.push(current);
|
|
79
|
+
const parent = dirname(current);
|
|
80
|
+
/* c8 ignore next */
|
|
81
|
+
if (parent === current)
|
|
82
|
+
break;
|
|
83
|
+
current = parent;
|
|
84
|
+
}
|
|
85
|
+
return missing.reverse();
|
|
86
|
+
}
|
|
87
|
+
function rollbackInstall(createdFiles, createdDirectories) {
|
|
88
|
+
for (const file of [...createdFiles].reverse()) {
|
|
89
|
+
rmSync(file, { force: true });
|
|
90
|
+
}
|
|
91
|
+
for (const directory of [...createdDirectories].reverse()) {
|
|
92
|
+
rmSync(directory, { force: true, recursive: false });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderManualSetupInstructions(releaseTag: string): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const requiredSecrets = [
|
|
2
|
+
["GITVIBE_AI_ENV_JSON", "JSON env bundle for AI provider config and CLI auth."],
|
|
3
|
+
["GITVIBE_GITHUB_TOKEN", "Fine-grained PAT for GitVibe workflow and server writes."],
|
|
4
|
+
["WEBHOOK_SECRET", "Webhook shared secret mapped to GITHUB_WEBHOOK_SECRET in deployment."],
|
|
5
|
+
];
|
|
6
|
+
const usefulVariables = [
|
|
7
|
+
"GITVIBE_BASE_BRANCH",
|
|
8
|
+
"GITVIBE_DISCUSSION_CATEGORY",
|
|
9
|
+
"GITVIBE_RUNNER",
|
|
10
|
+
"GITVIBE_LOG_LEVEL",
|
|
11
|
+
];
|
|
12
|
+
export function renderManualSetupInstructions(releaseTag) {
|
|
13
|
+
const lines = [
|
|
14
|
+
`GitVibe starter files installed with reusable workflows pinned to ${releaseTag}.`,
|
|
15
|
+
"",
|
|
16
|
+
"Configure these GitHub secrets manually before running the workflows:",
|
|
17
|
+
...requiredSecrets.map(([name, description]) => `- ${name}: ${description}`),
|
|
18
|
+
"",
|
|
19
|
+
"Optional repository variables:",
|
|
20
|
+
...usefulVariables.map((name) => `- ${name}`),
|
|
21
|
+
"",
|
|
22
|
+
`Reference bundle shape: https://github.com/markhuangai/git-vibe/blob/${releaseTag}/examples/consumer/GITVIBE_AI_ENV_JSON.example.json`,
|
|
23
|
+
];
|
|
24
|
+
return lines.join("\n");
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface GitHubRelease {
|
|
2
|
+
created_at?: string;
|
|
3
|
+
draft?: boolean;
|
|
4
|
+
prerelease?: boolean;
|
|
5
|
+
published_at?: string;
|
|
6
|
+
tag_name?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class ReleaseLookupError extends Error {
|
|
9
|
+
}
|
|
10
|
+
export declare function latestStableReleaseTag(fetchImpl?: typeof fetch): Promise<string>;
|
|
11
|
+
export declare function selectLatestStableRelease(releases: GitHubRelease[]): GitHubRelease | undefined;
|
package/dist/releases.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export class ReleaseLookupError extends Error {
|
|
2
|
+
}
|
|
3
|
+
const releasesUrl = "https://api.github.com/repos/markhuangai/git-vibe/releases";
|
|
4
|
+
const releasesPerPage = 100;
|
|
5
|
+
export async function latestStableReleaseTag(fetchImpl = fetch) {
|
|
6
|
+
const releases = await fetchReleases(fetchImpl);
|
|
7
|
+
const release = selectLatestStableRelease(releases);
|
|
8
|
+
if (!release?.tag_name) {
|
|
9
|
+
throw new ReleaseLookupError("git-vibe-setup could not check the latest GitVibe update because no stable release is available. No files were written.");
|
|
10
|
+
}
|
|
11
|
+
return release.tag_name;
|
|
12
|
+
}
|
|
13
|
+
export function selectLatestStableRelease(releases) {
|
|
14
|
+
return releases
|
|
15
|
+
.filter((release) => !release.draft && !release.prerelease && release.tag_name)
|
|
16
|
+
.sort(compareReleaseFreshness)[0];
|
|
17
|
+
}
|
|
18
|
+
async function fetchReleases(fetchImpl) {
|
|
19
|
+
const releases = [];
|
|
20
|
+
for (let page = 1;; page += 1) {
|
|
21
|
+
const data = await fetchReleasePage(fetchImpl, page);
|
|
22
|
+
releases.push(...data);
|
|
23
|
+
if (data.length < releasesPerPage)
|
|
24
|
+
return releases;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function fetchReleasePage(fetchImpl, page) {
|
|
28
|
+
let response;
|
|
29
|
+
try {
|
|
30
|
+
response = await fetchImpl(releasePageUrl(page), {
|
|
31
|
+
headers: {
|
|
32
|
+
accept: "application/vnd.github+json",
|
|
33
|
+
"user-agent": "git-vibe-setup",
|
|
34
|
+
"x-github-api-version": "2022-11-28",
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
throw unavailableReleaseError();
|
|
40
|
+
}
|
|
41
|
+
if (!response.ok)
|
|
42
|
+
throw unavailableReleaseError();
|
|
43
|
+
try {
|
|
44
|
+
const data = await response.json();
|
|
45
|
+
return Array.isArray(data) ? data : [];
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
throw unavailableReleaseError();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function releasePageUrl(page) {
|
|
52
|
+
const url = new URL(releasesUrl);
|
|
53
|
+
url.searchParams.set("page", String(page));
|
|
54
|
+
url.searchParams.set("per_page", String(releasesPerPage));
|
|
55
|
+
return url.toString();
|
|
56
|
+
}
|
|
57
|
+
function compareReleaseFreshness(left, right) {
|
|
58
|
+
return releaseTime(right) - releaseTime(left);
|
|
59
|
+
}
|
|
60
|
+
function releaseTime(release) {
|
|
61
|
+
return Date.parse(release.published_at || release.created_at || "") || 0;
|
|
62
|
+
}
|
|
63
|
+
function unavailableReleaseError() {
|
|
64
|
+
return new ReleaseLookupError("git-vibe-setup could not check the latest GitVibe update because the GitHub release service is unavailable. No files were written.");
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "git-vibe-setup",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"git-vibe-setup": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"templates",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc --project tsconfig.build.json",
|
|
16
|
+
"check": "prettier --check . && eslint . && corepack pnpm typecheck && corepack pnpm test && corepack pnpm build",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"typecheck": "tsc --project tsconfig.json --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^25.6.0",
|
|
22
|
+
"typescript": "^6.0.3",
|
|
23
|
+
"vitest": "^4.1.5"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Correctness Reviewer
|
|
2
|
+
|
|
3
|
+
Review the stage result for behavioral correctness. Check that conclusions are
|
|
4
|
+
grounded in the GitHub context and repository evidence, and that any required
|
|
5
|
+
next action is specific enough to execute.
|
|
6
|
+
|
|
7
|
+
Return only the current stage schema.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Copy this file to .github/git-vibe.yml in the consumer repository.
|
|
2
|
+
|
|
3
|
+
version: 1
|
|
4
|
+
|
|
5
|
+
branches:
|
|
6
|
+
base: ""
|
|
7
|
+
|
|
8
|
+
runner:
|
|
9
|
+
default: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
github_auth:
|
|
12
|
+
mode: webhook-pat
|
|
13
|
+
# GitHub Actions Secret name. Stores the GitHub write token.
|
|
14
|
+
token_secret: GITVIBE_GITHUB_TOKEN
|
|
15
|
+
|
|
16
|
+
ai:
|
|
17
|
+
default_profile: local_proxy
|
|
18
|
+
profiles:
|
|
19
|
+
local_proxy:
|
|
20
|
+
enabled: true
|
|
21
|
+
adapter: ai-sdk-agentool
|
|
22
|
+
provider:
|
|
23
|
+
type: openai-compatible # openai | anthropic | openai-compatible
|
|
24
|
+
# Model names are configuration, not credentials.
|
|
25
|
+
model: glm-5
|
|
26
|
+
# Keys inside GITVIBE_AI_ENV_JSON.
|
|
27
|
+
base_url:
|
|
28
|
+
from_bundle: GITVIBE_AI_BASE_URL
|
|
29
|
+
api_key:
|
|
30
|
+
from_bundle: GITVIBE_AI_API_KEY
|
|
31
|
+
reasoning:
|
|
32
|
+
effort: high
|
|
33
|
+
generation:
|
|
34
|
+
temperature: 0.2
|
|
35
|
+
max_output_tokens: 6000
|
|
36
|
+
max_steps: 90
|
|
37
|
+
codex_cli:
|
|
38
|
+
enabled: false
|
|
39
|
+
adapter: cli-codex
|
|
40
|
+
# Key inside GITVIBE_AI_ENV_JSON. Stores compact auth.json contents.
|
|
41
|
+
auth_json:
|
|
42
|
+
from_bundle: CODEX_AUTH_JSON
|
|
43
|
+
model: gpt-5.3-codex
|
|
44
|
+
reasoning:
|
|
45
|
+
effort: high
|
|
46
|
+
summary: concise
|
|
47
|
+
claude_code:
|
|
48
|
+
enabled: false
|
|
49
|
+
adapter: cli-claude-code
|
|
50
|
+
# Key inside GITVIBE_AI_ENV_JSON. Stores the Claude Code OAuth access token.
|
|
51
|
+
env:
|
|
52
|
+
CLAUDE_CODE_OAUTH_TOKEN:
|
|
53
|
+
from_bundle: CLAUDE_OAUTH_TOKEN
|
|
54
|
+
model: opus
|
|
55
|
+
reasoning:
|
|
56
|
+
effort: xhigh
|
|
57
|
+
role_groups:
|
|
58
|
+
review_gate:
|
|
59
|
+
synthesizer: local_proxy
|
|
60
|
+
parallel: 2
|
|
61
|
+
roles:
|
|
62
|
+
- role: correctness.md
|
|
63
|
+
profile: local_proxy
|
|
64
|
+
- role: security.md
|
|
65
|
+
profile: local_proxy
|
|
66
|
+
- role: maintainability.md
|
|
67
|
+
profile: local_proxy
|
|
68
|
+
budgets:
|
|
69
|
+
default_timeout_minutes: 60
|
|
70
|
+
implementation_timeout_minutes: 120
|
|
71
|
+
feedback_timeout_minutes: 120
|
|
72
|
+
publish_timeout_minutes: 15
|
|
73
|
+
default_max_turns: 90
|
|
74
|
+
implementation_max_turns: 120
|
|
75
|
+
feedback_max_turns: 120
|
|
76
|
+
stages:
|
|
77
|
+
investigate:
|
|
78
|
+
role_group: review_gate
|
|
79
|
+
validate:
|
|
80
|
+
role_group: review_gate
|
|
81
|
+
decompose:
|
|
82
|
+
profile: local_proxy
|
|
83
|
+
materialize:
|
|
84
|
+
profile: local_proxy
|
|
85
|
+
review-matrix:
|
|
86
|
+
role_group: review_gate
|
|
87
|
+
implement:
|
|
88
|
+
profile: local_proxy
|
|
89
|
+
create-pr:
|
|
90
|
+
profile: local_proxy
|
|
91
|
+
address-pr-feedback:
|
|
92
|
+
profile: local_proxy
|
|
93
|
+
|
|
94
|
+
bug_investigation:
|
|
95
|
+
auto_start_on_new_bug: false
|
|
96
|
+
community_trigger:
|
|
97
|
+
enabled: false
|
|
98
|
+
reaction: "+1"
|
|
99
|
+
threshold: 6
|
|
100
|
+
eligible_labels:
|
|
101
|
+
- git-vibe:bug
|
|
102
|
+
dispatch: investigate
|
|
103
|
+
|
|
104
|
+
tests:
|
|
105
|
+
commands: []
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: GitVibe address feedback
|
|
2
|
+
run-name: "[git-vibe][address-feedback]: PR #${{ inputs.pr-number }}"
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
pr-number:
|
|
8
|
+
description: Pull request number with feedback to address.
|
|
9
|
+
required: true
|
|
10
|
+
type: string
|
|
11
|
+
dry-run:
|
|
12
|
+
description: Validate without writing to GitHub.
|
|
13
|
+
required: false
|
|
14
|
+
type: boolean
|
|
15
|
+
default: false
|
|
16
|
+
source-comment:
|
|
17
|
+
description: JSON source comment metadata for replying to command comments.
|
|
18
|
+
required: false
|
|
19
|
+
type: string
|
|
20
|
+
default: ""
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
address-feedback:
|
|
24
|
+
uses: markhuangai/git-vibe/.github/workflows/address-feedback.yml@v2
|
|
25
|
+
with:
|
|
26
|
+
pr-number: ${{ inputs.pr-number }}
|
|
27
|
+
runner: ubuntu-latest
|
|
28
|
+
timeout_minutes: 120
|
|
29
|
+
max_turns: 120
|
|
30
|
+
dry-run: ${{ inputs.dry-run }}
|
|
31
|
+
source-comment: ${{ inputs.source-comment }}
|
|
32
|
+
secrets:
|
|
33
|
+
GITVIBE_GITHUB_TOKEN: ${{ secrets.GITVIBE_GITHUB_TOKEN }}
|
|
34
|
+
GITVIBE_AI_ENV_JSON: ${{ secrets.GITVIBE_AI_ENV_JSON }}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: GitVibe decompose
|
|
2
|
+
run-name: "[git-vibe][decompose]: Discussion #${{ inputs.discussion-number }}"
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
discussion-number:
|
|
8
|
+
description: Discussion number to decompose.
|
|
9
|
+
required: true
|
|
10
|
+
type: string
|
|
11
|
+
dry-run:
|
|
12
|
+
description: Validate without writing to GitHub.
|
|
13
|
+
required: false
|
|
14
|
+
type: boolean
|
|
15
|
+
default: false
|
|
16
|
+
source-comment:
|
|
17
|
+
description: JSON source comment metadata for replying to command comments.
|
|
18
|
+
required: false
|
|
19
|
+
type: string
|
|
20
|
+
default: ""
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
decompose:
|
|
24
|
+
uses: markhuangai/git-vibe/.github/workflows/decompose.yml@v2
|
|
25
|
+
with:
|
|
26
|
+
discussion-number: ${{ inputs.discussion-number }}
|
|
27
|
+
runner: ubuntu-latest
|
|
28
|
+
timeout_minutes: 60
|
|
29
|
+
max_turns: 90
|
|
30
|
+
dry-run: ${{ inputs.dry-run }}
|
|
31
|
+
source-comment: ${{ inputs.source-comment }}
|
|
32
|
+
secrets:
|
|
33
|
+
GITVIBE_GITHUB_TOKEN: ${{ secrets.GITVIBE_GITHUB_TOKEN }}
|
|
34
|
+
GITVIBE_AI_ENV_JSON: ${{ secrets.GITVIBE_AI_ENV_JSON }}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: GitVibe develop
|
|
2
|
+
run-name: "[git-vibe][develop]: Issue #${{ inputs.issue-number }}"
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
issue-number:
|
|
8
|
+
description: Approved implementation issue number.
|
|
9
|
+
required: true
|
|
10
|
+
type: string
|
|
11
|
+
dry-run:
|
|
12
|
+
description: Validate without writing to GitHub.
|
|
13
|
+
required: false
|
|
14
|
+
type: boolean
|
|
15
|
+
default: false
|
|
16
|
+
source-comment:
|
|
17
|
+
description: JSON source comment metadata for replying to command comments.
|
|
18
|
+
required: false
|
|
19
|
+
type: string
|
|
20
|
+
default: ""
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
develop:
|
|
24
|
+
uses: markhuangai/git-vibe/.github/workflows/develop.yml@v2
|
|
25
|
+
with:
|
|
26
|
+
issue-number: ${{ inputs.issue-number }}
|
|
27
|
+
runner: ubuntu-latest
|
|
28
|
+
implementation_timeout_minutes: 120
|
|
29
|
+
review_timeout_minutes: 60
|
|
30
|
+
publish_timeout_minutes: 15
|
|
31
|
+
max_turns: 90
|
|
32
|
+
implementation_max_turns: 120
|
|
33
|
+
validation_repair_attempts: 2
|
|
34
|
+
validation_repair_max_turns: 90
|
|
35
|
+
dry-run: ${{ inputs.dry-run }}
|
|
36
|
+
source-comment: ${{ inputs.source-comment }}
|
|
37
|
+
secrets:
|
|
38
|
+
GITVIBE_GITHUB_TOKEN: ${{ secrets.GITVIBE_GITHUB_TOKEN }}
|
|
39
|
+
GITVIBE_AI_ENV_JSON: ${{ secrets.GITVIBE_AI_ENV_JSON }}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: GitVibe investigate
|
|
2
|
+
run-name: "[git-vibe][investigate]: Issue #${{ inputs.issue-number }}"
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
issue-number:
|
|
8
|
+
description: Issue number to investigate.
|
|
9
|
+
required: true
|
|
10
|
+
type: string
|
|
11
|
+
dry-run:
|
|
12
|
+
description: Validate without writing to GitHub.
|
|
13
|
+
required: false
|
|
14
|
+
type: boolean
|
|
15
|
+
default: false
|
|
16
|
+
source-comment:
|
|
17
|
+
description: JSON source comment metadata for replying to command comments.
|
|
18
|
+
required: false
|
|
19
|
+
type: string
|
|
20
|
+
default: ""
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
investigate:
|
|
24
|
+
uses: markhuangai/git-vibe/.github/workflows/investigate.yml@v2
|
|
25
|
+
with:
|
|
26
|
+
issue-number: ${{ inputs.issue-number }}
|
|
27
|
+
runner: ubuntu-latest
|
|
28
|
+
timeout_minutes: 60
|
|
29
|
+
max_turns: 90
|
|
30
|
+
dry-run: ${{ inputs.dry-run }}
|
|
31
|
+
source-comment: ${{ inputs.source-comment }}
|
|
32
|
+
secrets:
|
|
33
|
+
GITVIBE_GITHUB_TOKEN: ${{ secrets.GITVIBE_GITHUB_TOKEN }}
|
|
34
|
+
GITVIBE_AI_ENV_JSON: ${{ secrets.GITVIBE_AI_ENV_JSON }}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: GitVibe materialize
|
|
2
|
+
run-name: "[git-vibe][materialize]: Discussion #${{ inputs.discussion-number }}"
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
discussion-number:
|
|
8
|
+
description: Discussion number to materialize.
|
|
9
|
+
required: true
|
|
10
|
+
type: string
|
|
11
|
+
dry-run:
|
|
12
|
+
description: Validate without writing to GitHub.
|
|
13
|
+
required: false
|
|
14
|
+
type: boolean
|
|
15
|
+
default: false
|
|
16
|
+
source-comment:
|
|
17
|
+
description: JSON source comment metadata for replying to command comments.
|
|
18
|
+
required: false
|
|
19
|
+
type: string
|
|
20
|
+
default: ""
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
materialize:
|
|
24
|
+
uses: markhuangai/git-vibe/.github/workflows/materialize.yml@v2
|
|
25
|
+
with:
|
|
26
|
+
discussion-number: ${{ inputs.discussion-number }}
|
|
27
|
+
runner: ubuntu-latest
|
|
28
|
+
timeout_minutes: 60
|
|
29
|
+
max_turns: 90
|
|
30
|
+
dry-run: ${{ inputs.dry-run }}
|
|
31
|
+
source-comment: ${{ inputs.source-comment }}
|
|
32
|
+
secrets:
|
|
33
|
+
GITVIBE_GITHUB_TOKEN: ${{ secrets.GITVIBE_GITHUB_TOKEN }}
|
|
34
|
+
GITVIBE_AI_ENV_JSON: ${{ secrets.GITVIBE_AI_ENV_JSON }}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: GitVibe validate
|
|
2
|
+
run-name: "[git-vibe][validate]: ${{ inputs.discussion-number != '' && format('Discussion #{0}', inputs.discussion-number) || inputs.issue-number != '' && format('Issue #{0}', inputs.issue-number) || 'Artifact' }}"
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
issue-number:
|
|
8
|
+
description: Issue number to validate.
|
|
9
|
+
required: false
|
|
10
|
+
type: string
|
|
11
|
+
default: ""
|
|
12
|
+
discussion-number:
|
|
13
|
+
description: Discussion number to validate.
|
|
14
|
+
required: false
|
|
15
|
+
type: string
|
|
16
|
+
default: ""
|
|
17
|
+
dry-run:
|
|
18
|
+
description: Validate without writing to GitHub.
|
|
19
|
+
required: false
|
|
20
|
+
type: boolean
|
|
21
|
+
default: false
|
|
22
|
+
source-comment:
|
|
23
|
+
description: JSON source comment metadata for replying to command comments.
|
|
24
|
+
required: false
|
|
25
|
+
type: string
|
|
26
|
+
default: ""
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
validate:
|
|
30
|
+
uses: markhuangai/git-vibe/.github/workflows/validate.yml@v2
|
|
31
|
+
with:
|
|
32
|
+
issue-number: ${{ inputs.issue-number }}
|
|
33
|
+
discussion-number: ${{ inputs.discussion-number }}
|
|
34
|
+
runner: ubuntu-latest
|
|
35
|
+
timeout_minutes: 60
|
|
36
|
+
max_turns: 90
|
|
37
|
+
dry-run: ${{ inputs.dry-run }}
|
|
38
|
+
source-comment: ${{ inputs.source-comment }}
|
|
39
|
+
secrets:
|
|
40
|
+
GITVIBE_GITHUB_TOKEN: ${{ secrets.GITVIBE_GITHUB_TOKEN }}
|
|
41
|
+
GITVIBE_AI_ENV_JSON: ${{ secrets.GITVIBE_AI_ENV_JSON }}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"CLAUDE_OAUTH_TOKEN": "replace-with-claude-oauth-token",
|
|
3
|
+
"CODEX_AUTH_JSON": "{\"tokens\":[]}",
|
|
4
|
+
"GITVIBE_AI_API_KEY": "replace-with-ai-provider-api-key",
|
|
5
|
+
"GITVIBE_AI_BASE_URL": "https://api.provider.example/v1",
|
|
6
|
+
"MINIMAX_API_KEY": "replace-with-minimax-api-key",
|
|
7
|
+
"MINIMAX_ANTHROPIC_BASE_URL": "https://api.minimax.example/anthropic"
|
|
8
|
+
}
|