@sjawhar/pi-legion 8.5.1 → 8.7.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/legion.js +67 -4
- package/dist/skills/legion-worker/SKILL.md +3 -3
- package/package.json +1 -1
package/dist/legion.js
CHANGED
|
@@ -15309,7 +15309,7 @@ function onEnvoyRoleRegained(listener) {
|
|
|
15309
15309
|
// package.json
|
|
15310
15310
|
var package_default = {
|
|
15311
15311
|
name: "@sjawhar/pi-legion",
|
|
15312
|
-
version: "8.
|
|
15312
|
+
version: "8.7.0",
|
|
15313
15313
|
license: "Apache-2.0",
|
|
15314
15314
|
type: "module",
|
|
15315
15315
|
omp: {
|
|
@@ -16495,6 +16495,42 @@ function createLegionTool(deps) {
|
|
|
16495
16495
|
};
|
|
16496
16496
|
}
|
|
16497
16497
|
|
|
16498
|
+
// src/workspace-recreated.ts
|
|
16499
|
+
var WORKSPACE_RECREATED_VARIABLE = "LEGION_WORKSPACE_RECREATED";
|
|
16500
|
+
var WORKSPACE_RECREATED_MESSAGE = "legion-workspace-recreated";
|
|
16501
|
+
function workspaceRecreatedNotice(environment, issue2) {
|
|
16502
|
+
if (environment[WORKSPACE_RECREATED_VARIABLE] !== "true")
|
|
16503
|
+
return;
|
|
16504
|
+
return {
|
|
16505
|
+
id: crypto.randomUUID(),
|
|
16506
|
+
content: `Your workspace was recreated since your last turn: it holds what was pushed to legion/${issue2} ` + "(main if nothing was), and anything you had not pushed is gone. Before you continue, check " + "the workspace against what you remember doing and re-read your last handoff."
|
|
16507
|
+
};
|
|
16508
|
+
}
|
|
16509
|
+
function workspaceRecreatedMessage(notice) {
|
|
16510
|
+
return {
|
|
16511
|
+
customType: WORKSPACE_RECREATED_MESSAGE,
|
|
16512
|
+
content: notice.content,
|
|
16513
|
+
display: true,
|
|
16514
|
+
details: { id: notice.id }
|
|
16515
|
+
};
|
|
16516
|
+
}
|
|
16517
|
+
function isNoticeCopy(value, kind, id) {
|
|
16518
|
+
if (typeof value !== "object" || value === null)
|
|
16519
|
+
return false;
|
|
16520
|
+
const typed = kind === "entry" ? "type" in value && value.type === "custom_message" : ("role" in value) && value.role === "custom";
|
|
16521
|
+
return typed && "customType" in value && value.customType === WORKSPACE_RECREATED_MESSAGE && "details" in value && typeof value.details === "object" && value.details !== null && "id" in value.details && value.details.id === id;
|
|
16522
|
+
}
|
|
16523
|
+
function branchHoldsWorkspaceRecreatedNotice(branch, id) {
|
|
16524
|
+
return branch.some((entry) => isNoticeCopy(entry, "entry", id));
|
|
16525
|
+
}
|
|
16526
|
+
function withoutRepeatedWorkspaceRecreatedNotice(messages, id) {
|
|
16527
|
+
const first = messages.findIndex((message) => isNoticeCopy(message, "message", id));
|
|
16528
|
+
if (first === -1)
|
|
16529
|
+
return;
|
|
16530
|
+
const kept = messages.filter((message, index) => index <= first || !isNoticeCopy(message, "message", id));
|
|
16531
|
+
return kept.length === messages.length ? undefined : kept;
|
|
16532
|
+
}
|
|
16533
|
+
|
|
16498
16534
|
// extensions/legion.ts
|
|
16499
16535
|
var exitProcess = (code) => process.exit(code);
|
|
16500
16536
|
function setLegionBootstrapExitForTests(hook) {
|
|
@@ -16762,27 +16798,54 @@ function legionExtension(pi) {
|
|
|
16762
16798
|
return;
|
|
16763
16799
|
writeSessionTitle(sessionDirectory(process.env, sessionID), context.sessionManager.getSessionName?.() ?? title);
|
|
16764
16800
|
};
|
|
16801
|
+
let recreatedNotice;
|
|
16765
16802
|
pi.on("session_start", async (_event, context) => {
|
|
16766
16803
|
if (await checkSubagentSession(context))
|
|
16767
16804
|
return;
|
|
16768
16805
|
await titleSession(context);
|
|
16769
16806
|
phaseStall = restorePhaseStall(context.sessionManager.getBranch?.() ?? []);
|
|
16770
|
-
const
|
|
16771
|
-
if (kind === "not-legion")
|
|
16807
|
+
const session = classifySession(process.env);
|
|
16808
|
+
if (session.kind === "not-legion")
|
|
16772
16809
|
return;
|
|
16773
16810
|
const refusal = envoyPluginRefusal();
|
|
16774
16811
|
if (refusal !== undefined) {
|
|
16775
16812
|
logger3.error(refusal);
|
|
16776
16813
|
exitProcess(1);
|
|
16777
16814
|
}
|
|
16778
|
-
if (kind === "controller") {
|
|
16815
|
+
if (session.kind === "controller") {
|
|
16779
16816
|
await controllerSession.handleSessionStart(context);
|
|
16780
16817
|
return;
|
|
16781
16818
|
}
|
|
16819
|
+
recreatedNotice = workspaceRecreatedNotice(process.env, session.kind === "root-architect" ? session.tree : session.issue);
|
|
16820
|
+
if (recreatedNotice !== undefined) {
|
|
16821
|
+
pi.sendMessage(workspaceRecreatedMessage(recreatedNotice), {
|
|
16822
|
+
deliverAs: "steer",
|
|
16823
|
+
triggerTurn: false
|
|
16824
|
+
});
|
|
16825
|
+
}
|
|
16782
16826
|
await claimSession.bootstrap(context);
|
|
16783
16827
|
registerLegionTool();
|
|
16784
16828
|
await activateLegionTool();
|
|
16785
16829
|
});
|
|
16830
|
+
let resentNoticeId;
|
|
16831
|
+
pi.on("before_agent_start", async (_event, context) => {
|
|
16832
|
+
if (recreatedNotice === undefined)
|
|
16833
|
+
return;
|
|
16834
|
+
const branch = context.sessionManager.getBranch?.() ?? [];
|
|
16835
|
+
if (branchHoldsWorkspaceRecreatedNotice(branch, recreatedNotice.id))
|
|
16836
|
+
return;
|
|
16837
|
+
resentNoticeId = recreatedNotice.id;
|
|
16838
|
+
return { message: workspaceRecreatedMessage(recreatedNotice) };
|
|
16839
|
+
});
|
|
16840
|
+
pi.on("agent_start", async () => {
|
|
16841
|
+
recreatedNotice = undefined;
|
|
16842
|
+
});
|
|
16843
|
+
pi.on("context", async (event) => {
|
|
16844
|
+
if (resentNoticeId === undefined)
|
|
16845
|
+
return;
|
|
16846
|
+
const messages = withoutRepeatedWorkspaceRecreatedNotice(event.messages, resentNoticeId);
|
|
16847
|
+
return messages === undefined ? undefined : { messages };
|
|
16848
|
+
});
|
|
16786
16849
|
const afterSessionChange = async (context) => {
|
|
16787
16850
|
if (await checkSubagentSession(context))
|
|
16788
16851
|
return;
|
|
@@ -142,9 +142,9 @@ predecessor phases already wrote. The durable copy lives in
|
|
|
142
142
|
`$LEGION_WORKSPACE/.legion/<issue>/<phase>.json`. If a committed handoff conflicts with memory or a prior
|
|
143
143
|
transcript, the committed file wins: it is the copy that survived.
|
|
144
144
|
|
|
145
|
-
If your
|
|
146
|
-
`.legion/<issue>/workspace-recovered.json`,
|
|
147
|
-
new work.
|
|
145
|
+
If your task, prompt, or a message since your last turn begins `Your workspace was recreated…`, read
|
|
146
|
+
your phase's committed handoff and any `.legion/<issue>/workspace-recovered.json`, and reconcile
|
|
147
|
+
before new work: anything unpushed is gone. That message stays in history; reconciled, it is done.
|
|
148
148
|
|
|
149
149
|
## jj Safety Rules
|
|
150
150
|
|