orbit-code-ai 0.1.40 → 0.1.41

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.
Files changed (3) hide show
  1. package/README.md +32 -0
  2. package/dist/cli.mjs +415 -88
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -107,6 +107,38 @@ Built-in reference docs loaded into every session:
107
107
 
108
108
  ---
109
109
 
110
+ ## LLD → APIC artifacts
111
+
112
+ Turn a middleware **Low-Level Design** (`.docx`) into deployable artifacts. `/lld` reads the Word
113
+ document (paragraphs **and** tables), extracts the API spec against the house template, shows you an
114
+ extraction summary to confirm, then generates any combination of:
115
+
116
+ ```
117
+ /lld "C:\path\to\LLD_MyApi.docx" [contract] [api] [diagram] # or: both | all (default: all)
118
+ ```
119
+
120
+ - **contract** → a contract-only OpenAPI (rich request/response/error schemas) via `/api-contract`
121
+ - **api** → the APIC gateway definition (`x-ibm-configuration` assembly) via `/apic-api`
122
+ — supports a `backend` pattern (APIC wraps a raw backend in the ESB envelope) and a `wrapper`
123
+ pattern (a thin proxy over an existing ACE/webMethods service that already returns the envelope)
124
+ - **diagram** → the **Integration Service Flow** as a `.drawio` file (BIDAYA activity-diagram house
125
+ style) via `/drawio`
126
+
127
+ The diagram is drawn deterministically from a small flow model, and branches reflect the LLD:
128
+
129
+ - a **token** branch (access-token call cached until the JWT `exp`) appears only when auth is
130
+ token-based — omitted for no-auth / static-key services;
131
+ - a **cache** branch appears only when the MW caches the response — omitted when the LLD says
132
+ "Cache: Not applicable";
133
+ - the **success/error** decision uses the LLD's actual success rule (e.g. `HTTP 200`, or a body
134
+ status code like `eigerResultCode = 200`), feeding green (success) / red (error) mapping boxes.
135
+
136
+ Output opens directly in [diagrams.net](https://app.diagrams.net) with the house style: green
137
+ swimlanes, blue action parallelograms, pink decision diamonds, green/red mapping boxes, a yellow
138
+ START ellipse and a red-ringed final node.
139
+
140
+ ---
141
+
110
142
  ## Agent Routing
111
143
 
112
144
  Route different agent tasks to different models. Define each model's connection in `agentModels`, then map agents (or `default`) to those names in `agentRouting`. Every name used in `agentRouting` must exist in `agentModels`:
package/dist/cli.mjs CHANGED
@@ -83818,7 +83818,7 @@ async function printStartupScreen() {
83818
83818
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
83819
83819
  out.push(boxRow(sRow, W2, sLen));
83820
83820
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W2 - 2)}╝${RESET}`);
83821
- out.push(` ${DIM}${rgb(...DIMCOL)}orbit-code ${RESET}${rgb(...ACCENT)}v${"0.1.40"}${RESET}`);
83821
+ out.push(` ${DIM}${rgb(...DIMCOL)}orbit-code ${RESET}${rgb(...ACCENT)}v${"0.1.41"}${RESET}`);
83822
83822
  out.push("");
83823
83823
  process.stdout.write(out.join(`
83824
83824
  `) + `
@@ -334342,7 +334342,7 @@ function getAnthropicEnvMetadata() {
334342
334342
  function getBuildAgeMinutes() {
334343
334343
  if (false)
334344
334344
  ;
334345
- const buildTime = new Date("2026-07-22T07:54:15.011Z").getTime();
334345
+ const buildTime = new Date("2026-07-23T10:01:27.244Z").getTime();
334346
334346
  if (isNaN(buildTime))
334347
334347
  return;
334348
334348
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -358759,7 +358759,7 @@ function buildPrimarySection() {
358759
358759
  }, undefined, false, undefined, this);
358760
358760
  return [{
358761
358761
  label: "Version",
358762
- value: "0.1.40"
358762
+ value: "0.1.41"
358763
358763
  }, {
358764
358764
  label: "Session name",
358765
358765
  value: nameValue
@@ -471068,7 +471068,7 @@ function WelcomeV2() {
471068
471068
  dimColor: true,
471069
471069
  children: [
471070
471070
  "v",
471071
- "0.1.40",
471071
+ "0.1.41",
471072
471072
  " "
471073
471073
  ]
471074
471074
  }, undefined, true, undefined, this)
@@ -471268,7 +471268,7 @@ function WelcomeV2() {
471268
471268
  dimColor: true,
471269
471269
  children: [
471270
471270
  "v",
471271
- "0.1.40",
471271
+ "0.1.41",
471272
471272
  " "
471273
471273
  ]
471274
471274
  }, undefined, true, undefined, this)
@@ -471494,7 +471494,7 @@ function AppleTerminalWelcomeV2(t0) {
471494
471494
  dimColor: true,
471495
471495
  children: [
471496
471496
  "v",
471497
- "0.1.40",
471497
+ "0.1.41",
471498
471498
  " "
471499
471499
  ]
471500
471500
  }, undefined, true, undefined, this);
@@ -471748,7 +471748,7 @@ function AppleTerminalWelcomeV2(t0) {
471748
471748
  dimColor: true,
471749
471749
  children: [
471750
471750
  "v",
471751
- "0.1.40",
471751
+ "0.1.41",
471752
471752
  " "
471753
471753
  ]
471754
471754
  }, undefined, true, undefined, this);
@@ -475773,6 +475773,250 @@ var init_aceSkills = __esm(() => {
475773
475773
  init_bundledSkills();
475774
475774
  });
475775
475775
 
475776
+ // src/utils/drawio/drawioFlow.ts
475777
+ function escapeXml2(s) {
475778
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
475779
+ }
475780
+ function labelValue(label) {
475781
+ return label.split(/\r?\n/).map(escapeXml2).join("&lt;br&gt;");
475782
+ }
475783
+ function laneHeight(name) {
475784
+ const n2 = name.toUpperCase();
475785
+ if (n2 === "CONSUMER")
475786
+ return 320;
475787
+ if (n2 === "MW" || n2 === "MIDDLEWARE")
475788
+ return 860;
475789
+ return 320;
475790
+ }
475791
+ function validateModel2(model) {
475792
+ if (!model.lanes?.length)
475793
+ throw new Error("FlowModel needs at least one lane.");
475794
+ if (!model.nodes?.length)
475795
+ throw new Error("FlowModel needs at least one node.");
475796
+ const laneSet = new Set(model.lanes);
475797
+ const ids = new Set;
475798
+ for (const n2 of model.nodes) {
475799
+ if (ids.has(n2.id))
475800
+ throw new Error(`Duplicate node id: ${n2.id}`);
475801
+ ids.add(n2.id);
475802
+ if (!laneSet.has(n2.lane))
475803
+ throw new Error(`Node "${n2.id}" is in unknown lane "${n2.lane}".`);
475804
+ }
475805
+ for (const e2 of model.edges ?? []) {
475806
+ if (!ids.has(e2.source))
475807
+ throw new Error(`Edge source "${e2.source}" is not a known node id.`);
475808
+ if (!ids.has(e2.target))
475809
+ throw new Error(`Edge target "${e2.target}" is not a known node id.`);
475810
+ }
475811
+ }
475812
+ function layout(model) {
475813
+ const laneBands = [];
475814
+ let y2 = 0;
475815
+ for (const name of model.lanes) {
475816
+ const h2 = laneHeight(name);
475817
+ laneBands.push({ name, y: y2, h: h2 });
475818
+ y2 += h2;
475819
+ }
475820
+ const pageH = y2;
475821
+ const bandOf = (lane) => laneBands.find((b) => b.name === lane);
475822
+ const rects = new Map;
475823
+ for (const band of laneBands) {
475824
+ const laneNodes = model.nodes.filter((n2) => n2.lane === band.name);
475825
+ const isMW = band.name.toUpperCase() === "MW" || band.name.toUpperCase() === "MIDDLEWARE";
475826
+ if (isMW) {
475827
+ let cy = band.y + 40;
475828
+ for (let i3 = 0;i3 < laneNodes.length; i3++) {
475829
+ const n2 = laneNodes[i3];
475830
+ const s = SIZE[n2.kind];
475831
+ const next = laneNodes[i3 + 1];
475832
+ if (n2.kind === "success" && next && next.kind === "error") {
475833
+ rects.set(n2.id, { x: NODE_X0, y: cy, w: s.w, h: s.h });
475834
+ const s2 = SIZE[next.kind];
475835
+ rects.set(next.id, { x: NODE_X0 + s.w + 90, y: cy, w: s2.w, h: s2.h });
475836
+ i3++;
475837
+ cy += Math.max(s.h, s2.h) + 55;
475838
+ } else {
475839
+ rects.set(n2.id, { x: NODE_X0, y: cy, w: s.w, h: s.h });
475840
+ cy += s.h + 55;
475841
+ }
475842
+ }
475843
+ } else {
475844
+ let cx = NODE_X0;
475845
+ const midY = band.y + band.h / 2;
475846
+ for (const n2 of laneNodes) {
475847
+ const s = SIZE[n2.kind];
475848
+ rects.set(n2.id, { x: cx, y: Math.round(midY - s.h / 2), w: s.w, h: s.h });
475849
+ cx += s.w + 70;
475850
+ }
475851
+ }
475852
+ }
475853
+ return { laneBands, rects, pageH };
475854
+ }
475855
+ function anchors(a2, b) {
475856
+ const ac = { x: a2.x + a2.w / 2, y: a2.y + a2.h / 2 };
475857
+ const bc = { x: b.x + b.w / 2, y: b.y + b.h / 2 };
475858
+ const dx = bc.x - ac.x;
475859
+ const dy = bc.y - ac.y;
475860
+ let ex, ey, nx, ny;
475861
+ if (Math.abs(dy) >= Math.abs(dx)) {
475862
+ if (dy >= 0) {
475863
+ ex = 0.5;
475864
+ ey = 1;
475865
+ nx = 0.5;
475866
+ ny = 0;
475867
+ } else {
475868
+ ex = 0.5;
475869
+ ey = 0;
475870
+ nx = 0.5;
475871
+ ny = 1;
475872
+ }
475873
+ } else if (dx >= 0) {
475874
+ ex = 1;
475875
+ ey = 0.5;
475876
+ nx = 0;
475877
+ ny = 0.5;
475878
+ } else {
475879
+ ex = 0;
475880
+ ey = 0.5;
475881
+ nx = 1;
475882
+ ny = 0.5;
475883
+ }
475884
+ return `exitX=${ex};exitY=${ey};exitDx=0;exitDy=0;entryX=${nx};entryY=${ny};entryDx=0;entryDy=0;`;
475885
+ }
475886
+ function generateDrawioFlow(model) {
475887
+ validateModel2(model);
475888
+ const { laneBands, rects, pageH } = layout(model);
475889
+ const cells = ['<mxCell id="0"/>', '<mxCell id="1" parent="0"/>'];
475890
+ laneBands.forEach((b, i3) => {
475891
+ cells.push(`<mxCell id="lane${i3}" value="${escapeXml2(b.name)}" style="${LANE_STYLE}" vertex="1" parent="1">` + `<mxGeometry x="0" y="${b.y}" width="${PAGE_W}" height="${b.h}" as="geometry"/></mxCell>`);
475892
+ });
475893
+ for (const n2 of model.nodes) {
475894
+ const r = rects.get(n2.id);
475895
+ const value = n2.kind === "end" ? "" : labelValue(n2.label);
475896
+ cells.push(`<mxCell id="${escapeXml2(n2.id)}" value="${value}" style="${STYLE[n2.kind]}" vertex="1" parent="1">` + `<mxGeometry x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" as="geometry"/></mxCell>`);
475897
+ }
475898
+ model.edges?.forEach((e2, i3) => {
475899
+ const sr = rects.get(e2.source);
475900
+ const tr = rects.get(e2.target);
475901
+ const style = EDGE_STYLE + anchors(sr, tr);
475902
+ cells.push(`<mxCell id="e${i3}" value="${e2.label ? labelValue(e2.label) : ""}" style="${style}" edge="1" parent="1" source="${escapeXml2(e2.source)}" target="${escapeXml2(e2.target)}">` + `<mxGeometry relative="1" as="geometry"/></mxCell>`);
475903
+ });
475904
+ const name = escapeXml2(`${model.apiName} Integration Flow`);
475905
+ return `<mxfile host="app.diagrams.net" version="24.0.0">` + `<diagram name="${name}" id="flow">` + `<mxGraphModel dx="1200" dy="1500" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="${PAGE_W}" pageHeight="${pageH}" math="0" shadow="0">` + `<root>${cells.join("")}</root>` + `</mxGraphModel></diagram></mxfile>`;
475906
+ }
475907
+ var LANE_STYLE = "swimlane;html=1;horizontal=0;startSize=32;fillColor=#3FA34D;swimlaneFillColor=#FFFFFF;strokeColor=#000000;fontColor=#FFFFFF;fontStyle=1;fontSize=13;verticalAlign=middle;", STYLE, EDGE_STYLE = "edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=classic;strokeColor=#000000;fontColor=#000000;fontStyle=1;fontSize=11;", PAGE_W = 1090, LANE_TITLE = 32, NODE_X0, SIZE;
475908
+ var init_drawioFlow = __esm(() => {
475909
+ STYLE = {
475910
+ action: "shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fillColor=#7EA6E0;strokeColor=#3B5A9A;fontColor=#000000;fontStyle=1;",
475911
+ success: "shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fillColor=#8FCB5E;strokeColor=#5E8A34;fontColor=#000000;fontStyle=1;",
475912
+ error: "shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fillColor=#FF2020;strokeColor=#B20000;fontColor=#FFFFFF;fontStyle=1;",
475913
+ decision: "rhombus;whiteSpace=wrap;html=1;fillColor=#F8CECC;strokeColor=#D48A8A;fontColor=#000000;fontStyle=1;",
475914
+ start: "ellipse;whiteSpace=wrap;html=1;fillColor=#FFF176;strokeColor=#B8A400;fontColor=#000000;fontStyle=1;",
475915
+ end: "ellipse;shape=endState;fillColor=#000000;strokeColor=#FF0000;strokeWidth=2;"
475916
+ };
475917
+ NODE_X0 = LANE_TITLE + 40;
475918
+ SIZE = {
475919
+ start: { w: 90, h: 50 },
475920
+ end: { w: 30, h: 30 },
475921
+ action: { w: 190, h: 60 },
475922
+ success: { w: 200, h: 64 },
475923
+ error: { w: 200, h: 64 },
475924
+ decision: { w: 180, h: 90 }
475925
+ };
475926
+ });
475927
+
475928
+ // src/skills/bundled/drawio.ts
475929
+ import { writeFileSync as writeFileSync5 } from "fs";
475930
+ import { join as join127 } from "path";
475931
+ function textBlock(text) {
475932
+ return [{ type: "text", text }];
475933
+ }
475934
+ function sanitizeStem(s) {
475935
+ return s.trim().replace(/\.docx$/i, "").replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "") || "API";
475936
+ }
475937
+ function handle(args) {
475938
+ const trimmed = args.trim();
475939
+ if (!trimmed || trimmed.toLowerCase() === "help")
475940
+ return HELP;
475941
+ let model;
475942
+ try {
475943
+ model = JSON.parse(trimmed);
475944
+ } catch (e2) {
475945
+ return `/drawio expects a single JSON FlowModel argument, but JSON.parse failed: ${e2.message}
475946
+
475947
+ ${HELP}`;
475948
+ }
475949
+ let xml;
475950
+ try {
475951
+ xml = generateDrawioFlow(model);
475952
+ } catch (e2) {
475953
+ return `The flow model is invalid: ${e2.message}
475954
+
475955
+ Fix the model (check node ids, lanes, and edge endpoints) and call /drawio again.`;
475956
+ }
475957
+ const stem = sanitizeStem(model.fileStem || model.apiName || "API");
475958
+ const filename = `${stem}_Integration_Flow.drawio`;
475959
+ try {
475960
+ writeFileSync5(join127(process.cwd(), filename), xml, "utf8");
475961
+ } catch (e2) {
475962
+ return `Generated valid diagram XML but could not write ${filename}: ${e2.message}.
475963
+ Save this content manually as ${filename}:
475964
+
475965
+ ${xml}`;
475966
+ }
475967
+ return `✓ Integration-flow diagram written → ${filename}
475968
+
475969
+ lanes: ${model.lanes.join(" / ")}
475970
+ nodes: ${model.nodes.length} edges: ${model.edges?.length ?? 0}
475971
+
475972
+ Opens in diagrams.net (app.diagrams.net). Tell the user the file was created at ${filename} and summarize the flow branches it drew (token/cache/success-error) based on the model.`;
475973
+ }
475974
+ function registerDrawioSkill() {
475975
+ registerBundledSkill({
475976
+ name: "drawio",
475977
+ description: "Render an integration-flow semantic model (JSON: lanes/nodes/edges) into a .drawio activity diagram in the BIDAYA house style, written next to the other artifacts. Deterministic layout + XML; used by /lld to emit the Integration Service Flow diagram.",
475978
+ whenToUse: "After extracting an integration-flow semantic model from an LLD (usually via /lld ... diagram), to write the .drawio diagram file. Pass the JSON FlowModel as the argument.",
475979
+ argumentHint: "<json flow model>",
475980
+ userInvocable: true,
475981
+ allowedTools: [],
475982
+ async getPromptForCommand(args) {
475983
+ try {
475984
+ return textBlock(handle(args));
475985
+ } catch (e2) {
475986
+ return textBlock(`/drawio error: ${e2.message}`);
475987
+ }
475988
+ }
475989
+ });
475990
+ }
475991
+ var HELP = `# /drawio — render an integration-flow semantic model to a .drawio diagram
475992
+
475993
+ Usage:
475994
+ /drawio <json flow model>
475995
+
475996
+ The argument is a JSON FlowModel:
475997
+ {
475998
+ "apiName": "Commodity API",
475999
+ "fileStem": "LLD_CommodityAPI", // optional; output = <fileStem>_Integration_Flow.drawio
476000
+ "lanes": ["CONSUMER", "MW", "Eiger"], // top→bottom; MW gets the tallest lane
476001
+ "nodes": [
476002
+ { "id": "start", "kind": "start", "lane": "CONSUMER", "label": "START" },
476003
+ { "id": "send", "kind": "action", "lane": "CONSUMER", "label": "send request to MW" },
476004
+ { "id": "dec", "kind": "decision","lane": "MW", "label": "Valid access token?" },
476005
+ { "id": "ok", "kind": "success", "lane": "MW", "label": "Map success..." },
476006
+ { "id": "err", "kind": "error", "lane": "MW", "label": "Map error..." },
476007
+ { "id": "end", "kind": "end", "lane": "CONSUMER", "label": "" }
476008
+ ],
476009
+ "edges": [ { "source": "start", "target": "send", "label": "" } ]
476010
+ }
476011
+
476012
+ kind ∈ start | action | decision | success | error | end. This skill lays out the nodes and writes
476013
+ the .drawio file in the BIDAYA house style (green lanes, blue parallelograms, pink diamonds,
476014
+ green/red mapping boxes, START ellipse, red-ringed final node).`;
476015
+ var init_drawio = __esm(() => {
476016
+ init_bundledSkills();
476017
+ init_drawioFlow();
476018
+ });
476019
+
475776
476020
  // src/utils/docx.ts
475777
476021
  import { readFileSync as readFileSync10 } from "fs";
475778
476022
  function escapeReg(s) {
@@ -475943,7 +476187,7 @@ async function extractDocxText(filePath, maxChars = 60000) {
475943
476187
  var init_docx = () => {};
475944
476188
 
475945
476189
  // src/skills/bundled/lld.ts
475946
- function textBlock(text) {
476190
+ function textBlock2(text) {
475947
476191
  return [{ type: "text", text }];
475948
476192
  }
475949
476193
  function parseArgs(args) {
@@ -475963,22 +476207,90 @@ function parseArgs(args) {
475963
476207
  rest = trimmed;
475964
476208
  }
475965
476209
  }
475966
- const t = rest.match(/\b(contract|api|both)\b/i)?.[1]?.toLowerCase();
475967
- const target = t === "contract" || t === "api" ? t : "both";
475968
- return { path: path20.replace(/[.,;]$/, ""), target };
476210
+ const kw = rest.toLowerCase();
476211
+ const c6 = /\bcontract\b/.test(kw);
476212
+ const a2 = /\bapi\b/.test(kw);
476213
+ const d = /\b(diagram|drawio|flow)\b/.test(kw);
476214
+ const both = /\bboth\b/.test(kw);
476215
+ const all4 = /\ball\b/.test(kw);
476216
+ const want = all4 || !c6 && !a2 && !d && !both ? { contract: true, api: true, diagram: true } : { contract: c6 || both, api: a2 || both, diagram: d };
476217
+ return { path: path20.replace(/[.,;]$/, ""), want };
475969
476218
  }
475970
- function buildPrompt(path20, content, target) {
475971
- const gen = target === "contract" ? "the CONTRACT only (invoke /api-contract)" : target === "api" ? "the GATEWAY API only (invoke /apic-api)" : "BOTH the contract (/api-contract) and the gateway API (/apic-api)";
475972
- return `You are turning an LLD (Low-Level Design) Word document into APIC artifacts. The full LLD text
475973
- below was extracted from ${path20} (paragraphs as text, tables as markdown). Requested output: ${gen}.
475974
-
475975
- ════════════════════ EXTRACTED LLD ════════════════════
475976
- ${content}
475977
- ════════════════════ END LLD ════════════════════
475978
-
475979
- Do this, in order:
475980
-
475981
- 1. EXTRACT the API spec from the LLD above, using this house-template map (sections/tables → fields):
476219
+ function buildPrompt(path20, content, want) {
476220
+ const parts = [];
476221
+ if (want.contract)
476222
+ parts.push("the CONTRACT (invoke /api-contract)");
476223
+ if (want.api)
476224
+ parts.push("the GATEWAY API (invoke /apic-api)");
476225
+ if (want.diagram)
476226
+ parts.push("the INTEGRATION-FLOW DIAGRAM (build a flow model, then invoke /drawio)");
476227
+ const gen = parts.join(", ");
476228
+ const diagramSection = want.diagram ? `
476229
+
476230
+ ── INTEGRATION-FLOW DIAGRAM ──
476231
+ Also produce the "Integration Service Flow" diagram (the LLD's Figure 1) as a .drawio file. Build a
476232
+ SEMANTIC flow model from the SAME extracted LLD, then invoke the /drawio skill with it as JSON —
476233
+ /drawio does the layout + XML + file write; you only supply the model.
476234
+
476235
+ Model shape (pass as one JSON object to /drawio):
476236
+ { "apiName": "...", "fileStem": "<the LLD file name, no extension>",
476237
+ "lanes": ["CONSUMER", "MW", "<Provider>"], // top→bottom; MW is the middle/tallest lane
476238
+ "nodes": [ { "id","kind","lane","label" } ], // kind ∈ start|action|decision|success|error|end
476239
+ "edges": [ { "source","target","label" } ] }
476240
+
476241
+ Build the flow with these rules — include a branch ONLY when the LLD supports it:
476242
+ CONSUMER lane: start "START" → action "send request to MW"; action "Receive MW response" → end node.
476243
+ MW lane:
476244
+ - If the MW caches the RESPONSE (LLD says so; if it says "Cache: Not applicable", OMIT this):
476245
+ decision "Check cache (payload in last N min)?" → True path returns a green success
476246
+ "get response from cache and return to consumer" → Receive MW response; False path continues.
476247
+ - If auth is TOKEN-BASED (the MW calls an access-token/login op and caches the JWT until exp):
476248
+ decision "Valid access token in cache? (exp not passed)" → True → action "send request to
476249
+ <Provider> (<operation>)"; False → (Provider lane) action "invoke <Provider> Access Token
476250
+ service (get JWT, cache until exp)" → back to "send request to <Provider>".
476251
+ If NO auth / static keys: OMIT the token decision and the Access Token node entirely.
476252
+ - action "send request to <Provider>" → (Provider lane) action "invoke <Provider> <operation>".
476253
+ - provider returns → action "MW will receive BE Response".
476254
+ - decision "Check body status (<the LLD's actual success rule, e.g. eigerResultCode = 200>)?":
476255
+ success edge → green success "Map the success response and send to consumer" → Receive MW response
476256
+ error edge → red error "Map the error response and send to consumer" → Receive MW response
476257
+ <Provider> lane: holds "invoke ... Access Token service" (only if token-based) and
476258
+ "invoke ... <operation>"; the operation's "2xx"/"non-2xx" (or Success/Failure) edges return to
476259
+ "MW will receive BE Response".
476260
+
476261
+ ONE diagram per LLD representing the common MW pattern. If operations diverge (e.g. one cached, one
476262
+ not), pick the richest common flow and label the operation box "<op1> | <op2>". Use success/error
476263
+ mapping boxes for the mapping steps. Every edge's source/target must be a node id you defined.
476264
+ ` : "";
476265
+ const onlyDiagram = want.diagram && !want.contract && !want.api;
476266
+ const asks = [];
476267
+ if (want.contract || want.api)
476268
+ asks.push("OpenAPI version — 2.0 or 3.0");
476269
+ if (want.contract)
476270
+ asks.push("inbound consumer auth scheme (basic / apikey / oauth2)", "API host (e.g. api.example.com)");
476271
+ if (want.api)
476272
+ asks.push("integration pattern — wrapper (thin proxy over an ACE/webMethods service) vs backend (APIC calls the raw backend)", "JWT validation on/off (and the crypto object name if on)", "the backend target-url variable / endpoint");
476273
+ const asksBlock = asks.length ? `Then ask the user ONLY for these unguessables (they are needed for the requested output):
476274
+ - ${asks.join(`
476275
+ - `)}
476276
+ NEVER fabricate hosts, crypto objects, scopes, or business fields — ask, or use clearly-marked
476277
+ CHANGEME placeholders and list them.` : `Do NOT ask for any unguessables. A diagram-only request is fully derived from the LLD (the
476278
+ operations, provider, whether auth is token-based, cache behaviour, and the success rule are all in
476279
+ the document). Do NOT ask about OpenAPI version, host, auth scheme, JWT, crypto, or backend URLs —
476280
+ none of those are needed to draw the flow.`;
476281
+ const notRequested = [];
476282
+ if (!want.contract)
476283
+ notRequested.push("/api-contract");
476284
+ if (!want.api)
476285
+ notRequested.push("/apic-api");
476286
+ if (!want.diagram)
476287
+ notRequested.push("/drawio");
476288
+ const scopeLine = `Produce ONLY: ${gen}.` + (notRequested.length ? ` Do NOT invoke ${notRequested.join(" or ")}, and do NOT ask for details only those skills need.` : "");
476289
+ const extractStep = onlyDiagram ? `1. EXTRACT only the FLOW-relevant facts from the LLD (you do NOT need the request/response field
476290
+ models for a diagram): the operation(s) (name, verb, gateway endpoint); the provider(s); whether the
476291
+ MW obtains and CACHES an access token (→ token-based auth) or uses static/no auth; whether the MW
476292
+ caches the RESPONSE (or says "Cache: Not applicable"); and the success rule (e.g. HTTP 200, or a body
476293
+ status code like eigerResultCode = 200).` : `1. EXTRACT the API spec from the LLD above, using this house-template map (sections/tables → fields):
475982
476294
  - Introduction (Purpose / Scope) → API title + description.
475983
476295
  - "Integration flow (<op>)" → its "API Gateway endpoint" and "Method" → the operation path + verb.
475984
476296
  - "<op> Request" table → request model. Columns are typically Field | Type | Occurrence | Length |
@@ -475990,30 +476302,42 @@ Do this, in order:
475990
476302
  - "Annex / Provider" (endpoints, auth) → the backend/provider endpoint(s) and their auth.
475991
476303
  - Integration pattern: if the middleware is an existing ACE/webMethods service that already returns
475992
476304
  the response envelope, it is a **wrapper**; if APIC calls a raw backend and must build the
475993
- envelope, it is **backend**. State which and why.
476305
+ envelope, it is **backend**. State which and why.`;
476306
+ const genBullets = [];
476307
+ if (want.contract)
476308
+ genBullets.push(` - Contract → invoke /api-contract with the API name, host, security, and the full request/response/error models.`);
476309
+ if (want.api)
476310
+ genBullets.push(` - Gateway API → invoke /apic-api per operation with the verb, basePath, explicit path, --pattern, backend target-url, and flags.`);
476311
+ if (want.diagram)
476312
+ genBullets.push(` - Integration-flow diagram → build the JSON flow model per the DIAGRAM rules above and invoke /drawio. Report the .drawio file it wrote.`);
476313
+ return `You are turning an LLD (Low-Level Design) Word document into APIC artifacts. The full LLD text
476314
+ below was extracted from ${path20} (paragraphs as text, tables as markdown).
475994
476315
 
475995
- 2. ECHO a concise EXTRACTION SUMMARY to the user FIRST (do NOT generate yet): API name, pattern,
475996
- each operation (verb + path), request/response field lists, error codes, backend endpoint, and the
475997
- fields you could NOT determine. Then ask for the unguessables only: OpenAPI 2.0 vs 3.0; inbound
475998
- consumer auth (basic/apikey/oauth2); host; and (for /apic-api) JWT on/off + crypto object and the
475999
- backend target-url variable. NEVER fabricate hosts, crypto objects, scopes, or business fields — ask
476000
- or use clearly-marked CHANGEME placeholders and list them.
476316
+ **SCOPE: ${scopeLine}**${diagramSection}
476317
+
476318
+ ════════════════════ EXTRACTED LLD ════════════════════
476319
+ ${content}
476320
+ ════════════════════ END LLD ════════════════════
476321
+
476322
+ Do this, in order:
476323
+
476324
+ ${extractStep}
476325
+
476326
+ 2. ECHO a concise EXTRACTION SUMMARY to the user FIRST (do NOT generate yet), covering only what the
476327
+ requested output needs. ${asksBlock}
476001
476328
 
476002
476329
  3. After the user confirms/corrects, GENERATE ${gen}:
476003
- - Contract → invoke the /api-contract skill, passing the API name, host, security, and the full
476004
- request/response/error models you extracted.
476005
- - Gateway API → invoke the /apic-api skill, passing the operation (name, verb, basePath, explicit
476006
- path), the chosen --pattern (wrapper vs backend), the backend target-url, and the flags. One
476007
- /apic-api call per operation.
476330
+ ${genBullets.join(`
476331
+ `)}
476008
476332
  Reuse the values from the extraction summary verbatim — do not re-derive or drop fields.
476009
476333
 
476010
476334
  Ground everything in the extracted LLD above; if the LLD does not state something, say so rather than
476011
476335
  inventing it.`;
476012
476336
  }
476013
- async function handle(args) {
476014
- const { path: path20, target } = parseArgs(args);
476337
+ async function handle2(args) {
476338
+ const { path: path20, want } = parseArgs(args);
476015
476339
  if (!path20)
476016
- return HELP;
476340
+ return HELP2;
476017
476341
  let content;
476018
476342
  try {
476019
476343
  content = await extractDocxText(path20);
@@ -476026,33 +476350,34 @@ Give the full path to a .docx file, e.g.
476026
476350
  if (!content.trim()) {
476027
476351
  return `The LLD at "${path20}" extracted no text (it may be image-only or empty). I can't generate from it — confirm the file, or paste the request/response models directly.`;
476028
476352
  }
476029
- return buildPrompt(path20, content, target);
476353
+ return buildPrompt(path20, content, want);
476030
476354
  }
476031
476355
  function registerLldSkill() {
476032
476356
  registerBundledSkill({
476033
476357
  name: "lld",
476034
476358
  description: "Read an LLD (.docx) Word document — paragraphs and tables — extract the API spec against the house template, confirm it, then generate the contract-only OpenAPI (/api-contract) and/or the APIC gateway API (/apic-api) from it.",
476035
476359
  whenToUse: "When the user points at an LLD .docx and wants the APIC contract and/or gateway API generated from it (LLD → YAML).",
476036
- argumentHint: '"<path-to-LLD.docx>" [contract|api|both]',
476360
+ argumentHint: '"<path-to-LLD.docx>" [contract|api|diagram|both|all]',
476037
476361
  userInvocable: true,
476038
476362
  allowedTools: ["Read", "Glob", "Grep"],
476039
476363
  async getPromptForCommand(args) {
476040
476364
  try {
476041
- return textBlock(await handle(args));
476365
+ return textBlock2(await handle2(args));
476042
476366
  } catch (e2) {
476043
- return textBlock(`/lld error: ${e2.message}`);
476367
+ return textBlock2(`/lld error: ${e2.message}`);
476044
476368
  }
476045
476369
  }
476046
476370
  });
476047
476371
  }
476048
- var HELP = `# /lld — read an LLD (.docx) and generate the APIC contract and/or gateway API
476372
+ var HELP2 = `# /lld — read an LLD (.docx) and generate APIC contract / gateway API / flow diagram
476049
476373
 
476050
476374
  Usage:
476051
- /lld "<path-to-LLD.docx>" [contract|api|both]
476375
+ /lld "<path-to-LLD.docx>" [contract] [api] [diagram] | both | all
476052
476376
 
476053
- - contract → generate the contract-only OpenAPI via /api-contract
476054
- - api → generate the gateway implementation via /apic-api
476055
- - both generate both (default)
476377
+ - contract → contract-only OpenAPI via /api-contract
476378
+ - api → gateway implementation via /apic-api
476379
+ - diagram the Integration Service Flow .drawio via /drawio
476380
+ - both → contract + api ; all (or no keyword) → contract + api + diagram
476056
476381
 
476057
476382
  Reads the Word LLD (paragraphs + tables), extracts the API spec against the house template,
476058
476383
  shows you an extraction summary to confirm, then hands off to the generator skill(s).`;
@@ -510692,7 +511017,7 @@ ${declareVars || " -- (no parameters)"}${resultHandling}`;
510692
511017
  }
510693
511018
 
510694
511019
  // src/skills/bundled/sql.ts
510695
- function textBlock2(text) {
511020
+ function textBlock3(text) {
510696
511021
  return [{ type: "text", text }];
510697
511022
  }
510698
511023
  function parseConnectArgs(args) {
@@ -510931,22 +511256,22 @@ Do this, in order:
510931
511256
 
510932
511257
  Data-handling notice (state once): these are REAL values from the connected database and may include personal/production data. Return them as-is; never fabricate. If a SELECT returns no rows, say so plainly — for a happy case it means no qualifying data exists; do not invent a row. If the app calls no stored procedures at all, build the input body from the XSD types alone and clearly mark those values as synthetic (no DB row backs them).`;
510933
511258
  }
510934
- async function handle2(args) {
511259
+ async function handle3(args) {
510935
511260
  const trimmed = args.trim();
510936
511261
  if (!trimmed)
510937
- return HELP2;
511262
+ return HELP3;
510938
511263
  const firstTok = trimmed.split(/\s+/)[0].toLowerCase();
510939
511264
  const restStr = trimmed.slice(trimmed.split(/\s+/)[0].length).trim();
510940
511265
  switch (firstTok) {
510941
511266
  case "help":
510942
- return HELP2;
511267
+ return HELP3;
510943
511268
  case "connect": {
510944
511269
  const parsed = parseConnectArgs(restStr);
510945
511270
  const missing = ["server", "database", "user", "password"].filter((k) => !parsed[k]);
510946
511271
  if (missing.length > 0)
510947
511272
  return `Missing required field(s): ${missing.join(", ")}.
510948
511273
 
510949
- ${HELP2}`;
511274
+ ${HELP3}`;
510950
511275
  const conn2 = parsed;
510951
511276
  const saved = saveSqlConnection(conn2);
510952
511277
  let testMsg;
@@ -511074,14 +511399,14 @@ function registerSqlSkill() {
511074
511399
  allowedTools: ["Read", "Glob", "Grep"],
511075
511400
  async getPromptForCommand(args) {
511076
511401
  try {
511077
- return textBlock2(await handle2(args));
511402
+ return textBlock3(await handle3(args));
511078
511403
  } catch (e2) {
511079
- return textBlock2(`/sql error: ${e2.message}`);
511404
+ return textBlock3(`/sql error: ${e2.message}`);
511080
511405
  }
511081
511406
  }
511082
511407
  });
511083
511408
  }
511084
- var HELP2, GROUND = `
511409
+ var HELP3, GROUND = `
511085
511410
 
511086
511411
  IMPORTANT: The metadata above is the ONLY database information you have — you cannot query the DB yourself. State only what appears above; never invent, guess, or "fill in" parameters, columns, types, or procedures. If something is not shown, say it is not shown.`, STOPWORDS;
511087
511412
  var init_sql = __esm(() => {
@@ -511089,7 +511414,7 @@ var init_sql = __esm(() => {
511089
511414
  init_connectionStore();
511090
511415
  init_mssqlClient();
511091
511416
  init_spMetadata();
511092
- HELP2 = `# /sql — SQL Server helper (native connection)
511417
+ HELP3 = `# /sql — SQL Server helper (native connection)
511093
511418
 
511094
511419
  Subcommands (also understands plain English, e.g. "/sql details of the SP Get_UserInformation"):
511095
511420
  - \`/sql connect server=HOST database=DB user=USER password=PASS [port=1433] [encrypt=false]\` — save the connection once (OS secure vault; password never written to disk in plaintext).
@@ -511653,6 +511978,7 @@ function initBundledSkills() {
511653
511978
  registerAceSkills();
511654
511979
  registerSqlSkill();
511655
511980
  registerLldSkill();
511981
+ registerDrawioSkill();
511656
511982
  registerUpdateConfigSkill();
511657
511983
  if (false) {}
511658
511984
  if (false) {}
@@ -511667,6 +511993,7 @@ function initBundledSkills() {
511667
511993
  var init_bundled = __esm(() => {
511668
511994
  init_setup2();
511669
511995
  init_aceSkills();
511996
+ init_drawio();
511670
511997
  init_lld();
511671
511998
  init_orbitInChrome();
511672
511999
  init_sql();
@@ -512561,9 +512888,9 @@ var init_doctor3 = __esm(() => {
512561
512888
 
512562
512889
  // src/utils/releaseNotes.ts
512563
512890
  import { mkdir as mkdir36, readFile as readFile40, writeFile as writeFile37 } from "fs/promises";
512564
- import { dirname as dirname56, join as join127 } from "path";
512891
+ import { dirname as dirname56, join as join128 } from "path";
512565
512892
  function getChangelogCachePath() {
512566
- return join127(getOrbitConfigHomeDir(), "cache", "changelog.md");
512893
+ return join128(getOrbitConfigHomeDir(), "cache", "changelog.md");
512567
512894
  }
512568
512895
  async function migrateChangelogFromConfig() {
512569
512896
  const config3 = getGlobalConfig();
@@ -512702,12 +513029,12 @@ var init_releaseNotes = __esm(() => {
512702
513029
  });
512703
513030
 
512704
513031
  // src/utils/errorLogSink.ts
512705
- import { dirname as dirname57, join as join128 } from "path";
513032
+ import { dirname as dirname57, join as join129 } from "path";
512706
513033
  function getErrorsPath() {
512707
- return join128(CACHE_PATHS.errors(), DATE + ".jsonl");
513034
+ return join129(CACHE_PATHS.errors(), DATE + ".jsonl");
512708
513035
  }
512709
513036
  function getMCPLogsPath(serverName) {
512710
- return join128(CACHE_PATHS.mcpLogs(serverName), DATE + ".jsonl");
513037
+ return join129(CACHE_PATHS.mcpLogs(serverName), DATE + ".jsonl");
512711
513038
  }
512712
513039
  function createJsonlWriter(options2) {
512713
513040
  const writer = createBufferedWriter(options2);
@@ -513047,7 +513374,7 @@ var init_sessionMemory = __esm(() => {
513047
513374
  // src/utils/iTermBackup.ts
513048
513375
  import { copyFile as copyFile10, stat as stat41 } from "fs/promises";
513049
513376
  import { homedir as homedir37 } from "os";
513050
- import { join as join129 } from "path";
513377
+ import { join as join130 } from "path";
513051
513378
  function markITerm2SetupComplete() {
513052
513379
  saveGlobalConfig((current) => ({
513053
513380
  ...current,
@@ -513062,7 +513389,7 @@ function getIterm2RecoveryInfo() {
513062
513389
  };
513063
513390
  }
513064
513391
  function getITerm2PlistPath() {
513065
- return join129(homedir37(), "Library", "Preferences", "com.googlecode.iterm2.plist");
513392
+ return join130(homedir37(), "Library", "Preferences", "com.googlecode.iterm2.plist");
513066
513393
  }
513067
513394
  async function checkAndRestoreITerm2Backup() {
513068
513395
  const { inProgress, backupPath } = getIterm2RecoveryInfo();
@@ -513893,14 +514220,14 @@ __export(exports_orbitDesktop, {
513893
514220
  });
513894
514221
  import { readdir as readdir27, readFile as readFile41, stat as stat42 } from "fs/promises";
513895
514222
  import { homedir as homedir38 } from "os";
513896
- import { join as join130 } from "path";
514223
+ import { join as join131 } from "path";
513897
514224
  async function getOrbitDesktopConfigPath() {
513898
514225
  const platform6 = getPlatform();
513899
514226
  if (!SUPPORTED_PLATFORMS.includes(platform6)) {
513900
514227
  throw new Error(`Unsupported platform: ${platform6} - Orbit Desktop integration only works on macOS and WSL.`);
513901
514228
  }
513902
514229
  if (platform6 === "macos") {
513903
- return join130(homedir38(), "Library", "Application Support", "Orbit", "orbit_desktop_config.json");
514230
+ return join131(homedir38(), "Library", "Application Support", "Orbit", "orbit_desktop_config.json");
513904
514231
  }
513905
514232
  const windowsHome = process.env.USERPROFILE ? process.env.USERPROFILE.replace(/\\/g, "/") : null;
513906
514233
  if (windowsHome) {
@@ -513919,7 +514246,7 @@ async function getOrbitDesktopConfigPath() {
513919
514246
  if (user.name === "Public" || user.name === "Default" || user.name === "Default User" || user.name === "All Users") {
513920
514247
  continue;
513921
514248
  }
513922
- const potentialConfigPath = join130(usersDir, user.name, "AppData", "Roaming", "Orbit", "orbit_desktop_config.json");
514249
+ const potentialConfigPath = join131(usersDir, user.name, "AppData", "Roaming", "Orbit", "orbit_desktop_config.json");
513923
514250
  try {
513924
514251
  await stat42(potentialConfigPath);
513925
514252
  return potentialConfigPath;
@@ -518034,7 +518361,7 @@ var init_bridgeConfig = __esm(() => {
518034
518361
  // src/bridge/inboundAttachments.ts
518035
518362
  import { randomUUID as randomUUID47 } from "crypto";
518036
518363
  import { mkdir as mkdir37, writeFile as writeFile39 } from "fs/promises";
518037
- import { basename as basename52, join as join131 } from "path";
518364
+ import { basename as basename52, join as join132 } from "path";
518038
518365
  function debug(msg) {
518039
518366
  logForDebugging2(`[bridge:inbound-attach] ${msg}`);
518040
518367
  }
@@ -518050,7 +518377,7 @@ function sanitizeFileName(name) {
518050
518377
  return base2 || "attachment";
518051
518378
  }
518052
518379
  function uploadsDir() {
518053
- return join131(getOrbitConfigHomeDir(), "uploads", getSessionId());
518380
+ return join132(getOrbitConfigHomeDir(), "uploads", getSessionId());
518054
518381
  }
518055
518382
  async function resolveOne(att) {
518056
518383
  const token = getBridgeAccessToken();
@@ -518079,7 +518406,7 @@ async function resolveOne(att) {
518079
518406
  const safeName = sanitizeFileName(att.file_name);
518080
518407
  const prefix = (att.file_uuid.slice(0, 8) || randomUUID47().slice(0, 8)).replace(/[^a-zA-Z0-9_-]/g, "_");
518081
518408
  const dir = uploadsDir();
518082
- const outPath = join131(dir, `${prefix}-${safeName}`);
518409
+ const outPath = join132(dir, `${prefix}-${safeName}`);
518083
518410
  try {
518084
518411
  await mkdir37(dir, { recursive: true });
518085
518412
  await writeFile39(outPath, data);
@@ -518179,7 +518506,7 @@ var init_sessionUrl = __esm(() => {
518179
518506
 
518180
518507
  // src/utils/plugins/zipCacheAdapters.ts
518181
518508
  import { readFile as readFile42 } from "fs/promises";
518182
- import { join as join132 } from "path";
518509
+ import { join as join133 } from "path";
518183
518510
  async function readZipCacheKnownMarketplaces() {
518184
518511
  try {
518185
518512
  const content = await readFile42(getZipCacheKnownMarketplacesPath(), "utf-8");
@@ -518204,13 +518531,13 @@ async function saveMarketplaceJsonToZipCache(marketplaceName, installLocation) {
518204
518531
  const content = await readMarketplaceJsonContent(installLocation);
518205
518532
  if (content !== null) {
518206
518533
  const relPath = getMarketplaceJsonRelativePath(marketplaceName);
518207
- await atomicWriteToZipCache(join132(zipCachePath, relPath), content);
518534
+ await atomicWriteToZipCache(join133(zipCachePath, relPath), content);
518208
518535
  }
518209
518536
  }
518210
518537
  async function readMarketplaceJsonContent(dir) {
518211
518538
  const candidates = [
518212
- join132(dir, ".orbit-plugin", "marketplace.json"),
518213
- join132(dir, "marketplace.json"),
518539
+ join133(dir, ".orbit-plugin", "marketplace.json"),
518540
+ join133(dir, "marketplace.json"),
518214
518541
  dir
518215
518542
  ];
518216
518543
  for (const candidate of candidates) {
@@ -519254,9 +519581,9 @@ __export(exports_bridgePointer, {
519254
519581
  BRIDGE_POINTER_TTL_MS: () => BRIDGE_POINTER_TTL_MS
519255
519582
  });
519256
519583
  import { mkdir as mkdir38, readFile as readFile43, stat as stat44, unlink as unlink23, writeFile as writeFile40 } from "fs/promises";
519257
- import { dirname as dirname58, join as join133 } from "path";
519584
+ import { dirname as dirname58, join as join134 } from "path";
519258
519585
  function getBridgePointerPath(dir) {
519259
- return join133(getProjectsDir(), sanitizePath2(dir), "bridge-pointer.json");
519586
+ return join134(getProjectsDir(), sanitizePath2(dir), "bridge-pointer.json");
519260
519587
  }
519261
519588
  async function writeBridgePointer(dir, pointer) {
519262
519589
  const path20 = getBridgePointerPath(dir);
@@ -523125,7 +523452,7 @@ ${m.text}
523125
523452
  let bridgeFailureDetail;
523126
523453
  try {
523127
523454
  const { initReplBridge: initReplBridge2 } = await Promise.resolve().then(() => (init_initReplBridge(), exports_initReplBridge));
523128
- const handle3 = await initReplBridge2({
523455
+ const handle4 = await initReplBridge2({
523129
523456
  onInboundMessage(msg) {
523130
523457
  const fields = extractInboundMessageFields(msg);
523131
523458
  if (!fields)
@@ -523178,21 +523505,21 @@ ${m.text}
523178
523505
  },
523179
523506
  initialMessages: mutableMessages.length > 0 ? mutableMessages : undefined
523180
523507
  });
523181
- if (!handle3) {
523508
+ if (!handle4) {
523182
523509
  sendControlResponseError(message, bridgeFailureDetail ?? "Remote Control initialization failed");
523183
523510
  } else {
523184
- bridgeHandle = handle3;
523511
+ bridgeHandle = handle4;
523185
523512
  bridgeLastForwardedIndex = mutableMessages.length;
523186
523513
  structuredIO.setOnControlRequestSent((request) => {
523187
- handle3.sendControlRequest(request);
523514
+ handle4.sendControlRequest(request);
523188
523515
  });
523189
523516
  structuredIO.setOnControlRequestResolved((requestId) => {
523190
- handle3.sendControlCancelRequest(requestId);
523517
+ handle4.sendControlCancelRequest(requestId);
523191
523518
  });
523192
523519
  sendControlResponseSuccess(message, {
523193
- session_url: getRemoteSessionUrl(handle3.bridgeSessionId, handle3.sessionIngressUrl),
523194
- connect_url: buildBridgeConnectUrl(handle3.environmentId, handle3.sessionIngressUrl),
523195
- environment_id: handle3.environmentId
523520
+ session_url: getRemoteSessionUrl(handle4.bridgeSessionId, handle4.sessionIngressUrl),
523521
+ connect_url: buildBridgeConnectUrl(handle4.environmentId, handle4.sessionIngressUrl),
523522
+ environment_id: handle4.environmentId
523196
523523
  });
523197
523524
  }
523198
523525
  } catch (err2) {
@@ -524898,12 +525225,12 @@ __export(exports_install, {
524898
525225
  getInstallationPath: () => getInstallationPath2
524899
525226
  });
524900
525227
  import { homedir as homedir39 } from "node:os";
524901
- import { join as join134 } from "node:path";
525228
+ import { join as join135 } from "node:path";
524902
525229
  function getInstallationPath2() {
524903
525230
  const isWindows2 = env2.platform === "win32";
524904
525231
  const homeDir = homedir39();
524905
525232
  if (isWindows2) {
524906
- const windowsPath = join134(homeDir, ".local", "bin", "orbitcode.exe");
525233
+ const windowsPath = join135(homeDir, ".local", "bin", "orbitcode.exe");
524907
525234
  return windowsPath.replace(/\//g, "\\");
524908
525235
  }
524909
525236
  return "~/.local/bin/orbitcode";
@@ -527757,7 +528084,7 @@ Usage: orbit --remote "your task description"`, () => gracefulShutdown(1));
527757
528084
  pendingHookMessages
527758
528085
  }, renderAndRun);
527759
528086
  }
527760
- }).version("0.1.40 (Orbit AI)", "-v, --version", "Output the version number");
528087
+ }).version("0.1.41 (Orbit AI)", "-v, --version", "Output the version number");
527761
528088
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
527762
528089
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
527763
528090
  if (canUserConfigureAdvisor()) {
@@ -528279,7 +528606,7 @@ if (false) {}
528279
528606
  async function main2() {
528280
528607
  const args = process.argv.slice(2);
528281
528608
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
528282
- console.log(`${"0.1.40"} (Orbit AI)`);
528609
+ console.log(`${"0.1.41"} (Orbit AI)`);
528283
528610
  return;
528284
528611
  }
528285
528612
  if (args.includes("--provider")) {
@@ -528387,4 +528714,4 @@ async function main2() {
528387
528714
  }
528388
528715
  main2();
528389
528716
 
528390
- //# debugId=7191C892F3DDD05064756E2164756E21
528717
+ //# debugId=03E546CCD84EB70B64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orbit-code-ai",
3
- "version": "0.1.40",
3
+ "version": "0.1.41",
4
4
  "description": "Orbit AI – Your AI-powered IBM ACE coding companion",
5
5
  "type": "module",
6
6
  "author": "moenawaf",