@sjawhar/pi-legion-envoy 5.16.6 → 5.16.8

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/envoy.js CHANGED
@@ -30600,6 +30600,7 @@ function controllerToken(project) {
30600
30600
 
30601
30601
  // ../contracts/src/legion-daemon-api.ts
30602
30602
  var nonEmptyString = exports_external.string().min(1);
30603
+ var appLogin = exports_external.string().regex(/^[^[\]]+\[bot\]$/);
30603
30604
  var legionRole = exports_external.enum(LEGION_ROLES);
30604
30605
  var requiredUnknown = exports_external.unknown().refine((value) => value !== undefined, {
30605
30606
  message: "Required"
@@ -30853,7 +30854,11 @@ var LegionDaemonApi = {
30853
30854
  },
30854
30855
  GitHubToken: {
30855
30856
  request: exports_external.strictObject({ grantId: nonEmptyString }),
30856
- response: exports_external.object({ token: nonEmptyString, appLogin: exports_external.string().endsWith("[bot]") })
30857
+ response: exports_external.object({
30858
+ token: nonEmptyString,
30859
+ appLogin: exports_external.string().endsWith("[bot]"),
30860
+ legionAppLogins: exports_external.object({ implement: appLogin, review: appLogin }).optional()
30861
+ })
30857
30862
  },
30858
30863
  GitCredential: {
30859
30864
  request: exports_external.strictObject({ grantId: nonEmptyString })
package/dist/legion.js CHANGED
@@ -30769,6 +30769,7 @@ function controllerToken(project) {
30769
30769
 
30770
30770
  // ../contracts/src/legion-daemon-api.ts
30771
30771
  var nonEmptyString = exports_external.string().min(1);
30772
+ var appLogin = exports_external.string().regex(/^[^[\]]+\[bot\]$/);
30772
30773
  var legionRole = exports_external.enum(LEGION_ROLES);
30773
30774
  var requiredUnknown = exports_external.unknown().refine((value) => value !== undefined, {
30774
30775
  message: "Required"
@@ -31022,7 +31023,11 @@ var LegionDaemonApi = {
31022
31023
  },
31023
31024
  GitHubToken: {
31024
31025
  request: exports_external.strictObject({ grantId: nonEmptyString }),
31025
- response: exports_external.object({ token: nonEmptyString, appLogin: exports_external.string().endsWith("[bot]") })
31026
+ response: exports_external.object({
31027
+ token: nonEmptyString,
31028
+ appLogin: exports_external.string().endsWith("[bot]"),
31029
+ legionAppLogins: exports_external.object({ implement: appLogin, review: appLogin }).optional()
31030
+ })
31026
31031
  },
31027
31032
  GitCredential: {
31028
31033
  request: exports_external.strictObject({ grantId: nonEmptyString })
@@ -33415,7 +33420,7 @@ import { logger } from "@oh-my-pi/pi-utils";
33415
33420
  // package.json
33416
33421
  var package_default = {
33417
33422
  name: "@sjawhar/pi-legion-envoy",
33418
- version: "5.16.6",
33423
+ version: "5.16.8",
33419
33424
  type: "module",
33420
33425
  omp: {
33421
33426
  extensions: [
@@ -33428,7 +33433,7 @@ var package_default = {
33428
33433
  },
33429
33434
  legion: {
33430
33435
  daemonApiVersion: 9,
33431
- goDaemonApiVersion: 10
33436
+ goDaemonApiVersion: 11
33432
33437
  },
33433
33438
  repository: {
33434
33439
  type: "git",
@@ -33990,9 +33995,11 @@ var LegionGoGrantResponse = exports_external.strictObject({
33990
33995
  grantId: nonEmptyString2,
33991
33996
  expiresAt: timestamp
33992
33997
  });
33998
+ var appLogin2 = exports_external.string().regex(/^[^[\]]+\[bot\]$/);
33993
33999
  var LegionGoGitHubTokenResponse = exports_external.strictObject({
33994
34000
  token: nonEmptyString2,
33995
- appLogin: exports_external.string().endsWith("[bot]")
34001
+ appLogin: exports_external.string().endsWith("[bot]"),
34002
+ legionAppLogins: exports_external.strictObject({ implement: appLogin2, review: appLogin2 }).optional()
33996
34003
  });
33997
34004
  var LegionGoGitCredentialResponse = exports_external.strictObject({
33998
34005
  username: exports_external.literal("x-access-token"),
@@ -41227,6 +41234,15 @@ function scanIpythonShell(source, sinks) {
41227
41234
  }
41228
41235
 
41229
41236
  // src/legion/pane-guard.ts
41237
+ var definitions = new WeakMap;
41238
+ function trapSignal(operand) {
41239
+ const name = operand.toUpperCase();
41240
+ if (name === "0")
41241
+ return "EXIT";
41242
+ return name.startsWith("SIG") && name !== "SIGEXIT" ? name.slice(3) : name;
41243
+ }
41244
+ var UNREADABLE_CONDITION = "an unreadable condition";
41245
+
41230
41246
  class Refusal extends Error {
41231
41247
  snippet;
41232
41248
  line;
@@ -41252,7 +41268,7 @@ function wrapRefusal(error48, site, label) {
41252
41268
  throw new Refusal(site.snippet, site.line, `line ${error48.line} of ${source}, \`${error48.snippet}\`: ${error48.detail}`);
41253
41269
  }
41254
41270
  var MAX_DEPTH = 8;
41255
- var MAX_WALK_STEPS = 1e4;
41271
+ var MAX_WALK_STEPS = 1e5;
41256
41272
  var MAX_ALTERNATIVES = 64;
41257
41273
  var MAX_SCRIPT_BYTES = 1024 * 1024;
41258
41274
  var FRESH_TEMP_NAME = "tmp.XXXXXXXXXX";
@@ -41570,12 +41586,22 @@ function substitution(script, text, st, ctx) {
41570
41586
  }
41571
41587
  const only = script?.commands.length === 1 ? script.commands[0]?.command : undefined;
41572
41588
  const invocation = substitutionInvocation(only, st, ctx);
41573
- const definition = invocation === undefined ? undefined : st.functions.get(invocation.base);
41574
- if (definition !== undefined && invocation !== undefined) {
41575
- const output = functionOutput(invocation.base, definition, invocation.rest, st, ctx);
41576
- if (output !== undefined)
41577
- return output.map((value) => [...value]);
41589
+ const callee = invocation === undefined ? undefined : st.functions.get(invocation.base);
41590
+ if (callee !== undefined && invocation !== undefined) {
41591
+ const alternatives = [];
41592
+ let external2 = false;
41593
+ for (const definition of callee) {
41594
+ const output = definition === undefined ? undefined : functionOutput(invocation.base, definition, invocation.rest, st, ctx);
41595
+ if (output !== undefined)
41596
+ alternatives.push(...output.map((value) => [...value]));
41597
+ else
41598
+ external2 = true;
41599
+ }
41600
+ return external2 ? [...alternatives, ...commandOutput(only, invocation, text, st, ctx)] : alternatives;
41578
41601
  }
41602
+ return commandOutput(only, invocation, text, st, ctx);
41603
+ }
41604
+ function commandOutput(only, invocation, text, st, ctx) {
41579
41605
  if (invocation !== undefined) {
41580
41606
  if (invocation.base === "pwd" && invocation.rest.length === 0 && st.cwd !== undefined) {
41581
41607
  return [[literal2(st.cwd)]];
@@ -41813,7 +41839,7 @@ function walkSubstitution(script, inner, text, st, ctx) {
41813
41839
  throw new Refusal(text, 1, `the guard could not read the command in \`${text}\``);
41814
41840
  }
41815
41841
  const source = parsed.source ?? (script === undefined ? inner ?? "" : st.source);
41816
- walkScript(parsed, { ...clone2(st), source }, ctx);
41842
+ walkScript(parsed, subshell(st, { source }), ctx);
41817
41843
  }
41818
41844
  function clone2(st) {
41819
41845
  return {
@@ -41856,6 +41882,8 @@ function merge2(target, branches) {
41856
41882
  target.arrays.set(name, new Map([[UNKNOWN_ARRAY_INDEX, unknownElement]]));
41857
41883
  }
41858
41884
  }
41885
+ const positionals = branches.map((branch) => JSON.stringify(branch.positional ?? null));
41886
+ target.positional = positionals.every((value) => value === positionals[0]) ? branches[0]?.positional : undefined;
41859
41887
  const cwds = new Set(branches.map((branch) => branch.cwd));
41860
41888
  if (cwds.size > 1) {
41861
41889
  target.cwd = undefined;
@@ -41869,6 +41897,46 @@ function merge2(target, branches) {
41869
41897
  target.exported.add(name);
41870
41898
  target.backgroundStarted ||= branch.backgroundStarted;
41871
41899
  }
41900
+ const functionNames = new Set;
41901
+ for (const branch of branches)
41902
+ for (const name of branch.functions.keys())
41903
+ functionNames.add(name);
41904
+ const functions = new Map;
41905
+ for (const name of functionNames) {
41906
+ const callees = branches.map((branch) => branch.functions.get(name));
41907
+ const first = callees[0];
41908
+ if (first !== undefined && callees.every((callee) => callee === first)) {
41909
+ functions.set(name, first);
41910
+ continue;
41911
+ }
41912
+ const candidates = new Set;
41913
+ for (const callee of callees)
41914
+ for (const definition of callee ?? [undefined])
41915
+ candidates.add(definition);
41916
+ functions.set(name, [...candidates]);
41917
+ }
41918
+ target.functions = functions;
41919
+ const lifted = [];
41920
+ let merged;
41921
+ for (const branch of branches) {
41922
+ for (const trap of branch.traps) {
41923
+ if (target.traps.includes(trap))
41924
+ continue;
41925
+ merged ??= new Map(target.vars);
41926
+ lifted.push({ ...trap, vars: handlerVars(trap, branch.vars), merged });
41927
+ }
41928
+ }
41929
+ target.traps = [...target.traps, ...lifted];
41930
+ }
41931
+ function handlerVars(trap, vars) {
41932
+ const { vars: branch, merged } = trap;
41933
+ if (branch === undefined || merged === undefined)
41934
+ return vars;
41935
+ const out = new Map(vars);
41936
+ for (const [name, value] of branch)
41937
+ if (vars.get(name) === merged.get(name))
41938
+ out.set(name, value);
41939
+ return out;
41872
41940
  }
41873
41941
  function lineOf(source, pos) {
41874
41942
  let line = 1;
@@ -41894,13 +41962,19 @@ function walkScript(script, st, ctx, runTraps = true) {
41894
41962
  }
41895
41963
  for (const statement of script.commands)
41896
41964
  walkNode(statement, st, ctx, false);
41897
- if (!runTraps)
41898
- return;
41965
+ if (runTraps)
41966
+ runSetTraps(st, ctx);
41967
+ }
41968
+ function subshell(st, patch) {
41969
+ return { ...clone2(st), traps: [], ...patch };
41970
+ }
41971
+ function runSetTraps(st, ctx) {
41899
41972
  for (const trap of st.traps) {
41973
+ const vars = new Map([...handlerVars(trap, st.vars), ...trap.pids ?? []]);
41900
41974
  try {
41901
- runText(trap.text, "the EXIT trap", { ...clone2(st), source: trap.file, traps: [] }, ctx, trap.site);
41902
- } catch (error49) {
41903
- locateRefusal(error49, trap.file);
41975
+ runText(trap.text, "the EXIT trap", subshell(st, { source: trap.file, vars }), ctx, trap.site);
41976
+ } catch (error48) {
41977
+ locateRefusal(error48, trap.file);
41904
41978
  }
41905
41979
  }
41906
41980
  }
@@ -41919,20 +41993,34 @@ function walkNode(node, st, ctx, pipeIn) {
41919
41993
  switch (node.type) {
41920
41994
  case "Statement": {
41921
41995
  checkRedirects(node.redirects, undefined, siteOf(node, st), st, ctx);
41922
- walkNode(node.command, st, ctx, pipeIn);
41923
- if (node.background)
41996
+ if (node.background) {
41997
+ const before = st.output;
41998
+ const child = subshell(st);
41999
+ walkNode(node.command, child, ctx, pipeIn);
42000
+ runSetTraps(child, ctx);
42001
+ if (outputChanged(before, child.output))
42002
+ st.output = undefined;
41924
42003
  st.backgroundStarted = true;
42004
+ return;
42005
+ }
42006
+ walkNode(node.command, st, ctx, pipeIn);
41925
42007
  return;
41926
42008
  }
41927
42009
  case "Command":
41928
42010
  handleCommand(node, st, ctx, pipeIn);
41929
42011
  return;
41930
42012
  case "Pipeline": {
42013
+ if (node.commands.length === 1) {
42014
+ for (const command of node.commands)
42015
+ walkNode(command, st, ctx, pipeIn);
42016
+ return;
42017
+ }
41931
42018
  const before = st.output;
41932
42019
  const parts = [];
41933
42020
  for (const [index, command] of node.commands.entries()) {
41934
- const part = clone2(st);
42021
+ const part = subshell(st);
41935
42022
  walkNode(command, part, ctx, index > 0);
42023
+ runSetTraps(part, ctx);
41936
42024
  parts.push(part);
41937
42025
  }
41938
42026
  if (parts.some((part) => outputChanged(before, part.output)))
@@ -41951,8 +42039,9 @@ function walkNode(node, st, ctx, pipeIn) {
41951
42039
  return;
41952
42040
  case "Subshell": {
41953
42041
  const before = st.output;
41954
- const child = clone2(st);
42042
+ const child = subshell(st);
41955
42043
  walkList(node.body.commands, child, ctx);
42044
+ runSetTraps(child, ctx);
41956
42045
  if (outputChanged(before, child.output))
41957
42046
  st.output = undefined;
41958
42047
  return;
@@ -42041,14 +42130,21 @@ function walkNode(node, st, ctx, pipeIn) {
42041
42130
  st.output = undefined;
42042
42131
  return;
42043
42132
  }
42044
- case "Function":
42045
- st.functions.set(node.name.value, { body: node.body, source: st.source, file: st.script });
42133
+ case "Function": {
42134
+ let callee = definitions.get(node);
42135
+ if (callee === undefined) {
42136
+ callee = [{ body: node.body, source: st.source, file: st.script }];
42137
+ definitions.set(node, callee);
42138
+ }
42139
+ st.functions.set(node.name.value, callee);
42046
42140
  checkRedirects(node.redirects, undefined, siteOf(node, st), st, ctx);
42047
42141
  return;
42142
+ }
42048
42143
  case "Coproc": {
42049
42144
  const before = st.output;
42050
- const child = clone2(st);
42145
+ const child = subshell(st);
42051
42146
  walkNode(node.body, child, ctx, false);
42147
+ runSetTraps(child, ctx);
42052
42148
  if (outputChanged(before, child.output))
42053
42149
  st.output = undefined;
42054
42150
  checkRedirects(node.redirects, undefined, siteOf(node, st), st, ctx);
@@ -42359,9 +42455,24 @@ function dispatch(invocation, outer, ctx) {
42359
42455
  const base = path4.basename(name);
42360
42456
  const rest = argv.slice(1);
42361
42457
  const site = invocation.site;
42362
- const functionDefinition = outer.functions.get(base);
42363
- if (functionDefinition !== undefined) {
42364
- runFunction(base, functionDefinition, rest, outer, ctx);
42458
+ const callee = outer.functions.get(base);
42459
+ if (callee !== undefined) {
42460
+ const [only] = callee;
42461
+ if (callee.length === 1 && only !== undefined) {
42462
+ runFunction(base, only, rest, outer, ctx);
42463
+ return;
42464
+ }
42465
+ const runs = callee.map((definition) => {
42466
+ const run = clone2(outer);
42467
+ if (definition !== undefined)
42468
+ runFunction(base, definition, rest, run, ctx);
42469
+ else {
42470
+ run.functions.delete(base);
42471
+ dispatch(invocation, run, ctx);
42472
+ }
42473
+ return run;
42474
+ });
42475
+ merge2(outer, runs);
42365
42476
  return;
42366
42477
  }
42367
42478
  const stdoutRedirected = invocation.redirects.some((redirect) => (redirect.fileDescriptor === undefined || redirect.fileDescriptor === 1) && [">", ">>", ">|", "&>", "&>>", ">&"].includes(redirect.operator));
@@ -42453,11 +42564,34 @@ function dispatch(invocation, outer, ctx) {
42453
42564
  return;
42454
42565
  }
42455
42566
  case "trap": {
42456
- const text = literalText(operands(rest, "").operands[0]?.exp);
42567
+ const [handler, ...conditions] = operands(rest, "").operands;
42568
+ if (handler === undefined)
42569
+ return;
42570
+ const text = literalText(handler.exp);
42571
+ const readable = conditions.map((arg) => literalText(arg.exp));
42572
+ const signals = readable.map((condition) => condition === undefined ? UNREADABLE_CONDITION : trapSignal(condition));
42573
+ const handled = signals.length === 0 ? ["EXIT"] : signals;
42574
+ const file2 = outer.script ?? outer.source;
42457
42575
  if (text === "-") {
42458
- outer.traps = [];
42459
- } else if (text !== undefined && !text.startsWith("-")) {
42460
- outer.traps = [...outer.traps, { text, site, file: outer.script ?? outer.source }];
42576
+ const named = readable.flatMap((condition) => condition === undefined ? [] : [trapSignal(condition)]);
42577
+ outer.traps = outer.traps.flatMap((trap) => {
42578
+ const signals2 = trap.signals.filter((signal) => !named.includes(signal));
42579
+ return signals2.length === 0 ? [] : [{ ...trap, signals: signals2 }];
42580
+ });
42581
+ } else if (text === undefined && handler.exp.every((piece) => piece.kind === "literal" || piece.descendantPid)) {
42582
+ const pids = new Map;
42583
+ const handlerText = handler.exp.map((piece) => {
42584
+ if (piece.kind === "literal")
42585
+ return piece.text;
42586
+ const name2 = `__legion_guard_trap_pid_${pids.size}`;
42587
+ pids.set(name2, [piece]);
42588
+ return `\${${name2}}`;
42589
+ }).join("");
42590
+ outer.traps = [...outer.traps, { text: handlerText, site, signals: handled, file: file2, pids }];
42591
+ } else if (text === undefined) {
42592
+ throw new Refusal(site.snippet, site.line, `the guard cannot read the handler this \`trap\` sets, \`${handler.text}\` (${handler.exp.find((piece) => piece.kind !== "literal")?.why ?? "a value the guard cannot know"}), so it cannot check what runs when this shell exits; write the handler out, or put it in a function`);
42593
+ } else if (!text.startsWith("-")) {
42594
+ outer.traps = [...outer.traps, { text, site, signals: handled, file: file2 }];
42461
42595
  }
42462
42596
  return;
42463
42597
  }
@@ -43139,9 +43273,11 @@ function runFile(file2, positional, st, ctx, site, kind, source = false) {
43139
43273
  throw new Refusal(site.snippet, site.line, "the guard stops following scripts this deep; run the inner script directly");
43140
43274
  }
43141
43275
  const child = { ...clone2(st), source: content, script: abs, depth: st.depth + 1 };
43142
- child.positional = positional.map((arg) => arg.exp);
43276
+ const operands2 = positional.map((arg) => arg.exp);
43277
+ child.positional = source && operands2.length === 0 ? st.positional : operands2;
43143
43278
  walkScript(parse5(content), child, ctx, !source);
43144
43279
  if (source) {
43280
+ st.positional = operands2.length === 0 ? child.positional : child.positional === operands2 ? st.positional : undefined;
43145
43281
  st.vars = child.vars;
43146
43282
  st.exported = child.exported;
43147
43283
  st.arrays.clear();
@@ -285,9 +285,11 @@ later phase keeps it current rather than replacing it:
285
285
  - Thread <id>: fixed in <commit-sha> — <one line>.
286
286
  - Thread <id>: not a defect — <reason>.
287
287
  `legion threads resolve --pr <n> --repo <owner>/<repo>` at <head-sha>:
288
- resolved <thread URL>
288
+ resolved <thread URL> — its opener's acceptance
289
+ resolved <thread URL> — the Legion reviewer's acceptance of a bot's thread
289
290
  left open <thread URL> — newest reply by <login> is not an acceptance
290
291
  left open <thread URL> — newest reply by <login> is an unsubmitted draft in a pending review
292
+ left open <thread URL> — newest reply by <login> is not its opener's or the Legion reviewer's acceptance
291
293
 
292
294
  **Thermo:** `ce-simplify-code` once at <head-sha>: <0 applied | applied → new head <sha>>; thermonuclear pair at the final head <sha>:
293
295
  <verdict>. (omitted entirely on a docs-only PR — there is no code for either pass, so neither runs)
@@ -329,7 +331,8 @@ this proof.
329
331
 
330
332
  - **Threads are dispositioned individually, never resolved in bulk.** Every open review
331
333
  thread gets its own line naming the fixing commit or the reason it isn't a defect. The
332
- reviewer answers each thread it opened with exactly one of `Accepted: fixed in <commit> — <one line>`,
334
+ reviewer answers each thread it opened, and each thread a bot opened that is none of Legion's
335
+ role Apps, with exactly one of `Accepted: fixed in <commit> — <one line>`,
333
336
  `Accepted: not a defect — <reason>`, or `Still open: <what remains>`; nothing else is an
334
337
  acceptance, and nobody replies after an `Accepted:` (any later reply that is not itself an
335
338
  `Accepted:` — the opener's own follow-up included — leaves the thread open, because resolution
@@ -341,9 +344,16 @@ this proof.
341
344
  In a Legion pane, the **implementer** runs the command before every push that answers a review
342
345
  (the corrective push and the final `.legion/` deletion push) and pastes its output into the
343
346
  `Threads` section. The command resolves each unresolved thread whose newest submitted comment is
344
- the opener's own `Accepted:` reply, one `resolveReviewThread` per thread, prints `resolved <url>`
345
- or `left open <url> — newest reply by <login> is not an acceptance`, and exits 1 naming the
346
- thread's URL and GitHub's message when GitHub refuses one.
347
+ the opener's own `Accepted:` reply. On a thread a bot account opened that is none of Legion's
348
+ role Apps (the daemon names them, keyed by App role), the Legion reviewer's `Accepted:` also
349
+ closes it. GitHub cannot tell a CI bot, which never accepts, from a person whose `gh` is routed
350
+ to an App, so the reviewer adjudicates such a finding, and it may accept one an App-routed person
351
+ raised. The subject of a finding never closes it: the implementer's `Fixed in <commit>: …` or
352
+ `Declined: …` answers a thread and closes none. A thread either Legion App opened, a reviewer's
353
+ finding included, still needs its opener's `Accepted:`. It makes one `resolveReviewThread` per
354
+ thread, prints `resolved <url> — <whose acceptance>` (its opener's, or the Legion reviewer's on a
355
+ bot's thread, so the ledger shows which) or `left open <url> — newest reply by <login> is …`
356
+ naming why, and exits 1 naming the thread's URL and GitHub's message when GitHub refuses one.
347
357
 
348
358
  Without a grant, page through `reviewThreads`, skip `isResolved: true`, and compare the opener
349
359
  with the newest comment. Query shape, inside `repository { pullRequest { … } }`:
@@ -353,15 +363,18 @@ this proof.
353
363
  pageInfo { hasNextPage endCursor }
354
364
  nodes {
355
365
  id isResolved
356
- opener: comments(first: 1) { nodes { author { login } } }
357
- newest: comments(last: 1) { nodes { author { login } body state } }
366
+ opener: comments(first: 1) { nodes { author { __typename login } } }
367
+ newest: comments(last: 1) { nodes { author { __typename login } body state } }
358
368
  }
359
369
  }
360
370
  ```
361
371
 
362
- Resolve only when the newest comment is submitted, its `author { login }` equals the opener's,
363
- and its `body`, after removing leading spaces, tabs, CR, and LF, begins `Accepted:`. For each
364
- such thread:
372
+ Resolve only when the newest comment is submitted, its `author` is the opener's account (the same
373
+ `__typename` and `login`: a login alone is a string anyone may register), and its `body`, after
374
+ removing leading spaces, tabs, CR, and LF, begins `Accepted:`. Without a
375
+ grant nothing names Legion's own App logins, so this route closes a bot's thread only on its
376
+ opener's `Accepted:`: leave one the Legion reviewer accepted for the implementer's or merger's
377
+ run in a pane, or report it. For each thread to resolve:
365
378
 
366
379
  ```graphql
367
380
  mutation($threadId: ID!) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-legion-envoy",
3
- "version": "5.16.6",
3
+ "version": "5.16.8",
4
4
  "type": "module",
5
5
  "omp": {
6
6
  "extensions": [
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "legion": {
15
15
  "daemonApiVersion": 9,
16
- "goDaemonApiVersion": 10
16
+ "goDaemonApiVersion": 11
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",