guardian-framework 0.1.74 → 0.1.75
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 +1 -1
- package/dist/exports.js +1 -1
- package/package.json +1 -1
- package/templates/pi/extensions/architect-lib/forge-adapter.ts +11 -1
- package/templates/pi/extensions/architect-lib/helpers.ts +22 -7
- package/templates/pi/extensions/architect.ts +11 -1
- package/templates/pi/preflight_report.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3197,7 +3197,7 @@ __export(exports_package, {
|
|
|
3197
3197
|
bin: () => bin,
|
|
3198
3198
|
author: () => author
|
|
3199
3199
|
});
|
|
3200
|
-
var name = "guardian-framework", version = "0.1.
|
|
3200
|
+
var name = "guardian-framework", version = "0.1.75", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
|
|
3201
3201
|
var init_package = __esm(() => {
|
|
3202
3202
|
exports = {
|
|
3203
3203
|
".": {
|
package/dist/exports.js
CHANGED
|
@@ -1982,7 +1982,7 @@ __export(exports_package, {
|
|
|
1982
1982
|
bin: () => bin,
|
|
1983
1983
|
author: () => author
|
|
1984
1984
|
});
|
|
1985
|
-
var name = "guardian-framework", version = "0.1.
|
|
1985
|
+
var name = "guardian-framework", version = "0.1.75", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
|
|
1986
1986
|
var init_package = __esm(() => {
|
|
1987
1987
|
exports = {
|
|
1988
1988
|
".": {
|
package/package.json
CHANGED
|
@@ -72,6 +72,15 @@ export function readLanguage(cwd: string): string {
|
|
|
72
72
|
return "typescript";
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* URL-encode a GitLab project/group path for API calls.
|
|
77
|
+
* GitLab API requires nested paths to be URL-encoded:
|
|
78
|
+
* "group/subgroup/project" -> "group%2Fsubgroup%2Fproject"
|
|
79
|
+
*/
|
|
80
|
+
export function glabEncodePath(rawPath: string): string {
|
|
81
|
+
return encodeURIComponent(rawPath);
|
|
82
|
+
}
|
|
83
|
+
|
|
75
84
|
/**
|
|
76
85
|
* Get forge base URL. For GitLab, detects self-hosted instances via glab config.
|
|
77
86
|
*/
|
|
@@ -142,10 +151,11 @@ export function verifyForgeAccess(cwd: string): { authenticated: boolean; projec
|
|
|
142
151
|
|
|
143
152
|
// Verify project-level access
|
|
144
153
|
if (repository) {
|
|
154
|
+
const encodedRepo = repoTool === "glab" ? glabEncodePath(repository) : repository;
|
|
145
155
|
const projectCheck = runScript(
|
|
146
156
|
cwd,
|
|
147
157
|
repoTool === "glab"
|
|
148
|
-
? `glab api "projects/${
|
|
158
|
+
? `glab api "projects/${encodedRepo}" --method GET 2>/dev/null | jq -r '.id // empty'`
|
|
149
159
|
: `gh api "repos/${repository}" --method GET 2>/dev/null | jq -r '.id // empty'`,
|
|
150
160
|
);
|
|
151
161
|
if (projectCheck.exitCode === 0 && projectCheck.stdout.trim().length > 0) {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
commandExists as adapterCommandExists,
|
|
11
11
|
runScript as adapterRunScript,
|
|
12
12
|
verifyForgeAccess,
|
|
13
|
+
glabEncodePath,
|
|
13
14
|
} from "./forge-adapter.ts";
|
|
14
15
|
// ── Constants ──
|
|
15
16
|
|
|
@@ -128,11 +129,12 @@ export function createGitlabEpic(
|
|
|
128
129
|
);
|
|
129
130
|
|
|
130
131
|
if (result.exitCode !== 0) {
|
|
131
|
-
// Fallback: try the API directly
|
|
132
|
+
// Fallback: try the API directly (URL-encode nested group paths)
|
|
133
|
+
const encodedGroup = glabEncodePath(group);
|
|
132
134
|
const body = JSON.stringify({ title, description: desc.slice(0, 5000) });
|
|
133
135
|
const apiResult = runScript(
|
|
134
136
|
cwd,
|
|
135
|
-
`glab api --method POST "groups/${
|
|
137
|
+
`glab api --method POST "groups/${encodedGroup}/epics" --body '${body}' 2>/dev/null | jq -r '.iid // empty'`,
|
|
136
138
|
);
|
|
137
139
|
if (apiResult.exitCode !== 0 || !apiResult.stdout.trim()) {
|
|
138
140
|
console.warn(`Failed to create GitLab epic: ${result.stdout || apiResult.stdout}`);
|
|
@@ -197,15 +199,28 @@ export function ensureRemoteRepo(
|
|
|
197
199
|
|
|
198
200
|
// GitLab path — detect self-hosted base URL from glab config
|
|
199
201
|
const glabBaseUrl = getGitBaseUrl("glab");
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
)
|
|
202
|
+
|
|
203
|
+
// Split repository path into group + project name for glab CLI
|
|
204
|
+
const parts = repository.split("/");
|
|
205
|
+
const projectName = parts.pop()!;
|
|
206
|
+
const group = parts.join("/");
|
|
207
|
+
|
|
208
|
+
const createResult = group
|
|
209
|
+
? runScript(
|
|
210
|
+
cwd,
|
|
211
|
+
`glab repo create "${projectName}" --group "${group}" --private --description "Epic: ${epicName}" 2>&1`,
|
|
212
|
+
)
|
|
213
|
+
: runScript(
|
|
214
|
+
cwd,
|
|
215
|
+
`glab repo create "${repository}" --private --description "Epic: ${epicName}" 2>&1`,
|
|
216
|
+
);
|
|
217
|
+
|
|
204
218
|
if (createResult.exitCode !== 0) {
|
|
205
219
|
// Repo may already exist — verify via API before giving up
|
|
220
|
+
const encodedPath = glabEncodePath(repository);
|
|
206
221
|
const viewResult = runScript(
|
|
207
222
|
cwd,
|
|
208
|
-
`glab api "projects/${
|
|
223
|
+
`glab api "projects/${encodedPath}" --method GET 2>/dev/null | jq -r '.id // empty'`,
|
|
209
224
|
);
|
|
210
225
|
if (viewResult.exitCode !== 0 || !viewResult.stdout.trim()) {
|
|
211
226
|
console.warn(`Failed to create or find GitLab project: ${createResult.stdout}`);
|
|
@@ -176,6 +176,16 @@ class EpicManager {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
// Loud warning if GitLab remote setup failed
|
|
180
|
+
if (repoTool === "glab" && !hasRemote) {
|
|
181
|
+
console.warn(
|
|
182
|
+
"⚠️ GitLab remote repo setup failed. Pipeline will run LOCAL-ONLY."
|
|
183
|
+
+ " Issues will be created as local .md files, not on GitLab."
|
|
184
|
+
+ " Check that the repository path in guardian-manifest.json exists"
|
|
185
|
+
+ " and your GitLab token has 'write_repository' scope.",
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
179
189
|
const issues: { id: string; title: string; status: string; remoteIssueId?: string | null }[] = [];
|
|
180
190
|
const issuesDir = join(this.cwd, ".pi/issues");
|
|
181
191
|
if (!existsSync(issuesDir)) mkdirSync(issuesDir, { recursive: true });
|
|
@@ -303,7 +313,7 @@ class EpicManager {
|
|
|
303
313
|
issues.push(readinessEntry);
|
|
304
314
|
|
|
305
315
|
// ── TDD test generation ──
|
|
306
|
-
|
|
316
|
+
const tddTestFiles: string[] = [];
|
|
307
317
|
if (tdd) {
|
|
308
318
|
const language = readLanguage(this.cwd);
|
|
309
319
|
if (isTddSupported(language)) {
|