@bytesbrains/pi-project-gate 1.2.1 → 1.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Project Gate for Pi
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/pi-project-gate)](https://www.npmjs.com/package/pi-project-gate)
4
- [![license](https://img.shields.io/npm/l/pi-project-gate)](./LICENSE)
3
+ [![npm version](https://img.shields.io/npm/v/@bytesbrains/pi-project-gate)](https://www.npmjs.com/package/@bytesbrains/pi-project-gate)
4
+ [![license](https://img.shields.io/npm/l/@bytesbrains/pi-project-gate)](./LICENSE)
5
5
 
6
6
  > Project orchestration gate for AI agents — structured issues, WIP limits, dependency blocking, and auto-generated release notes. **Agents work from issues, not vibes.**
7
7
 
@@ -14,7 +14,7 @@
14
14
  ## Install
15
15
 
16
16
  ```bash
17
- pi install npm:pi-project-gate
17
+ pi install npm:@bytesbrains/pi-project-gate
18
18
  ```
19
19
 
20
20
  ## Tools
@@ -122,9 +122,9 @@ Example output:
122
122
  Install all three gates for full agent governance:
123
123
 
124
124
  ```bash
125
- pi install npm:pi-contrib-gate
126
- pi install npm:pi-review-gate
127
- pi install npm:pi-project-gate
125
+ pi install npm:@bytesbrains/pi-contrib-gate
126
+ pi install npm:@bytesbrains/pi-review-gate
127
+ pi install npm:@bytesbrains/pi-project-gate
128
128
  ```
129
129
 
130
130
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytesbrains/pi-project-gate",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Project orchestration gate for AI agents \u2014 structured issues, WIP limits, dependency blocking, and auto-generated release notes.",
5
5
  "keywords": [
6
6
  "pi-package",
package/src/config.ts CHANGED
@@ -41,8 +41,9 @@ export function loadConfig(cwd: string): ProjectConfig {
41
41
  result[m[1]] = val;
42
42
  }
43
43
  }
44
+ const maxWip = parseInt(result["maxWip"] as string);
44
45
  return {
45
- maxWip: parseInt(result["maxWip"] as string) || DEFAULT_CONFIG.maxWip,
46
+ maxWip: isNaN(maxWip) ? DEFAULT_CONFIG.maxWip : maxWip,
46
47
  requiredSections: (result["requiredSections"] as string)?.split(",").map(s => s.trim()).filter(Boolean) || DEFAULT_CONFIG.requiredSections,
47
48
  complexityLevels: (result["complexityLevels"] as string)?.split(",").map(s => s.trim()).filter(Boolean) || DEFAULT_CONFIG.complexityLevels,
48
49
  areas: (result["areas"] as string)?.split(",").map(s => s.trim()).filter(Boolean) || [],
package/src/helpers.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as cp from "node:child_process";
2
2
 
3
+ // ⚠️ SYNC-MARKER: exec(), resolveGitea(), giteaApi() are duplicated across packages.
4
+ // If changing behavior here, update all copies in: ci-gate, contrib-gate, review-gate, project-gate
3
5
  export function exec(cmd: string, cwd?: string): { ok: boolean; stdout: string; stderr: string } {
4
6
  try { const r = cp.execSync(cmd, { cwd, encoding: "utf-8", timeout: 30000 }); return { ok: true, stdout: r.trim(), stderr: "" }; }
5
7
  catch (e: any) { return { ok: false, stdout: e.stdout?.trim() || "", stderr: e.stderr?.trim() || e.message }; }
@@ -16,10 +18,10 @@ export function resolveGitea(cwd: string): { repo: string; token: string } {
16
18
  return { repo, token: credMatch ? credMatch[2] : "" };
17
19
  }
18
20
 
19
- export async function giteaApi(path: string, method: string, body: Record<string, unknown> | null, opts: { repo: string; token?: string }, _cwd: string): Promise<{ ok: boolean; data: unknown; error?: string }> {
21
+ export async function giteaApi(path: string, method: string, body: Record<string, unknown> | null, opts: { repo: string; token?: string }, _cwd: string): Promise<{ ok: boolean; data: unknown; error?: string; statusCode?: number }> {
20
22
  const base = `http://127.0.0.1:3001/api/v1/repos/${opts.repo}`;
21
23
  const url = `${base}${path}`;
22
- const headers: Record<string, string> = { "Content-Type": "application/json" };
24
+ const headers: Record<string, string> = { "Content-Type": "application/json", "Accept": "application/json" };
23
25
  if (opts.token) headers["Authorization"] = `token ${opts.token}`;
24
26
 
25
27
  try {
@@ -29,11 +31,11 @@ export async function giteaApi(path: string, method: string, body: Record<string
29
31
  body: body ? JSON.stringify(body) : undefined,
30
32
  });
31
33
  const text = await res.text();
34
+ const statusCode = res.status;
32
35
  if (!res.ok) {
33
- const lines = text.split("\n");
34
- return { ok: false, data: null, error: text || lines.slice(0, -1).join("\n") || "API error" };
36
+ return { ok: false, data: null, statusCode, error: `Gitea API error: HTTP ${statusCode} ${method} ${path}` };
35
37
  }
36
- try { return { ok: true, data: JSON.parse(text) }; } catch { return { ok: true, data: text }; }
38
+ try { return { ok: true, data: JSON.parse(text), statusCode }; } catch { return { ok: true, data: text, statusCode }; }
37
39
  } catch (e: any) {
38
40
  return { ok: false, data: null, error: e.message || "Network error" };
39
41
  }