guardian-framework 0.1.155 → 0.1.156
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
|
@@ -3206,7 +3206,7 @@ __export(exports_package, {
|
|
|
3206
3206
|
bin: () => bin,
|
|
3207
3207
|
author: () => author
|
|
3208
3208
|
});
|
|
3209
|
-
var name = "guardian-framework", version = "0.1.
|
|
3209
|
+
var name = "guardian-framework", version = "0.1.156", 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;
|
|
3210
3210
|
var init_package = __esm(() => {
|
|
3211
3211
|
exports = {
|
|
3212
3212
|
".": {
|
package/dist/exports.js
CHANGED
|
@@ -1991,7 +1991,7 @@ __export(exports_package, {
|
|
|
1991
1991
|
bin: () => bin,
|
|
1992
1992
|
author: () => author
|
|
1993
1993
|
});
|
|
1994
|
-
var name = "guardian-framework", version = "0.1.
|
|
1994
|
+
var name = "guardian-framework", version = "0.1.156", 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;
|
|
1995
1995
|
var init_package = __esm(() => {
|
|
1996
1996
|
exports = {
|
|
1997
1997
|
".": {
|
package/package.json
CHANGED
|
@@ -58,6 +58,16 @@ RUNNER="$ROOT/.pi/scripts/epic-runner.mjs"
|
|
|
58
58
|
[ -f "$RUNNER" ] || { echo "missing $RUNNER — run guardian update" >&2; exit 1; }
|
|
59
59
|
|
|
60
60
|
# The runner is a Node script; bun also executes it.
|
|
61
|
+
# The project directory is the one that owns .pi/ (this script lives in
|
|
62
|
+
# <project>/.pi/scripts). It is NOT necessarily the git top level: a monorepo
|
|
63
|
+
# often keeps the app in <repo>/backend with .pi/ inside it. Agents must run in
|
|
64
|
+
# the project dir, otherwise pi finds no extensions and /architect is not a
|
|
65
|
+
# command at all.
|
|
66
|
+
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
67
|
+
GIT_TOP="$(git -C "$PROJECT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$PROJECT_DIR")"
|
|
68
|
+
PROJECT_REL="${PROJECT_DIR#"$GIT_TOP"}"
|
|
69
|
+
PROJECT_REL="${PROJECT_REL#/}"
|
|
70
|
+
|
|
61
71
|
NODE_BIN="$(command -v node || command -v bun || true)"
|
|
62
72
|
if [ -z "$NODE_BIN" ]; then
|
|
63
73
|
echo "neither node nor bun found — required to spawn headless agents" >&2
|
|
@@ -158,6 +168,17 @@ while IFS= read -r modline; do
|
|
|
158
168
|
[ -n "$modline" ] && MODULES+=("$modline")
|
|
159
169
|
done <<<"$SELECTED"
|
|
160
170
|
|
|
171
|
+
# ── Pre-flight: the spawned agents inherit THIS project's .pi/ ──────────────
|
|
172
|
+
# Without extensions, /architect is not a command: the prompt falls through to
|
|
173
|
+
# the model, which then improvises (expensive and wrong). Fail before spawning.
|
|
174
|
+
if [ "$NO_SPAWN" -eq 0 ] && [ "$DRY_RUN" -eq 0 ]; then
|
|
175
|
+
if [ ! -d "$PROJECT_DIR/.pi/extensions" ]; then
|
|
176
|
+
echo "⛔ $PROJECT_DIR/.pi/extensions is missing — the agent would have no /architect command." >&2
|
|
177
|
+
echo " Run guardian update in $PROJECT_DIR, or use --no-spawn." >&2
|
|
178
|
+
exit 1
|
|
179
|
+
fi
|
|
180
|
+
fi
|
|
181
|
+
|
|
161
182
|
echo "============================================"
|
|
162
183
|
echo " Parallel epic fan-out"
|
|
163
184
|
echo "============================================"
|
|
@@ -388,15 +409,23 @@ for m in ${MODULES[@]+"${MODULES[@]}"}; do
|
|
|
388
409
|
echo " ✓ worktree $WT"
|
|
389
410
|
|
|
390
411
|
if [ "$NO_SPAWN" -eq 1 ]; then
|
|
391
|
-
echo " → run: cd \"$WT\" && /architect --epic \"$m\"$( [ "$TDD" -eq 1 ] && echo " --tdd")"
|
|
412
|
+
echo " → run: cd \"$WT${PROJECT_REL:+/$PROJECT_REL}\" && /architect --epic \"$m\"$( [ "$TDD" -eq 1 ] && echo " --tdd")"
|
|
392
413
|
STARTED+=("$m")
|
|
393
414
|
continue
|
|
394
415
|
fi
|
|
395
416
|
|
|
396
417
|
# 3. spawn one headless agent in the worktree (RPC mode dispatches the command)
|
|
418
|
+
# cwd must be the PROJECT dir inside the worktree (where .pi/ lives).
|
|
419
|
+
SPAWN_CWD="$WT"
|
|
420
|
+
[ -n "$PROJECT_REL" ] && SPAWN_CWD="$WT/$PROJECT_REL"
|
|
421
|
+
if [ ! -d "$SPAWN_CWD/.pi/extensions" ]; then
|
|
422
|
+
echo " ✗ $SPAWN_CWD/.pi/extensions missing — refusing to spawn a blind agent"
|
|
423
|
+
FAILED+=("$m")
|
|
424
|
+
continue
|
|
425
|
+
fi
|
|
397
426
|
"$NODE_BIN" "$RUNNER" \
|
|
398
427
|
"/architect --epic \"$m\"$( [ "$TDD" -eq 1 ] && echo " --tdd")" \
|
|
399
|
-
--cwd "$
|
|
428
|
+
--cwd "$SPAWN_CWD" --log "$log" ${TIMEOUT_MS:+--timeout-ms "$TIMEOUT_MS"} \
|
|
400
429
|
>/dev/null 2>&1 &
|
|
401
430
|
PID=$!
|
|
402
431
|
bash "$REGISTRY" set "$m" "pid=$PID" "log=$log" "spawnedAt=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >/dev/null 2>&1
|
|
@@ -115,9 +115,32 @@ function handleLine(line) {
|
|
|
115
115
|
// The prompt was accepted by an extension command?
|
|
116
116
|
if (msg.type === "response" && msg.command === "prompt" && msg.success === true) {
|
|
117
117
|
const d = msg.data?.disposition;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
// "handled" = an extension command consumed it (what we need).
|
|
119
|
+
// "started"/"queued" = it went to the MODEL. For a /command that means
|
|
120
|
+
// the extension was not loaded (wrong cwd, missing .pi/extensions) — the
|
|
121
|
+
// model then improvises the workflow, which looks like success and burns
|
|
122
|
+
// tokens. Treat that as a hard error.
|
|
123
|
+
const isCommand = opts.command.startsWith("/");
|
|
124
|
+
if (d === "handled") {
|
|
125
|
+
handled = true;
|
|
126
|
+
armGrace();
|
|
127
|
+
} else if (isCommand) {
|
|
128
|
+
emit(
|
|
129
|
+
JSON.stringify({
|
|
130
|
+
type: "runner_error",
|
|
131
|
+
reason: "command_not_dispatched",
|
|
132
|
+
detail:
|
|
133
|
+
`'${opts.command.split(/\s+/)[0]}' was routed to the model ` +
|
|
134
|
+
`(disposition "${d}") — the extension is not loaded in ${opts.cwd}. ` +
|
|
135
|
+
"Check that .pi/extensions exists in that directory.",
|
|
136
|
+
}),
|
|
137
|
+
);
|
|
138
|
+
failed = true;
|
|
139
|
+
finish(3);
|
|
140
|
+
} else {
|
|
141
|
+
handled = true;
|
|
142
|
+
armGrace();
|
|
143
|
+
}
|
|
121
144
|
}
|
|
122
145
|
if (msg.type === "response" && msg.command === "prompt" && msg.success === false) {
|
|
123
146
|
emit(JSON.stringify({ type: "runner_error", reason: "prompt rejected" }));
|