git-vibe-setup 3.1.1 → 4.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/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import { pathToFileURL } from "node:url";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { fetchConsumerStarterFiles } from "./consumer-starter.js";
7
7
  import { githubTokenFromEnvironment } from "./github-api.js";
8
- import { blockingInstallPaths, buildInstallFiles, buildWorkflowUpdateFiles, existingFilesError, installFiles, unmanagedWorkflowUpdateError, unmanagedWorkflowUpdatePaths, updateFiles, } from "./install.js";
8
+ import { blockingInstallPaths, buildInstallFiles, buildUpdateFiles, existingFilesError, installFiles, unmanagedWorkflowUpdateError, unmanagedWorkflowUpdatePaths, updateFiles, } from "./install.js";
9
9
  import { renderManualSetupInstructions } from "./instructions.js";
10
10
  import { latestReleaseTag } from "./releases.js";
11
11
  const usage = `Usage:
@@ -40,12 +40,12 @@ export async function runUpdate(runtime = {}) {
40
40
  const githubToken = runtime.githubToken || githubTokenFromEnvironment();
41
41
  const releaseTag = await resolveReleaseTag(runtime, fetchImpl, githubToken);
42
42
  const sourceFiles = await fetchConsumerStarterFiles({ fetchImpl, githubToken, releaseTag });
43
- const files = buildWorkflowUpdateFiles({ cwd, releaseTag, sourceFiles });
43
+ const files = buildUpdateFiles({ cwd, releaseTag, sourceFiles });
44
44
  const unmanagedPaths = unmanagedWorkflowUpdatePaths(files);
45
45
  if (unmanagedPaths.length > 0)
46
46
  throw unmanagedWorkflowUpdateError(unmanagedPaths, cwd);
47
47
  updateFiles(files);
48
- (runtime.log || console.log)(`GitVibe workflow files updated with reusable workflows pinned to ${releaseTag}.`);
48
+ (runtime.log || console.log)(`GitVibe config and workflow files updated with reusable workflows pinned to ${releaseTag}.`);
49
49
  }
50
50
  export async function setupCli(runtime = {}) {
51
51
  const argv = runtime.argv || process.argv.slice(2);
package/dist/install.d.ts CHANGED
@@ -9,7 +9,7 @@ export declare function buildInstallFiles(options: {
9
9
  releaseTag: string;
10
10
  sourceFiles: ConsumerStarterFile[];
11
11
  }): InstallFile[];
12
- export declare function buildWorkflowUpdateFiles(options: {
12
+ export declare function buildUpdateFiles(options: {
13
13
  cwd: string;
14
14
  releaseTag: string;
15
15
  sourceFiles: ConsumerStarterFile[];
@@ -21,3 +21,4 @@ export declare function updateFiles(files: InstallFile[]): void;
21
21
  export declare function existingFilesError(paths: string[], cwd: string): Error;
22
22
  export declare function unmanagedWorkflowUpdateError(paths: string[], cwd: string): Error;
23
23
  export declare function pinWorkflowReleaseRefs(content: string, releaseTag: string): string;
24
+ export declare function migrateGitVibeConfigContent(content: string): string;
package/dist/install.js CHANGED
@@ -13,17 +13,18 @@ const requiredInstallSourcePaths = [
13
13
  ".git-vibe/role-group/security.md",
14
14
  ];
15
15
  const requiredWorkflowSourcePaths = requiredInstallSourcePaths.filter(isWorkflowSourcePath);
16
+ const requiredUpdateSourcePaths = [".github/git-vibe.yml", ...requiredWorkflowSourcePaths];
16
17
  export function buildInstallFiles(options) {
17
18
  requireSourcePaths(options.sourceFiles, requiredInstallSourcePaths, options.releaseTag);
18
19
  return options.sourceFiles
19
20
  .filter((file) => isInstallSourcePath(file.relativePath))
20
21
  .map((file) => buildInstallFile(file, options.cwd, options.releaseTag));
21
22
  }
22
- export function buildWorkflowUpdateFiles(options) {
23
- requireSourcePaths(options.sourceFiles, requiredWorkflowSourcePaths, options.releaseTag);
23
+ export function buildUpdateFiles(options) {
24
+ requireSourcePaths(options.sourceFiles, requiredUpdateSourcePaths, options.releaseTag);
24
25
  return options.sourceFiles
25
- .filter((file) => isWorkflowSourcePath(file.relativePath))
26
- .map((file) => buildInstallFile(file, options.cwd, options.releaseTag));
26
+ .filter((file) => isUpdateSourcePath(file.relativePath))
27
+ .map((file) => buildUpdateFile(file, options.cwd, options.releaseTag));
27
28
  }
28
29
  export function blockingInstallPaths(files) {
29
30
  return files
@@ -33,6 +34,7 @@ export function blockingInstallPaths(files) {
33
34
  }
34
35
  export function unmanagedWorkflowUpdatePaths(files) {
35
36
  return files
37
+ .filter(isWorkflowInstallFile)
36
38
  .filter((file) => existsSync(file.targetPath) && !isManagedWorkflowTarget(file))
37
39
  .map((file) => file.targetPath)
38
40
  .sort();
@@ -78,6 +80,10 @@ export function unmanagedWorkflowUpdateError(paths, cwd) {
78
80
  export function pinWorkflowReleaseRefs(content, releaseTag) {
79
81
  return content.replace(/(uses:\s*markhuangai\/git-vibe\/\.github\/workflows\/[^\s@]+)@[^\s]+/g, (_match, workflowReference) => `${workflowReference}@${releaseTag}`);
80
82
  }
83
+ export function migrateGitVibeConfigContent(content) {
84
+ const migratedComments = migrateLegacyEventDeliveryComments(content);
85
+ return ensureTrailingNewline(migrateGithubAuthConfig(migratedComments));
86
+ }
81
87
  function isManagedWorkflowTarget(file) {
82
88
  try {
83
89
  const workflowName = basename(file.targetPath);
@@ -150,6 +156,22 @@ function buildInstallFile(sourceFile, cwd, releaseTag) {
150
156
  targetPath: join(cwd, safeRelativePath(sourceFile.relativePath)),
151
157
  };
152
158
  }
159
+ function buildUpdateFile(sourceFile, cwd, releaseTag) {
160
+ const targetPath = join(cwd, safeRelativePath(sourceFile.relativePath));
161
+ const existingContent = fileContentIfExists(targetPath);
162
+ let content = pinWorkflowReleaseRefs(sourceFile.content, releaseTag);
163
+ if (sourceFile.relativePath === ".github/git-vibe.yml" && existingContent !== undefined) {
164
+ content = migrateGitVibeConfigContent(existingContent);
165
+ }
166
+ else if (isWorkflowSourcePath(sourceFile.relativePath) && existingContent !== undefined) {
167
+ content = preserveWorkflowRunner(content, existingContent);
168
+ }
169
+ return {
170
+ content,
171
+ sourcePath: sourceFile.sourcePath,
172
+ targetPath,
173
+ };
174
+ }
153
175
  function requireSourcePaths(sourceFiles, requiredPaths, releaseTag) {
154
176
  const sourcePaths = new Set(sourceFiles.map((file) => file.relativePath));
155
177
  const missingPaths = requiredPaths.filter((path) => !sourcePaths.has(path));
@@ -161,9 +183,15 @@ function requireSourcePaths(sourceFiles, requiredPaths, releaseTag) {
161
183
  function isInstallSourcePath(relativePath) {
162
184
  return relativePath.startsWith(".github/") || relativePath.startsWith(".git-vibe/");
163
185
  }
186
+ function isUpdateSourcePath(relativePath) {
187
+ return relativePath === ".github/git-vibe.yml" || isWorkflowSourcePath(relativePath);
188
+ }
164
189
  function isWorkflowSourcePath(relativePath) {
165
190
  return relativePath.startsWith(".github/workflows/") && relativePath.endsWith(".yml");
166
191
  }
192
+ function isWorkflowInstallFile(file) {
193
+ return file.sourcePath.includes(".github/workflows/") && file.sourcePath.endsWith(".yml");
194
+ }
167
195
  function safeRelativePath(relativePath) {
168
196
  const segments = relativePath.split("/");
169
197
  const isSafe = relativePath.length > 0 &&
@@ -174,3 +202,27 @@ function safeRelativePath(relativePath) {
174
202
  return relativePath;
175
203
  throw new Error(`git-vibe-setup found an unsafe starter file path: ${relativePath}`);
176
204
  }
205
+ function fileContentIfExists(targetPath) {
206
+ if (!existsSync(targetPath))
207
+ return undefined;
208
+ return readFileSync(targetPath, "utf8");
209
+ }
210
+ function preserveWorkflowRunner(generatedContent, existingContent) {
211
+ const runner = /^\s+runner:\s*(.+)$/m.exec(existingContent)?.[1];
212
+ if (!runner)
213
+ return generatedContent;
214
+ return generatedContent.replace(/^(\s+runner:\s*).+$/m, `$1${runner}`);
215
+ }
216
+ function migrateLegacyEventDeliveryComments(content) {
217
+ return content.replace(/^event_delivery:\n # webhook: repository webhook points at the self-hosted GitVibe server\.\n # relay: webhook proxy\/tunnel such as Smee, Hookdeck, Cloudflare Tunnel, or ngrok\.\n # actions: no-server receiver workflows in the consumer repository\.\n # polling: local\/scheduled worker polls GitHub APIs with cursors\/ETags\.\n/m, "event_delivery:\n # Hosted GitHub App installs configure webhooks centrally; repositories do not create hooks.\n");
218
+ }
219
+ function migrateGithubAuthConfig(content) {
220
+ const githubAppAuth = "github_auth:\n mode: github-app\n";
221
+ if (/^github_auth:\n/m.test(content)) {
222
+ return content.replace(/^github_auth:\n(?:[ \t]+.*(?:\n|$))*/m, githubAppAuth);
223
+ }
224
+ return `${content.trimEnd()}\n\n${githubAppAuth}`;
225
+ }
226
+ function ensureTrailingNewline(content) {
227
+ return content.endsWith("\n") ? content : `${content}\n`;
228
+ }
@@ -1,7 +1,5 @@
1
1
  const requiredSecrets = [
2
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
3
  ];
6
4
  const usefulVariables = [
7
5
  "GITVIBE_BASE_BRANCH",
@@ -13,8 +11,9 @@ export function renderManualSetupInstructions(releaseTag) {
13
11
  const lines = [
14
12
  `GitVibe starter files installed with reusable workflows pinned to ${releaseTag}.`,
15
13
  "",
16
- "Configure these GitHub secrets manually before running the workflows:",
14
+ "Configure this GitHub secret manually before running the workflows:",
17
15
  ...requiredSecrets.map(([name, description]) => `- ${name}: ${description}`),
16
+ "- GITVIBE_MCP_ENV_JSON: optional JSON env bundle for MCP credentials.",
18
17
  "",
19
18
  "Optional repository variables:",
20
19
  ...usefulVariables.map((name) => `- ${name}`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-vibe-setup",
3
- "version": "3.1.1",
3
+ "version": "4.0.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {