@sjawhar/pi-envoy 10.5.0 → 10.6.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/dispatch.js CHANGED
@@ -14033,7 +14033,8 @@ var dispatchToolSpecs = [
14033
14033
  labels: z2.array(z2.string({ min: 1, max: 40 }), { max: 20 }).describe("Optional initial labels, at most 20 labels of up to 40 characters.").optional(),
14034
14034
  priority: z2.number({ int: true, min: 0, max: 3 }).describe("Optional coarse priority: P0 is highest and P3 is lowest.").optional(),
14035
14035
  assignee: z2.string().describe("Email of the person who answers this issue's asks (someone who has signed in to Dispatch); defaults to your owner when you act for a person, else the parent's assignee, else unassigned.").optional(),
14036
- components: componentsArgument(z2).optional()
14036
+ components: componentsArgument(z2).optional(),
14037
+ repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; a child inherits its parent's when unset, and an issue with none on its parent chain takes the project's default.").optional()
14037
14038
  })
14038
14039
  },
14039
14040
  {
@@ -14043,7 +14044,7 @@ var dispatchToolSpecs = [
14043
14044
  status: "done",
14044
14045
  reason: "Shipped in owner/repo#7; verified on the production dashboard."
14045
14046
  },
14046
- description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, or attach it to " + "architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. components " + "replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); everything else, priority " + "included, waits for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
14047
+ description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, attach it to " + "architecture components, or set the repository it targets. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. components " + "replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); everything else, priority " + "included, waits for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
14047
14048
  arguments: (z2) => ({
14048
14049
  issue: z2.string().describe(ISSUE_REFERENCE),
14049
14050
  status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
@@ -14055,15 +14056,16 @@ var dispatchToolSpecs = [
14055
14056
  route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
14056
14057
  parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
14057
14058
  blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Replacement list of issue keys in the same project this issue waits on; [] clears it. Dispatch refuses a dependency cycle.").optional(),
14058
- components: componentsArgument(z2).optional()
14059
+ components: componentsArgument(z2).optional(),
14060
+ repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; an empty string clears it, so the issue inherits its parent's or the project's default again.").optional()
14059
14061
  }),
14060
14062
  validation: {
14061
14063
  check: (value) => {
14062
14064
  const input = value;
14063
14065
  const reasonFits = input.status === "done" ? typeof input.reason === "string" && input.reason.trim() !== "" : input.reason === undefined;
14064
- return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null);
14066
+ return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null || typeof input.repo === "string");
14065
14067
  },
14066
- message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, or components. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
14068
+ message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, components, or repo. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
14067
14069
  },
14068
14070
  strict: true
14069
14071
  },
@@ -16846,6 +16848,31 @@ function progressText(progress, sep) {
16846
16848
  }
16847
16849
  return parts.join(sep);
16848
16850
  }
16851
+ function repositoryLine(issue2) {
16852
+ if (issue2.resolved_repo === undefined) {
16853
+ return "Repository: unknown (this Dispatch server predates repository fields; upgrade it)";
16854
+ }
16855
+ if (issue2.resolved_repo === null)
16856
+ return "Repository: none";
16857
+ if (issue2.repo !== null && issue2.repo !== undefined)
16858
+ return `Repository: ${issue2.repo} (own)`;
16859
+ return `Repository: ${issue2.resolved_repo} (inherited or project default)`;
16860
+ }
16861
+ function repositoryFieldsWarnings(issue2) {
16862
+ if (issue2.resolved_repo !== undefined)
16863
+ return {};
16864
+ return {
16865
+ warnings: [
16866
+ `dispatch: warning: Dispatch issue is missing resolved_repo: this Dispatch server predates repository fields, so ${issue2.key}'s repository is unknown; upgrade the server`
16867
+ ]
16868
+ };
16869
+ }
16870
+ function refuseUnsavedRepository(verb, issue2, repo2) {
16871
+ if (repo2 === undefined || issue2.repo !== undefined)
16872
+ return;
16873
+ const lost = repo2 === "" ? "the repository was not cleared" : `${repo2} was not saved`;
16874
+ throw new Error(`Dispatch ${verb} ${issue2.key} without its repository: this Dispatch server predates repository fields, so ${lost}; upgrade the server`);
16875
+ }
16849
16876
  function issueSummary(issue2, events, references, graph, linkBase, titles) {
16850
16877
  const asks = issue2.open_asks;
16851
16878
  const spec = issue2.artifacts?.find((artifact) => artifact.primary);
@@ -16872,6 +16899,7 @@ function issueSummary(issue2, events, references, graph, linkBase, titles) {
16872
16899
  `Labels: ${issue2.labels.length === 0 ? "none" : issue2.labels.join(", ")}`,
16873
16900
  componentsLine(issue2.components),
16874
16901
  `Route: ${routeText(issue2, titles)}`,
16902
+ repositoryLine(issue2),
16875
16903
  `Progress: ${progressText(issue2.progress, ", ") || "none"}`,
16876
16904
  ...specApproval === undefined ? [] : [`Spec ${specApproval.replace(/^Approval/, "approval")}`],
16877
16905
  "External links:",
@@ -17427,6 +17455,7 @@ async function executeDispatchTool(input) {
17427
17455
  const priority = optionalPriority(args, "priority");
17428
17456
  const assignee = optionalString(args, "assignee");
17429
17457
  const components = optionalComponents(args, "components");
17458
+ const repo2 = optionalString(args, "repo");
17430
17459
  const labels = args.labels;
17431
17460
  const blockedBy = args.blocked_by;
17432
17461
  try {
@@ -17441,9 +17470,11 @@ async function executeDispatchTool(input) {
17441
17470
  ...priority === undefined ? {} : { priority },
17442
17471
  ...assignee === undefined ? {} : { assignee },
17443
17472
  ...components === undefined ? {} : { components },
17473
+ ...repo2 === undefined ? {} : { repo: repo2 },
17444
17474
  ...Array.isArray(labels) ? { labels } : {},
17445
17475
  actor
17446
17476
  });
17477
+ refuseUnsavedRepository("created", created, repo2);
17447
17478
  const componentGuidance = await architectureGuidance(client, created.project, created.components);
17448
17479
  const adviceLines = [
17449
17480
  ...renderAdvice(input.tool, created.key, created.advice, {
@@ -17492,6 +17523,7 @@ async function executeDispatchTool(input) {
17492
17523
  const route = optionalString(args, "route");
17493
17524
  const parent = optionalString(args, "parent");
17494
17525
  const components = optionalComponents(args, "components");
17526
+ const repo2 = optionalString(args, "repo");
17495
17527
  const priority = optionalPriority(args, "priority");
17496
17528
  const labels = Array.isArray(args.labels) ? args.labels : undefined;
17497
17529
  const blockedBy = Array.isArray(args.blocked_by) ? args.blocked_by : undefined;
@@ -17531,6 +17563,7 @@ async function executeDispatchTool(input) {
17531
17563
  ...parent === undefined ? {} : { parent: parent === "" ? null : parent },
17532
17564
  ...blockedBy === undefined ? {} : { blocked_by: blockedBy },
17533
17565
  ...components === undefined ? {} : { components },
17566
+ ...repo2 === undefined ? {} : { repo: repo2 === "" ? null : repo2 },
17534
17567
  ...sentLinks === undefined ? {} : { external_links: sentLinks },
17535
17568
  actor
17536
17569
  });
@@ -17545,6 +17578,7 @@ async function executeDispatchTool(input) {
17545
17578
  throw refusalWithCode(error48, taken, landed);
17546
17579
  throw withAccount(error48, landed);
17547
17580
  }
17581
+ refuseUnsavedRepository("updated", after, repo2);
17548
17582
  const linkCount = `(${after.external_links.length} ${after.external_links.length === 1 ? "link" : "links"})`;
17549
17583
  const changes = [
17550
17584
  ...closingNote === undefined ? [] : [`reason posted as message ${closingNote.id} (${closingNote.ref})`],
@@ -17560,7 +17594,10 @@ async function executeDispatchTool(input) {
17560
17594
  ...blockedBy === undefined ? [] : [
17561
17595
  after.blocked_by.length === 0 ? "blocked_by cleared" : `blocked by ${after.blocked_by.join(", ")}`
17562
17596
  ],
17563
- ...components === undefined ? [] : [componentsChange(components, after.components)]
17597
+ ...components === undefined ? [] : [componentsChange(components, after.components)],
17598
+ ...repo2 === undefined ? [] : [
17599
+ after.repo === null ? `repo cleared (resolves to ${after.resolved_repo ?? "none"})` : `repo -> ${after.repo}`
17600
+ ]
17564
17601
  ];
17565
17602
  const adviceLines = renderAdvice(input.tool, after.key, after.advice, {
17566
17603
  setsStatus: status !== undefined
@@ -18255,7 +18292,8 @@ ${trailer.join(`
18255
18292
  return {
18256
18293
  text: issueSummary(read.issue, read.events, references, [...pictures2.lines, ...graph], linkBase, titles),
18257
18294
  details: { issue: read.issue.key },
18258
- ...showImages(pictures2)
18295
+ ...showImages(pictures2),
18296
+ ...repositoryFieldsWarnings(read.issue)
18259
18297
  };
18260
18298
  }
18261
18299
  default:
@@ -19170,6 +19208,10 @@ async function runDispatchCli(argv, rawEnv, io) {
19170
19208
  ...io.fetchImpl === undefined ? {} : { fetchImpl: io.fetchImpl }
19171
19209
  });
19172
19210
  text = result.text;
19211
+ for (const warning of result.warnings ?? []) {
19212
+ io.stderr(`${warning}
19213
+ `);
19214
+ }
19173
19215
  try {
19174
19216
  for (const image of result.images ?? []) {
19175
19217
  const picture = writePicture(dir, image);
@@ -19211,6 +19253,7 @@ async function runDispatchCli(argv, rawEnv, io) {
19211
19253
  var readText = (path2) => readFileSync4(path2 === "-" ? 0 : path2, "utf-8");
19212
19254
  process.exit(await runDispatchCli(Bun.argv.slice(2), process.env, {
19213
19255
  stdout: (text) => process.stdout.write(text),
19256
+ stderr: (text) => process.stderr.write(text),
19214
19257
  readText,
19215
19258
  cwd: process.cwd()
19216
19259
  }));
package/dist/envoy.js CHANGED
@@ -30020,7 +30020,8 @@ var dispatchToolSpecs = [
30020
30020
  labels: z2.array(z2.string({ min: 1, max: 40 }), { max: 20 }).describe("Optional initial labels, at most 20 labels of up to 40 characters.").optional(),
30021
30021
  priority: z2.number({ int: true, min: 0, max: 3 }).describe("Optional coarse priority: P0 is highest and P3 is lowest.").optional(),
30022
30022
  assignee: z2.string().describe("Email of the person who answers this issue's asks (someone who has signed in to Dispatch); defaults to your owner when you act for a person, else the parent's assignee, else unassigned.").optional(),
30023
- components: componentsArgument(z2).optional()
30023
+ components: componentsArgument(z2).optional(),
30024
+ repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; a child inherits its parent's when unset, and an issue with none on its parent chain takes the project's default.").optional()
30024
30025
  })
30025
30026
  },
30026
30027
  {
@@ -30030,7 +30031,7 @@ var dispatchToolSpecs = [
30030
30031
  status: "done",
30031
30032
  reason: "Shipped in owner/repo#7; verified on the production dashboard."
30032
30033
  },
30033
- description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, or attach it to " + "architecture components. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. components " + "replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); everything else, priority " + "included, waits for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
30034
+ description: "Update an existing issue: move its lifecycle status, retitle it, replace its labels, set " + "its priority, link a URL (the pull request that delivers it, a run, a document), set its " + "route, set or clear its parent, replace the issues it is blocked by, attach it to " + "architecture components, or set the repository it targets. Status is one of " + `${ISSUE_STATUSES.join(", ")}; outside Legion, move it yourself as the work advances; inside ` + "Legion the daemon moves it. A non-empty external_links is " + "merged into the issue's existing links by URL, so linking the pull request you just opened " + "keeps every earlier link; an empty external_links removes every link instead. components " + "replaces the issue's own attachment. Closing an issue " + "(status done) requires reason, the note that says why: it is posted on the issue as a " + "message, then the issue closes, because a closed issue refuses messages, comments, and " + "artifacts; reason goes only with status done. A closed issue takes only rank, components, " + "a reopening status (any status but done), and an external_links write that adds no new " + "link (so a link can move to the issue that replaced it); everything else, priority " + "included, waits for the reopen. " + "priority is yours to set and a human overrides it; rank, the board's own order, is not " + "settable here. At least one " + `field besides issue is required. ${ISSUE_REFERENCE}`,
30034
30035
  arguments: (z2) => ({
30035
30036
  issue: z2.string().describe(ISSUE_REFERENCE),
30036
30037
  status: z2.enum(ISSUE_STATUSES).describe("New lifecycle status.").optional(),
@@ -30042,15 +30043,16 @@ var dispatchToolSpecs = [
30042
30043
  route: z2.string().describe("Route the issue to role:<name> or session:<id>; an empty string clears it.").optional(),
30043
30044
  parent: z2.string().describe("Parent issue key in the same project; an empty string clears the parent.").optional(),
30044
30045
  blocked_by: z2.array(z2.string({ min: 1 }), { max: MAX_ISSUE_BLOCKERS }).describe("Replacement list of issue keys in the same project this issue waits on; [] clears it. Dispatch refuses a dependency cycle.").optional(),
30045
- components: componentsArgument(z2).optional()
30046
+ components: componentsArgument(z2).optional(),
30047
+ repo: z2.string().describe("The repository the issue targets, owner/name, mapped to the issue's project in Settings; an empty string clears it, so the issue inherits its parent's or the project's default again.").optional()
30046
30048
  }),
30047
30049
  validation: {
30048
30050
  check: (value) => {
30049
30051
  const input = value;
30050
30052
  const reasonFits = input.status === "done" ? typeof input.reason === "string" && input.reason.trim() !== "" : input.reason === undefined;
30051
- return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null);
30053
+ return reasonFits && (typeof input.status === "string" || typeof input.title === "string" || Array.isArray(input.labels) || typeof input.priority === "number" || input.priority === null || Array.isArray(input.external_links) || typeof input.route === "string" || typeof input.parent === "string" || Array.isArray(input.blocked_by) || typeof input.components === "object" && input.components !== null || typeof input.repo === "string");
30052
30054
  },
30053
- message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, or components. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
30055
+ message: "Issue update requires at least one field besides issue: status, title, labels, priority, external_links, route, parent, blocked_by, components, or repo. " + "status done requires reason, a non-empty note saying why the issue is closing, posted on the issue before it closes because a closed issue refuses messages, comments, and artifacts; reason goes only with status done."
30054
30056
  },
30055
30057
  strict: true
30056
30058
  },
@@ -153,7 +153,7 @@ that GitHub issue or pull request. Only `dispatch issue` with `--external` creat
153
153
  `dispatch issue --external owner/repo#n --project <project> --title '<title>'` before addressing it.
154
154
 
155
155
  Create an issue for newly tracked work with `dispatch issue --project <KEY> --title '<title>'` (`dispatch issue --help` lists `--parent`, `--spec-file`, `--label`, `--priority` and the rest).
156
- Labels are optional: Dispatch trims them, preserves their case, and removes case-insensitive duplicates. `--priority` is yours on creation too — see [Priority is yours to set](skill://dispatch/references/issues.md). Set `--assignee` (the email of a person who has signed in to Dispatch) only when the human said who owns the work; otherwise the default above applies, so a child inherits its parent's assignee. It prints
156
+ Labels are optional: Dispatch trims them, preserves their case, and removes case-insensitive duplicates. `--priority` is yours on creation too — see [Priority is yours to set](skill://dispatch/references/issues.md). Set `--assignee` (the email of a person who has signed in to Dispatch) only when the human said who owns the work; otherwise the default above applies, so a child inherits its parent's assignee. Set `--repo <owner/name>` when the issue targets a repository other than the one it would inherit: its parent's, else the project's default; the repository must be mapped to the project in Settings, and `dispatch read` shows the one the issue resolves to on its `Repository:` line. It prints
157
157
  the new key; creating an issue does not subscribe you to it (see [Following](#following)). Use `dispatch issue` only to create an issue; never use it to park a question. When you pass a spec,
158
158
  follow [Writing a spec](#writing-a-spec).
159
159
 
@@ -85,12 +85,13 @@ issues you own as well as the root. An issue left at `triage` while work is unde
85
85
  Waiting for the deploy lane is not a status and is never announced.
86
86
 
87
87
  ```bash
88
- # PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL, or cleared by an empty list), route, parent, blocked_by
88
+ # PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL, or cleared by an empty list), route, parent, blocked_by, repo
89
89
  dispatch issue-update --issue PROJ-175 --status testing
90
90
  dispatch issue-update --issue PROJ-175 --status done --reason 'Shipped in owner/repo#7; verified on the production dashboard.'
91
91
  dispatch issue-update --issue PROJ-175 --priority 1 # 0–3; see Priority is yours to set
92
92
  dispatch issue-update --issue PROJ-175 --external-link https://github.com/owner/repo/pull/7
93
93
  dispatch issue-update --issue PROJ-175 --parent PROJ-170 # same-project key; --parent '' clears it
94
+ dispatch issue-update --issue PROJ-175 --repo acme/widgets # mapped to the project; --repo '' clears it
94
95
  ```
95
96
 
96
97
  Closing takes a `--reason`, and the command refuses `--status done` without one: it posts the reason on
@@ -100,9 +101,16 @@ error names the posted message; after a timeout or a server error it also says t
100
101
  landed, so read the issue's status first. A retry points its reason at the posted message rather
101
102
  than repeating it.
102
103
 
103
- The three clears differ: `--clear-priority` sends null, `--parent ''` and `--route ''` clear with an
104
- empty string, and `--clear-external-links` / `--clear-blocked-by` send an empty list. Guessing the
105
- wrong shape is a refusal either way.
104
+ The three clears differ: `--clear-priority` sends null, `--parent ''`, `--route ''` and
105
+ `--repo ''` clear with an empty string, and `--clear-external-links` / `--clear-blocked-by` send an
106
+ empty list. Guessing the wrong shape is a refusal either way.
107
+
108
+ An issue targets one repository: its own `--repo`, else its nearest ancestor's, else the project's
109
+ default (set on the Settings page), else none. A repository not mapped to the issue's project is
110
+ refused `REPO_NOT_MAPPED`, naming it. `dispatch read` prints the result as
111
+ `Repository: owner/name (own)`, `Repository: owner/name (inherited or project default)`, or
112
+ `Repository: none`. `Repository: unknown (…)` means the Dispatch server is older than repository
113
+ fields: the read still works, and a `--repo` write there fails rather than drop the repository.
106
114
 
107
115
  Link the pull request that delivers the issue with `--external-link` when you open it; the issue page
108
116
  renders its state and checks from that link, and `dispatch read` lists it under `External links:`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-envoy",
3
- "version": "10.5.0",
3
+ "version": "10.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "omp": {