guardian-framework 0.1.73 → 0.1.74
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/helpers.ts +41 -0
- package/templates/pi/extensions/architect.ts +27 -3
- package/templates/pi/preflight_report.json +1 -1
- package/templates/pi/scripts/git/create-tracking-issue.sh +1 -1
- package/templates/pi/scripts/git/link-issue-to-epic.sh +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.74", 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.74", 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
|
@@ -105,6 +105,47 @@ export function createRemoteIssue(
|
|
|
105
105
|
return { success: false, issueNumber: null, error: "Could not parse issue number" };
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
// Create a real GitLab Epic via the glab CLI.
|
|
109
|
+
// Returns the epic IID (string) on success, null on failure.
|
|
110
|
+
export function createGitlabEpic(
|
|
111
|
+
cwd: string,
|
|
112
|
+
repository: string,
|
|
113
|
+
title: string,
|
|
114
|
+
description: string,
|
|
115
|
+
): string | null {
|
|
116
|
+
// Derive group from repository path: "group/subgroup/project" -> "group/subgroup"
|
|
117
|
+
const parts = repository.split("/");
|
|
118
|
+
if (parts.length < 2) return null;
|
|
119
|
+
const group = parts.slice(0, -1).join("/");
|
|
120
|
+
|
|
121
|
+
// Build description from markdown content (strip YAML frontmatter)
|
|
122
|
+
const desc = description.replace(/^---[\s\S]*?---\n*/, "").trim();
|
|
123
|
+
|
|
124
|
+
// Create epic via glab CLI
|
|
125
|
+
const result = runScript(
|
|
126
|
+
cwd,
|
|
127
|
+
`glab epic create --group "${group}" --title "${title}" --description "${desc.slice(0, 5000)}" 2>&1`,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
if (result.exitCode !== 0) {
|
|
131
|
+
// Fallback: try the API directly
|
|
132
|
+
const body = JSON.stringify({ title, description: desc.slice(0, 5000) });
|
|
133
|
+
const apiResult = runScript(
|
|
134
|
+
cwd,
|
|
135
|
+
`glab api --method POST "groups/${group}/epics" --body '${body}' 2>/dev/null | jq -r '.iid // empty'`,
|
|
136
|
+
);
|
|
137
|
+
if (apiResult.exitCode !== 0 || !apiResult.stdout.trim()) {
|
|
138
|
+
console.warn(`Failed to create GitLab epic: ${result.stdout || apiResult.stdout}`);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return apiResult.stdout.trim();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Parse epic IID from output: "https://gitlab.com/groups/.../-/epics/42"
|
|
145
|
+
const epicMatch = result.stdout.match(/epics\/(\d+)/);
|
|
146
|
+
return epicMatch ? epicMatch[1] : null;
|
|
147
|
+
}
|
|
148
|
+
|
|
108
149
|
// Ensure the GitHub/GitLab repository exists and local git remote is configured.
|
|
109
150
|
// Returns the repository slug if remote is ready, empty string if not available.
|
|
110
151
|
export function ensureRemoteRepo(
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
readRepoTool,
|
|
29
29
|
runScript,
|
|
30
30
|
saveRoadmapState,
|
|
31
|
+
createGitlabEpic,
|
|
31
32
|
} from "./architect-lib/helpers";
|
|
32
33
|
import {
|
|
33
34
|
generateArchitectureReadinessMarkdown,
|
|
@@ -306,25 +307,48 @@ class EpicManager {
|
|
|
306
307
|
if (tdd) {
|
|
307
308
|
const language = readLanguage(this.cwd);
|
|
308
309
|
if (isTddSupported(language)) {
|
|
309
|
-
tddTestFiles
|
|
310
|
+
tddTestFiles.push(...generateEpicTestFiles({
|
|
310
311
|
components: slice.nextLogicalSlice,
|
|
311
312
|
moduleId: slice.module,
|
|
312
313
|
cwd: this.cwd,
|
|
313
314
|
language,
|
|
314
|
-
});
|
|
315
|
+
}));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// ── GitLab Epic creation (only for GitLab repos with remote access) ──
|
|
320
|
+
let effectiveEpicId: string | null = null;
|
|
321
|
+
if (repoTool === "glab" && hasRemote && remoteRepo) {
|
|
322
|
+
const epicTitle = `Epic: ${name} — ${slice.module}`;
|
|
323
|
+
const epicDesc = [
|
|
324
|
+
`# ${epicTitle}`,
|
|
325
|
+
"",
|
|
326
|
+
`**Module:** ${slice.module}`,
|
|
327
|
+
`**Components:** ${slice.nextLogicalSlice.length}`,
|
|
328
|
+
"",
|
|
329
|
+
"## Issues",
|
|
330
|
+
...issues.map((i) => `- ${i.title}${i.remoteIssueId ? ` (#${i.remoteIssueId})` : ""}`),
|
|
331
|
+
"",
|
|
332
|
+
"---",
|
|
333
|
+
"Auto-generated by Guardian Architect",
|
|
334
|
+
].join("\n");
|
|
335
|
+
effectiveEpicId = createGitlabEpic(this.cwd, remoteRepo, epicTitle, epicDesc);
|
|
336
|
+
if (effectiveEpicId) {
|
|
337
|
+
console.warn(`Created GitLab epic #${effectiveEpicId}`);
|
|
315
338
|
}
|
|
316
339
|
}
|
|
317
340
|
|
|
318
341
|
const state: EpicState = {
|
|
319
342
|
name,
|
|
320
343
|
trackingIssueId: effectiveTrackingId,
|
|
321
|
-
epicId:
|
|
344
|
+
epicId: effectiveEpicId,
|
|
322
345
|
slices: [slice],
|
|
323
346
|
issues,
|
|
324
347
|
status: "planning",
|
|
325
348
|
currentIssueIndex: 0,
|
|
326
349
|
createdAt: new Date().toISOString(),
|
|
327
350
|
tdd,
|
|
351
|
+
tddTestFiles,
|
|
328
352
|
};
|
|
329
353
|
|
|
330
354
|
this.state = state;
|
|
@@ -163,7 +163,7 @@ case "$PLATFORM" in
|
|
|
163
163
|
|
|
164
164
|
# Try to add labels separately (non-fatal)
|
|
165
165
|
if [[ -n "$LABELS" && -n "$ISSUE_NUMBER" ]]; then
|
|
166
|
-
glab issue update "$ISSUE_NUMBER" --label "$LABELS" 2>/dev/null || true
|
|
166
|
+
glab issue update "$ISSUE_NUMBER" --label "$LABELS" ${REPO:+--repo "$REPO"} 2>/dev/null || true
|
|
167
167
|
fi
|
|
168
168
|
|
|
169
169
|
echo "TRACKING_ID=$ISSUE_NUMBER"
|
|
@@ -57,7 +57,7 @@ Relates to #$EPIC_ID" 2>/dev/null
|
|
|
57
57
|
# API: POST /groups/:group/epics/:epic_iid/issues/:issue_iid
|
|
58
58
|
# Derive group from repository path: "group/subgroup/project" -> "group/subgroup"
|
|
59
59
|
if [[ -n "$REPO" ]]; then
|
|
60
|
-
|
|
60
|
+
group_path=$(echo "$REPO" | rev | cut -d'/' -f2- | rev)
|
|
61
61
|
if [[ -n "$group_path" ]]; then
|
|
62
62
|
glab api --method POST "groups/$group_path/epics/$EPIC_ID/issues/$ISSUE_ID" 2>/dev/null && {
|
|
63
63
|
echo "Linked GitLab issue #$ISSUE_ID to epic #$EPIC_ID"
|