@sjawhar/pi-legion-envoy 0.11.0 → 0.13.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/README.md CHANGED
@@ -44,9 +44,10 @@ set -g set-clipboard on
44
44
 
45
45
  This package declares two OMP extension entries in `package.json`: `extensions/envoy.ts`
46
46
  (Envoy messaging, subscriptions, and steering delivery) and `extensions/legion.ts` (the
47
- Legion lifecycle: root bootstrap, worker spawning, budgets, and daemon capabilities).
48
- `extensions/legion.ts` is inert without `LEGION_TREE`, `LEGION_ROLE`, or `LEGION_CONTROLLER`
49
- set in the environment, so loading both alongside each other is safe for every session.
47
+ Legion lifecycle: root and phase-worker bootstrap from the daemon's environment, and
48
+ daemon capabilities). The Legion daemon spawns every root and phase-worker process with
49
+ the installed plugin already active, so `extensions/legion.ts` loads for them automatically;
50
+ it is inert without `LEGION_TREE`/`LEGION_ROLE`/`LEGION_CONTROLLER` in the environment.
50
51
 
51
52
  For local development of the messaging extension alone, link the entry into OMP:
52
53
 
package/dist/envoy.js CHANGED
@@ -29783,9 +29783,7 @@ var LEGION_ROLES = [
29783
29783
  "reviewer",
29784
29784
  "merger"
29785
29785
  ];
29786
- var ENVOY_ROLE_TOKEN = /^[a-z0-9][a-z0-9_-]*$/;
29787
29786
  var PROJECT_TOKEN = /^[a-z0-9]+$/;
29788
- var ISSUE_PART = /^[a-z0-9._-]+$/;
29789
29787
  function isLegionRole(role) {
29790
29788
  return LEGION_ROLES.some((candidate) => candidate === role);
29791
29789
  }
@@ -29797,91 +29795,10 @@ function assertLegionProjectToken(project) {
29797
29795
  throw new Error(`Invalid Legion project token: ${project}`);
29798
29796
  }
29799
29797
  }
29800
- function encodeIssuePart(part) {
29801
- const normalized = part.toLowerCase();
29802
- if (!ISSUE_PART.test(normalized)) {
29803
- throw new Error(`Invalid Legion issue token part: ${part}`);
29804
- }
29805
- return normalized.replaceAll("_", "_u").replaceAll(".", "_d").replaceAll("-", "_h");
29806
- }
29807
- function decodeIssuePart(part) {
29808
- let decoded = "";
29809
- for (let index = 0;index < part.length; index += 1) {
29810
- const character = part[index];
29811
- if (character !== "_") {
29812
- decoded += character;
29813
- continue;
29814
- }
29815
- const escapeCode = part[index + 1];
29816
- if (escapeCode === "u")
29817
- decoded += "_";
29818
- else if (escapeCode === "d")
29819
- decoded += ".";
29820
- else if (escapeCode === "h")
29821
- decoded += "-";
29822
- else
29823
- return;
29824
- index += 1;
29825
- }
29826
- return decoded;
29827
- }
29828
- function formatIssueKey(owner, repo, number) {
29829
- return `${owner}/${repo}#${number}`;
29830
- }
29831
- function parseIssueKey(s) {
29832
- const match = /^([^/#]+)\/([^/#]+)#(\d+)$/.exec(s);
29833
- if (!match)
29834
- return;
29835
- const owner = match[1];
29836
- const repo = match[2];
29837
- const numberPart = match[3];
29838
- if (!owner || !repo || !numberPart)
29839
- return;
29840
- const number = Number(numberPart);
29841
- if (!Number.isSafeInteger(number))
29842
- return;
29843
- return { owner, repo, number };
29844
- }
29845
- function roleToken(project, issue, role) {
29846
- assertLegionProjectToken(project);
29847
- const parsedIssue = parseIssueKey(issue);
29848
- if (!parsedIssue)
29849
- throw new Error(`Invalid IssueKey: ${issue}`);
29850
- return `legion-${project}-${encodeIssuePart(parsedIssue.owner)}__${encodeIssuePart(parsedIssue.repo)}-${parsedIssue.number}-${role}`;
29851
- }
29852
29798
  function controllerToken(project) {
29853
29799
  assertLegionProjectToken(project);
29854
29800
  return `legion-${project}-controller`;
29855
29801
  }
29856
- function parseRoleToken(project, token) {
29857
- if (!isLegionProjectToken(project))
29858
- return;
29859
- const prefix = `legion-${project}-`;
29860
- if (!ENVOY_ROLE_TOKEN.test(token) || !token.startsWith(prefix))
29861
- return;
29862
- const rest = token.slice(prefix.length);
29863
- if (rest === "controller")
29864
- return { controller: true };
29865
- const match = /^([a-z0-9_]+)__([a-z0-9_]+)-(\d+)-(architect|planner|implementer|tester|reviewer|merger)$/.exec(rest);
29866
- if (!match)
29867
- return;
29868
- const ownerPart = match[1];
29869
- const repoPart = match[2];
29870
- const numberPart = match[3];
29871
- const role = match[4];
29872
- if (!ownerPart || !repoPart || !numberPart || !role || !isLegionRole(role))
29873
- return;
29874
- const owner = decodeIssuePart(ownerPart);
29875
- const repo = decodeIssuePart(repoPart);
29876
- const number = Number(numberPart);
29877
- if (!owner || !repo || !Number.isSafeInteger(number))
29878
- return;
29879
- return {
29880
- project,
29881
- issue: formatIssueKey(owner, repo, number),
29882
- role
29883
- };
29884
- }
29885
29802
 
29886
29803
  // ../contracts/src/legion-daemon-api.ts
29887
29804
  var nonEmptyString = string2().min(1);
@@ -30031,6 +29948,13 @@ var LegionDaemonApi = {
30031
29948
  }),
30032
29949
  response: object({})
30033
29950
  },
29951
+ PhaseComplete: {
29952
+ request: strictObject({
29953
+ grantId: nonEmptyString,
29954
+ summary: nonEmptyString
29955
+ }),
29956
+ response: object({})
29957
+ },
30034
29958
  SpawnWorker: {
30035
29959
  request: architectCapability.extend({
30036
29960
  issue: nonEmptyString,
@@ -31544,15 +31468,6 @@ async function claimEnvoyRole(sessionID, role, context) {
31544
31468
  const bridge = legionRoleClaimBridge();
31545
31469
  await (bridge.claim ?? await bridge.ready.promise)(sessionID, role, context);
31546
31470
  }
31547
- async function deleteEnvoyInterest(baseUrl, sessionID) {
31548
- const response = await fetch(`${baseUrl}/v1/interests/${encodeURIComponent(sessionID)}`, {
31549
- method: "DELETE"
31550
- });
31551
- const responseBody = await response.text();
31552
- if (!response.ok) {
31553
- throw new Error(`DELETE /v1/interests/${sessionID} failed with ${response.status}: ${responseBody}`);
31554
- }
31555
- }
31556
31471
  function resolveSkillsDirectory() {
31557
31472
  const moduleDirectory = dirname(fileURLToPath(import.meta.url));
31558
31473
  const candidates = [
@@ -32073,6 +31988,5 @@ function topicsFor(parameters, fallback = []) {
32073
31988
  }
32074
31989
  export {
32075
31990
  claimEnvoyRole,
32076
- envoyExtension as default,
32077
- deleteEnvoyInterest
31991
+ envoyExtension as default
32078
31992
  };