orbit-code-ai 0.1.38 → 0.1.40

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/cli.mjs CHANGED
@@ -57129,15 +57129,19 @@ function getOpus46CostTier(fastMode) {
57129
57129
  function tokensToUSDCost(modelCosts, usage) {
57130
57130
  return usage.input_tokens / 1e6 * modelCosts.inputTokens + usage.output_tokens / 1e6 * modelCosts.outputTokens + (usage.cache_read_input_tokens ?? 0) / 1e6 * modelCosts.promptCacheReadTokens + (usage.cache_creation_input_tokens ?? 0) / 1e6 * modelCosts.promptCacheWriteTokens + (usage.server_tool_use?.web_search_requests ?? 0) * modelCosts.webSearchRequests;
57131
57131
  }
57132
+ function geminiVersionAtLeast(model, min) {
57133
+ const match = model.toLowerCase().match(/gemini-(\d+\.\d+)/);
57134
+ return match ? Number.parseFloat(match[1]) >= min : false;
57135
+ }
57132
57136
  function getModelCosts(model, usage) {
57133
57137
  const shortName = getCanonicalName(model);
57134
57138
  if (model.toLowerCase().startsWith("gemini")) {
57135
57139
  const lower = model.toLowerCase();
57136
57140
  if (lower.includes("flash-lite") || lower.includes("3.1") && lower.includes("flash")) {
57137
- return COST_GEMINI_31_FLASH_LITE;
57141
+ return lower.includes("lite") && geminiVersionAtLeast(lower, 3.5) ? COST_GEMINI_35_FLASH_LITE : COST_GEMINI_31_FLASH_LITE;
57138
57142
  }
57139
- if (lower.includes("3.5") && lower.includes("flash")) {
57140
- return COST_GEMINI_35_FLASH;
57143
+ if (lower.includes("flash")) {
57144
+ return geminiVersionAtLeast(lower, 3.6) ? COST_GEMINI_36_FLASH : COST_GEMINI_35_FLASH;
57141
57145
  }
57142
57146
  if (lower.includes("pro")) {
57143
57147
  const promptTokens = usage.input_tokens + (usage.cache_read_input_tokens ?? 0) + (usage.cache_creation_input_tokens ?? 0);
@@ -57177,7 +57181,7 @@ function formatPrice(price) {
57177
57181
  function formatModelPricing(costs) {
57178
57182
  return `${formatPrice(costs.inputTokens)}/${formatPrice(costs.outputTokens)} per Mtok`;
57179
57183
  }
57180
- var COST_TIER_3_15, COST_TIER_15_75, COST_TIER_5_25, COST_TIER_30_150, COST_GEMINI_31_PRO, COST_GEMINI_31_PRO_HIGH, COST_GEMINI_31_FLASH_LITE, COST_GEMINI_35_FLASH, COST_HAIKU_35, COST_HAIKU_45, DEFAULT_UNKNOWN_MODEL_COST, MODEL_COSTS;
57184
+ var COST_TIER_3_15, COST_TIER_15_75, COST_TIER_5_25, COST_TIER_30_150, COST_GEMINI_31_PRO, COST_GEMINI_31_PRO_HIGH, COST_GEMINI_31_FLASH_LITE, COST_GEMINI_35_FLASH, COST_GEMINI_36_FLASH, COST_GEMINI_35_FLASH_LITE, COST_HAIKU_35, COST_HAIKU_45, DEFAULT_UNKNOWN_MODEL_COST, MODEL_COSTS;
57181
57185
  var init_modelCost = __esm(() => {
57182
57186
  init_state();
57183
57187
  init_fastMode();
@@ -57239,6 +57243,20 @@ var init_modelCost = __esm(() => {
57239
57243
  promptCacheReadTokens: 0.375,
57240
57244
  webSearchRequests: 0.01
57241
57245
  };
57246
+ COST_GEMINI_36_FLASH = {
57247
+ inputTokens: 1.5,
57248
+ outputTokens: 7.5,
57249
+ promptCacheWriteTokens: 0,
57250
+ promptCacheReadTokens: 0.15,
57251
+ webSearchRequests: 0.01
57252
+ };
57253
+ COST_GEMINI_35_FLASH_LITE = {
57254
+ inputTokens: 0.3,
57255
+ outputTokens: 2.5,
57256
+ promptCacheWriteTokens: 0,
57257
+ promptCacheReadTokens: 0.03,
57258
+ webSearchRequests: 0.01
57259
+ };
57242
57260
  COST_HAIKU_35 = {
57243
57261
  inputTokens: 0.8,
57244
57262
  outputTokens: 4,
@@ -57421,7 +57439,7 @@ function getSmallFastModel() {
57421
57439
  if (process.env.ANTHROPIC_SMALL_FAST_MODEL)
57422
57440
  return process.env.ANTHROPIC_SMALL_FAST_MODEL;
57423
57441
  if (getAPIProvider() === "gemini") {
57424
- return process.env.GEMINI_FAST_MODEL || "gemini-3.1-flash-lite";
57442
+ return process.env.GEMINI_FAST_MODEL || "gemini-3.5-flash-lite";
57425
57443
  }
57426
57444
  if (getAPIProvider() === "openai") {
57427
57445
  return process.env.OPENAI_MODEL || "gpt-4o-mini";
@@ -57485,7 +57503,7 @@ function getDefaultSonnetModel() {
57485
57503
  return process.env.ANTHROPIC_DEFAULT_SONNET_MODEL;
57486
57504
  }
57487
57505
  if (getAPIProvider() === "gemini") {
57488
- return process.env.GEMINI_FLASH_MODEL || "gemini-3.5-flash";
57506
+ return process.env.GEMINI_FLASH_MODEL || "gemini-3.6-flash";
57489
57507
  }
57490
57508
  if (getAPIProvider() === "openai") {
57491
57509
  return process.env.OPENAI_MODEL || "gpt-4o";
@@ -57515,7 +57533,7 @@ function getDefaultHaikuModel() {
57515
57533
  return process.env.OPENAI_MODEL || "github:copilot";
57516
57534
  }
57517
57535
  if (getAPIProvider() === "gemini") {
57518
- return process.env.GEMINI_FAST_MODEL || "gemini-3.1-flash-lite";
57536
+ return process.env.GEMINI_FAST_MODEL || "gemini-3.5-flash-lite";
57519
57537
  }
57520
57538
  return getModelStrings2().haiku45;
57521
57539
  }
@@ -57535,7 +57553,7 @@ function getDefaultMainLoopModelSetting() {
57535
57553
  return settings.model || process.env.OPENAI_MODEL || "github:copilot";
57536
57554
  }
57537
57555
  if (getAPIProvider() === "gemini") {
57538
- return process.env.GEMINI_MODEL || process.env.GEMINI_FAST_MODEL || "gemini-3.1-flash-lite";
57556
+ return process.env.GEMINI_MODEL || process.env.GEMINI_FAST_MODEL || "gemini-3.5-flash-lite";
57539
57557
  }
57540
57558
  if (getAPIProvider() === "openai") {
57541
57559
  return process.env.OPENAI_MODEL || "gpt-4o";
@@ -57686,6 +57704,10 @@ function getPublicModelDisplayName(model) {
57686
57704
  "claude-sonnet-4.5": "Orbit Sonnet 4.5",
57687
57705
  "claude-haiku-4.5": "Orbit Haiku 4.5",
57688
57706
  "gemini-3.1-pro-preview": "Gemini 3.1 Pro Preview",
57707
+ "gemini-3.6-flash": "Gemini 3.6 Flash",
57708
+ "gemini-3.5-flash-lite": "Gemini 3.5 Flash-Lite",
57709
+ "gemini-3.5-flash": "Gemini 3.5 Flash",
57710
+ "gemini-3.1-flash-lite": "Gemini 3.1 Flash-Lite",
57689
57711
  "gemini-3-flash-preview": "Gemini 3 Flash",
57690
57712
  "gemini-2.5-pro": "Gemini 2.5 Pro",
57691
57713
  "grok-code-fast-1": "Grok Code Fast 1"
@@ -57961,6 +57983,8 @@ var init_openaiContextWindows = __esm(() => {
57961
57983
  "google/gemini-2.0-flash": 1048576,
57962
57984
  "google/gemini-2.5-pro": 1048576,
57963
57985
  "gemini-3.1-pro-preview": 1048576,
57986
+ "gemini-3.6-flash": 1048576,
57987
+ "gemini-3.5-flash-lite": 1048576,
57964
57988
  "gemini-3.5-flash": 1048576,
57965
57989
  "gemini-3.1-flash-lite": 1048576,
57966
57990
  "gemini-2.0-flash": 1048576,
@@ -58011,6 +58035,8 @@ var init_openaiContextWindows = __esm(() => {
58011
58035
  "google/gemini-2.0-flash": 8192,
58012
58036
  "google/gemini-2.5-pro": 65536,
58013
58037
  "gemini-3.1-pro-preview": 65536,
58038
+ "gemini-3.6-flash": 65536,
58039
+ "gemini-3.5-flash-lite": 65536,
58014
58040
  "gemini-3.5-flash": 65536,
58015
58041
  "gemini-3.1-flash-lite": 65536,
58016
58042
  "gemini-2.0-flash": 8192,
@@ -83792,7 +83818,7 @@ async function printStartupScreen() {
83792
83818
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
83793
83819
  out.push(boxRow(sRow, W2, sLen));
83794
83820
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W2 - 2)}╝${RESET}`);
83795
- out.push(` ${DIM}${rgb(...DIMCOL)}orbit-code ${RESET}${rgb(...ACCENT)}v${"0.1.38"}${RESET}`);
83821
+ out.push(` ${DIM}${rgb(...DIMCOL)}orbit-code ${RESET}${rgb(...ACCENT)}v${"0.1.40"}${RESET}`);
83796
83822
  out.push("");
83797
83823
  process.stdout.write(out.join(`
83798
83824
  `) + `
@@ -186106,8 +186132,23 @@ var init_toolArgumentNormalization = __esm(() => {
186106
186132
  // src/services/api/openaiShim.ts
186107
186133
  var exports_openaiShim = {};
186108
186134
  __export(exports_openaiShim, {
186135
+ geminiOmitsSamplingParams: () => geminiOmitsSamplingParams,
186109
186136
  createOpenAIShimClient: () => createOpenAIShimClient
186110
186137
  });
186138
+ function geminiOmitsSamplingParams(model) {
186139
+ const m = model.toLowerCase();
186140
+ if (!m.startsWith("gemini"))
186141
+ return false;
186142
+ const match = m.match(/gemini-(\d+\.\d+)/);
186143
+ if (!match)
186144
+ return false;
186145
+ const version2 = Number.parseFloat(match[1]);
186146
+ if (m.includes("flash-lite"))
186147
+ return version2 >= 3.5;
186148
+ if (m.includes("flash"))
186149
+ return version2 >= 3.6;
186150
+ return false;
186151
+ }
186111
186152
  function isGithubModelsMode() {
186112
186153
  return isEnvTruthy(process.env.ORBIT_CODE_USE_GITHUB);
186113
186154
  }
@@ -186793,10 +186834,12 @@ class OpenAIShimMessages {
186793
186834
  body.max_tokens = body.max_completion_tokens;
186794
186835
  delete body.max_completion_tokens;
186795
186836
  }
186796
- if (params.temperature !== undefined)
186797
- body.temperature = params.temperature;
186798
- if (params.top_p !== undefined)
186799
- body.top_p = params.top_p;
186837
+ if (!geminiOmitsSamplingParams(request.resolvedModel)) {
186838
+ if (params.temperature !== undefined)
186839
+ body.temperature = params.temperature;
186840
+ if (params.top_p !== undefined)
186841
+ body.top_p = params.top_p;
186842
+ }
186800
186843
  if (params.tools && params.tools.length > 0) {
186801
186844
  const converted = convertTools(params.tools);
186802
186845
  if (converted.length > 0) {
@@ -319931,16 +319974,16 @@ function getGeminiModelOptions() {
319931
319974
  descriptionForModel: "Gemini 3.1 Pro - most capable, for complex generative work"
319932
319975
  },
319933
319976
  {
319934
- value: "gemini-3.5-flash",
319935
- label: "Gemini 3.5 Flash",
319936
- description: "Gemini 3.5 Flash · Balanced for everyday tasks",
319937
- descriptionForModel: "Gemini 3.5 Flash - balanced, for everyday tasks"
319977
+ value: "gemini-3.6-flash",
319978
+ label: "Gemini 3.6 Flash",
319979
+ description: "Gemini 3.6 Flash · Balanced for everyday tasks",
319980
+ descriptionForModel: "Gemini 3.6 Flash - balanced, for everyday tasks"
319938
319981
  },
319939
319982
  {
319940
- value: "gemini-3.1-flash-lite",
319941
- label: "Gemini 3.1 Flash-Lite",
319942
- description: "Gemini 3.1 Flash-Lite · Fastest & lowest cost (default)",
319943
- descriptionForModel: "Gemini 3.1 Flash-Lite - fastest and cheapest, for reading/planning"
319983
+ value: "gemini-3.5-flash-lite",
319984
+ label: "Gemini 3.5 Flash-Lite",
319985
+ description: "Gemini 3.5 Flash-Lite · Fastest & lowest cost (default)",
319986
+ descriptionForModel: "Gemini 3.5 Flash-Lite - fastest and cheapest, for reading/planning"
319944
319987
  }
319945
319988
  ];
319946
319989
  }
@@ -334299,7 +334342,7 @@ function getAnthropicEnvMetadata() {
334299
334342
  function getBuildAgeMinutes() {
334300
334343
  if (false)
334301
334344
  ;
334302
- const buildTime = new Date("2026-07-09T12:17:41.680Z").getTime();
334345
+ const buildTime = new Date("2026-07-22T07:54:15.011Z").getTime();
334303
334346
  if (isNaN(buildTime))
334304
334347
  return;
334305
334348
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -358716,7 +358759,7 @@ function buildPrimarySection() {
358716
358759
  }, undefined, false, undefined, this);
358717
358760
  return [{
358718
358761
  label: "Version",
358719
- value: "0.1.38"
358762
+ value: "0.1.40"
358720
358763
  }, {
358721
358764
  label: "Session name",
358722
358765
  value: nameValue
@@ -471025,7 +471068,7 @@ function WelcomeV2() {
471025
471068
  dimColor: true,
471026
471069
  children: [
471027
471070
  "v",
471028
- "0.1.38",
471071
+ "0.1.40",
471029
471072
  " "
471030
471073
  ]
471031
471074
  }, undefined, true, undefined, this)
@@ -471225,7 +471268,7 @@ function WelcomeV2() {
471225
471268
  dimColor: true,
471226
471269
  children: [
471227
471270
  "v",
471228
- "0.1.38",
471271
+ "0.1.40",
471229
471272
  " "
471230
471273
  ]
471231
471274
  }, undefined, true, undefined, this)
@@ -471451,7 +471494,7 @@ function AppleTerminalWelcomeV2(t0) {
471451
471494
  dimColor: true,
471452
471495
  children: [
471453
471496
  "v",
471454
- "0.1.38",
471497
+ "0.1.40",
471455
471498
  " "
471456
471499
  ]
471457
471500
  }, undefined, true, undefined, this);
@@ -471705,7 +471748,7 @@ function AppleTerminalWelcomeV2(t0) {
471705
471748
  dimColor: true,
471706
471749
  children: [
471707
471750
  "v",
471708
- "0.1.38",
471751
+ "0.1.40",
471709
471752
  " "
471710
471753
  ]
471711
471754
  }, undefined, true, undefined, this);
@@ -475730,6 +475773,294 @@ var init_aceSkills = __esm(() => {
475730
475773
  init_bundledSkills();
475731
475774
  });
475732
475775
 
475776
+ // src/utils/docx.ts
475777
+ import { readFileSync as readFileSync10 } from "fs";
475778
+ function escapeReg(s) {
475779
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
475780
+ }
475781
+ function decodeEntities(s) {
475782
+ return s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&#x([0-9a-fA-F]+);/g, (_m, h2) => String.fromCodePoint(parseInt(h2, 16))).replace(/&#(\d+);/g, (_m, d) => String.fromCodePoint(parseInt(d, 10))).replace(/&amp;/g, "&");
475783
+ }
475784
+ function firstTag(xml, name, from) {
475785
+ const re = new RegExp(`<${escapeReg(name)}(?=[\\s/>])`, "g");
475786
+ re.lastIndex = from;
475787
+ const m = re.exec(xml);
475788
+ return m ? m.index : -1;
475789
+ }
475790
+ function findElementEnd(xml, openIdx, name) {
475791
+ const openRe = new RegExp(`<${escapeReg(name)}(?=[\\s/>])`, "g");
475792
+ const closeStr = `</${name}>`;
475793
+ let depth = 0;
475794
+ let i3 = openIdx;
475795
+ while (i3 < xml.length) {
475796
+ openRe.lastIndex = i3;
475797
+ const om = openRe.exec(xml);
475798
+ const openPos = om ? om.index : -1;
475799
+ const closePos = xml.indexOf(closeStr, i3);
475800
+ if (closePos === -1)
475801
+ return xml.length;
475802
+ if (openPos !== -1 && openPos < closePos) {
475803
+ const gt2 = xml.indexOf(">", openPos);
475804
+ const selfClosing = gt2 > 0 && xml[gt2 - 1] === "/";
475805
+ if (!selfClosing)
475806
+ depth++;
475807
+ i3 = gt2 + 1;
475808
+ } else {
475809
+ depth--;
475810
+ i3 = closePos + closeStr.length;
475811
+ if (depth === 0)
475812
+ return i3;
475813
+ }
475814
+ }
475815
+ return xml.length;
475816
+ }
475817
+ function runText(xml) {
475818
+ let s = "";
475819
+ const re = /<w:t(?:\s[^>]*)?>([\s\S]*?)<\/w:t>/g;
475820
+ let m;
475821
+ while ((m = re.exec(xml)) !== null)
475822
+ s += m[1];
475823
+ return decodeEntities(s);
475824
+ }
475825
+ function inner(xml, name) {
475826
+ const start = xml.indexOf(">");
475827
+ const end = xml.lastIndexOf(`</${name}>`);
475828
+ return start === -1 || end === -1 ? xml : xml.slice(start + 1, end);
475829
+ }
475830
+ function cellText(tcXml) {
475831
+ const body = inner(tcXml, "w:tc");
475832
+ const parts = [];
475833
+ let i3 = 0;
475834
+ while (i3 < body.length) {
475835
+ const pPos = firstTag(body, "w:p", i3);
475836
+ if (pPos === -1)
475837
+ break;
475838
+ const pEnd = findElementEnd(body, pPos, "w:p");
475839
+ const t = runText(body.slice(pPos, pEnd)).trim();
475840
+ if (t)
475841
+ parts.push(t);
475842
+ i3 = pEnd;
475843
+ }
475844
+ return parts.join(" ").replace(/\s+/g, " ").trim().replace(/\|/g, "\\|");
475845
+ }
475846
+ function rowCells(trXml) {
475847
+ const body = inner(trXml, "w:tr");
475848
+ const cells = [];
475849
+ let i3 = 0;
475850
+ while (i3 < body.length) {
475851
+ const nested = firstTag(body, "w:tbl", i3);
475852
+ const tc = firstTag(body, "w:tc", i3);
475853
+ if (tc === -1)
475854
+ break;
475855
+ if (nested !== -1 && nested < tc) {
475856
+ i3 = findElementEnd(body, nested, "w:tbl");
475857
+ continue;
475858
+ }
475859
+ const tcEnd = findElementEnd(body, tc, "w:tc");
475860
+ cells.push(cellText(body.slice(tc, tcEnd)));
475861
+ i3 = tcEnd;
475862
+ }
475863
+ return cells;
475864
+ }
475865
+ function renderTable(tblXml) {
475866
+ const body = inner(tblXml, "w:tbl");
475867
+ const rows = [];
475868
+ let i3 = 0;
475869
+ while (i3 < body.length) {
475870
+ const nested = firstTag(body, "w:tbl", i3);
475871
+ const tr = firstTag(body, "w:tr", i3);
475872
+ if (tr === -1)
475873
+ break;
475874
+ if (nested !== -1 && nested < tr) {
475875
+ i3 = findElementEnd(body, nested, "w:tbl");
475876
+ continue;
475877
+ }
475878
+ const trEnd = findElementEnd(body, tr, "w:tr");
475879
+ rows.push(rowCells(body.slice(tr, trEnd)));
475880
+ i3 = trEnd;
475881
+ }
475882
+ if (rows.length === 0)
475883
+ return "";
475884
+ const width = Math.max(...rows.map((r) => r.length));
475885
+ const pad = (r) => "| " + Array.from({ length: width }, (_, k) => r[k] ?? "").join(" | ") + " |";
475886
+ const md = [pad(rows[0]), "| " + Array(width).fill("---").join(" | ") + " |"];
475887
+ for (const r of rows.slice(1))
475888
+ md.push(pad(r));
475889
+ return md.join(`
475890
+ `);
475891
+ }
475892
+ function renderBody(bodyXml) {
475893
+ const out = [];
475894
+ let i3 = 0;
475895
+ while (i3 < bodyXml.length) {
475896
+ const p = firstTag(bodyXml, "w:p", i3);
475897
+ const tbl = firstTag(bodyXml, "w:tbl", i3);
475898
+ if (p === -1 && tbl === -1)
475899
+ break;
475900
+ if (tbl !== -1 && (p === -1 || tbl < p)) {
475901
+ const end = findElementEnd(bodyXml, tbl, "w:tbl");
475902
+ const t = renderTable(bodyXml.slice(tbl, end));
475903
+ if (t)
475904
+ out.push(t);
475905
+ i3 = end;
475906
+ } else {
475907
+ const end = findElementEnd(bodyXml, p, "w:p");
475908
+ const t = runText(bodyXml.slice(p, end)).trim();
475909
+ if (t)
475910
+ out.push(t);
475911
+ i3 = end;
475912
+ }
475913
+ }
475914
+ return out.join(`
475915
+
475916
+ `);
475917
+ }
475918
+ async function extractDocxText(filePath, maxChars = 60000) {
475919
+ const { unzipSync: unzipSync2 } = await Promise.resolve().then(() => (init_esm3(), exports_esm));
475920
+ const data = readFileSync10(filePath);
475921
+ let files2;
475922
+ try {
475923
+ files2 = unzipSync2(new Uint8Array(data), {
475924
+ filter: (f) => f.name === "word/document.xml"
475925
+ });
475926
+ } catch (e2) {
475927
+ throw new Error(`Not a readable .docx (unzip failed): ${e2.message}`);
475928
+ }
475929
+ const bytes = files2["word/document.xml"];
475930
+ if (!bytes) {
475931
+ throw new Error("word/document.xml not found — the file is not a valid .docx (a .doc or renamed file?).");
475932
+ }
475933
+ const xml = new TextDecoder("utf-8").decode(bytes);
475934
+ const bodyMatch = xml.match(/<w:body[^>]*>([\s\S]*)<\/w:body>/);
475935
+ const text = renderBody(bodyMatch ? bodyMatch[1] : xml).trim();
475936
+ if (text.length > maxChars) {
475937
+ return `${text.slice(0, maxChars)}
475938
+
475939
+ …[truncated; ${text.length} chars total]…`;
475940
+ }
475941
+ return text;
475942
+ }
475943
+ var init_docx = () => {};
475944
+
475945
+ // src/skills/bundled/lld.ts
475946
+ function textBlock(text) {
475947
+ return [{ type: "text", text }];
475948
+ }
475949
+ function parseArgs(args) {
475950
+ const trimmed = args.trim();
475951
+ let path20 = "";
475952
+ let rest = "";
475953
+ const quoted = trimmed.match(/^["']([^"']+)["']\s*(.*)$/);
475954
+ if (quoted) {
475955
+ path20 = quoted[1];
475956
+ rest = quoted[2];
475957
+ } else {
475958
+ const dotdocx = trimmed.match(/^(.*?\.docx)\s*(.*)$/i);
475959
+ if (dotdocx) {
475960
+ path20 = dotdocx[1].trim();
475961
+ rest = dotdocx[2];
475962
+ } else {
475963
+ rest = trimmed;
475964
+ }
475965
+ }
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 };
475969
+ }
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):
475982
+ - Introduction (Purpose / Scope) → API title + description.
475983
+ - "Integration flow (<op>)" → its "API Gateway endpoint" and "Method" → the operation path + verb.
475984
+ - "<op> Request" table → request model. Columns are typically Field | Type | Occurrence | Length |
475985
+ Description | Validation. Convert: Occurrence M → required; O/C → optional (put the C rule in
475986
+ description); Length N → maxLength; allowed-values → enum; "1..*" → array (minItems 1 when ≥1).
475987
+ - "<op> Response" table + any "<type>" tables (e.g. commodity_type) → response model (nested/arrays).
475988
+ - "Error Codes" table + any sample error bodies → error responses (HTTP codes + error schema).
475989
+ - "Transformation Specifications" tables → how request fields map to the backend + any defaulting.
475990
+ - "Annex / Provider" (endpoints, auth) → the backend/provider endpoint(s) and their auth.
475991
+ - Integration pattern: if the middleware is an existing ACE/webMethods service that already returns
475992
+ 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.
475994
+
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.
476001
+
476002
+ 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.
476008
+ Reuse the values from the extraction summary verbatim — do not re-derive or drop fields.
476009
+
476010
+ Ground everything in the extracted LLD above; if the LLD does not state something, say so rather than
476011
+ inventing it.`;
476012
+ }
476013
+ async function handle(args) {
476014
+ const { path: path20, target } = parseArgs(args);
476015
+ if (!path20)
476016
+ return HELP;
476017
+ let content;
476018
+ try {
476019
+ content = await extractDocxText(path20);
476020
+ } catch (e2) {
476021
+ return `Could not read the LLD at "${path20}": ${e2.message}
476022
+
476023
+ Give the full path to a .docx file, e.g.
476024
+ /lld "C:\\\\path\\\\to\\\\LLD.docx" both`;
476025
+ }
476026
+ if (!content.trim()) {
476027
+ 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
+ }
476029
+ return buildPrompt(path20, content, target);
476030
+ }
476031
+ function registerLldSkill() {
476032
+ registerBundledSkill({
476033
+ name: "lld",
476034
+ 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
+ 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]',
476037
+ userInvocable: true,
476038
+ allowedTools: ["Read", "Glob", "Grep"],
476039
+ async getPromptForCommand(args) {
476040
+ try {
476041
+ return textBlock(await handle(args));
476042
+ } catch (e2) {
476043
+ return textBlock(`/lld error: ${e2.message}`);
476044
+ }
476045
+ }
476046
+ });
476047
+ }
476048
+ var HELP = `# /lld — read an LLD (.docx) and generate the APIC contract and/or gateway API
476049
+
476050
+ Usage:
476051
+ /lld "<path-to-LLD.docx>" [contract|api|both]
476052
+
476053
+ - contract → generate the contract-only OpenAPI via /api-contract
476054
+ - api → generate the gateway implementation via /apic-api
476055
+ - both → generate both (default)
476056
+
476057
+ Reads the Word LLD (paragraphs + tables), extracts the API spec against the house template,
476058
+ shows you an extraction summary to confirm, then hands off to the generator skill(s).`;
476059
+ var init_lld = __esm(() => {
476060
+ init_bundledSkills();
476061
+ init_docx();
476062
+ });
476063
+
475733
476064
  // src/skills/bundled/orbitInChrome.ts
475734
476065
  function registerOrbitInChromeSkill() {
475735
476066
  registerBundledSkill({
@@ -477312,7 +477643,7 @@ var require_tslib = __commonJS((exports, module) => {
477312
477643
  if (value !== null && value !== undefined) {
477313
477644
  if (typeof value !== "object" && typeof value !== "function")
477314
477645
  throw new TypeError("Object expected.");
477315
- var dispose4, inner;
477646
+ var dispose4, inner2;
477316
477647
  if (async) {
477317
477648
  if (!Symbol.asyncDispose)
477318
477649
  throw new TypeError("Symbol.asyncDispose is not defined.");
@@ -477323,14 +477654,14 @@ var require_tslib = __commonJS((exports, module) => {
477323
477654
  throw new TypeError("Symbol.dispose is not defined.");
477324
477655
  dispose4 = value[Symbol.dispose];
477325
477656
  if (async)
477326
- inner = dispose4;
477657
+ inner2 = dispose4;
477327
477658
  }
477328
477659
  if (typeof dispose4 !== "function")
477329
477660
  throw new TypeError("Object not disposable.");
477330
- if (inner)
477661
+ if (inner2)
477331
477662
  dispose4 = function() {
477332
477663
  try {
477333
- inner.call(this);
477664
+ inner2.call(this);
477334
477665
  } catch (e2) {
477335
477666
  return Promise.reject(e2);
477336
477667
  }
@@ -510361,7 +510692,7 @@ ${declareVars || " -- (no parameters)"}${resultHandling}`;
510361
510692
  }
510362
510693
 
510363
510694
  // src/skills/bundled/sql.ts
510364
- function textBlock(text) {
510695
+ function textBlock2(text) {
510365
510696
  return [{ type: "text", text }];
510366
510697
  }
510367
510698
  function parseConnectArgs(args) {
@@ -510600,22 +510931,22 @@ Do this, in order:
510600
510931
 
510601
510932
  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).`;
510602
510933
  }
510603
- async function handle(args) {
510934
+ async function handle2(args) {
510604
510935
  const trimmed = args.trim();
510605
510936
  if (!trimmed)
510606
- return HELP;
510937
+ return HELP2;
510607
510938
  const firstTok = trimmed.split(/\s+/)[0].toLowerCase();
510608
510939
  const restStr = trimmed.slice(trimmed.split(/\s+/)[0].length).trim();
510609
510940
  switch (firstTok) {
510610
510941
  case "help":
510611
- return HELP;
510942
+ return HELP2;
510612
510943
  case "connect": {
510613
510944
  const parsed = parseConnectArgs(restStr);
510614
510945
  const missing = ["server", "database", "user", "password"].filter((k) => !parsed[k]);
510615
510946
  if (missing.length > 0)
510616
510947
  return `Missing required field(s): ${missing.join(", ")}.
510617
510948
 
510618
- ${HELP}`;
510949
+ ${HELP2}`;
510619
510950
  const conn2 = parsed;
510620
510951
  const saved = saveSqlConnection(conn2);
510621
510952
  let testMsg;
@@ -510743,14 +511074,14 @@ function registerSqlSkill() {
510743
511074
  allowedTools: ["Read", "Glob", "Grep"],
510744
511075
  async getPromptForCommand(args) {
510745
511076
  try {
510746
- return textBlock(await handle(args));
511077
+ return textBlock2(await handle2(args));
510747
511078
  } catch (e2) {
510748
- return textBlock(`/sql error: ${e2.message}`);
511079
+ return textBlock2(`/sql error: ${e2.message}`);
510749
511080
  }
510750
511081
  }
510751
511082
  });
510752
511083
  }
510753
- var HELP, GROUND = `
511084
+ var HELP2, GROUND = `
510754
511085
 
510755
511086
  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;
510756
511087
  var init_sql = __esm(() => {
@@ -510758,7 +511089,7 @@ var init_sql = __esm(() => {
510758
511089
  init_connectionStore();
510759
511090
  init_mssqlClient();
510760
511091
  init_spMetadata();
510761
- HELP = `# /sql — SQL Server helper (native connection)
511092
+ HELP2 = `# /sql — SQL Server helper (native connection)
510762
511093
 
510763
511094
  Subcommands (also understands plain English, e.g. "/sql details of the SP Get_UserInformation"):
510764
511095
  - \`/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).
@@ -511321,6 +511652,7 @@ If a hook isn't running:
511321
511652
  function initBundledSkills() {
511322
511653
  registerAceSkills();
511323
511654
  registerSqlSkill();
511655
+ registerLldSkill();
511324
511656
  registerUpdateConfigSkill();
511325
511657
  if (false) {}
511326
511658
  if (false) {}
@@ -511335,6 +511667,7 @@ function initBundledSkills() {
511335
511667
  var init_bundled = __esm(() => {
511336
511668
  init_setup2();
511337
511669
  init_aceSkills();
511670
+ init_lld();
511338
511671
  init_orbitInChrome();
511339
511672
  init_sql();
511340
511673
  init_updateConfig();
@@ -522792,7 +523125,7 @@ ${m.text}
522792
523125
  let bridgeFailureDetail;
522793
523126
  try {
522794
523127
  const { initReplBridge: initReplBridge2 } = await Promise.resolve().then(() => (init_initReplBridge(), exports_initReplBridge));
522795
- const handle2 = await initReplBridge2({
523128
+ const handle3 = await initReplBridge2({
522796
523129
  onInboundMessage(msg) {
522797
523130
  const fields = extractInboundMessageFields(msg);
522798
523131
  if (!fields)
@@ -522845,21 +523178,21 @@ ${m.text}
522845
523178
  },
522846
523179
  initialMessages: mutableMessages.length > 0 ? mutableMessages : undefined
522847
523180
  });
522848
- if (!handle2) {
523181
+ if (!handle3) {
522849
523182
  sendControlResponseError(message, bridgeFailureDetail ?? "Remote Control initialization failed");
522850
523183
  } else {
522851
- bridgeHandle = handle2;
523184
+ bridgeHandle = handle3;
522852
523185
  bridgeLastForwardedIndex = mutableMessages.length;
522853
523186
  structuredIO.setOnControlRequestSent((request) => {
522854
- handle2.sendControlRequest(request);
523187
+ handle3.sendControlRequest(request);
522855
523188
  });
522856
523189
  structuredIO.setOnControlRequestResolved((requestId) => {
522857
- handle2.sendControlCancelRequest(requestId);
523190
+ handle3.sendControlCancelRequest(requestId);
522858
523191
  });
522859
523192
  sendControlResponseSuccess(message, {
522860
- session_url: getRemoteSessionUrl(handle2.bridgeSessionId, handle2.sessionIngressUrl),
522861
- connect_url: buildBridgeConnectUrl(handle2.environmentId, handle2.sessionIngressUrl),
522862
- environment_id: handle2.environmentId
523193
+ session_url: getRemoteSessionUrl(handle3.bridgeSessionId, handle3.sessionIngressUrl),
523194
+ connect_url: buildBridgeConnectUrl(handle3.environmentId, handle3.sessionIngressUrl),
523195
+ environment_id: handle3.environmentId
522863
523196
  });
522864
523197
  }
522865
523198
  } catch (err2) {
@@ -525467,7 +525800,7 @@ __export(exports_main, {
525467
525800
  startDeferredPrefetches: () => startDeferredPrefetches,
525468
525801
  main: () => main
525469
525802
  });
525470
- import { readFileSync as readFileSync10 } from "fs";
525803
+ import { readFileSync as readFileSync11 } from "fs";
525471
525804
  import { resolve as resolve40 } from "path";
525472
525805
  function logManagedSettings() {
525473
525806
  try {
@@ -525623,7 +525956,7 @@ function loadSettingsFromFlag(settingsFile) {
525623
525956
  resolvedPath: resolvedSettingsPath
525624
525957
  } = safeResolvePath(getFsImplementation(), settingsFile);
525625
525958
  try {
525626
- readFileSync10(resolvedSettingsPath, "utf8");
525959
+ readFileSync11(resolvedSettingsPath, "utf8");
525627
525960
  } catch (e2) {
525628
525961
  if (isENOENT(e2)) {
525629
525962
  process.stderr.write(source_default.red(`Error: Settings file not found: ${resolvedSettingsPath}
@@ -526026,7 +526359,7 @@ ${getTmuxInstallInstructions2()}
526026
526359
  }
526027
526360
  try {
526028
526361
  const filePath = resolve40(options2.systemPromptFile);
526029
- systemPrompt = readFileSync10(filePath, "utf8");
526362
+ systemPrompt = readFileSync11(filePath, "utf8");
526030
526363
  } catch (error41) {
526031
526364
  const code = getErrnoCode(error41);
526032
526365
  if (code === "ENOENT") {
@@ -526048,7 +526381,7 @@ ${getTmuxInstallInstructions2()}
526048
526381
  }
526049
526382
  try {
526050
526383
  const filePath = resolve40(options2.appendSystemPromptFile);
526051
- appendSystemPrompt = readFileSync10(filePath, "utf8");
526384
+ appendSystemPrompt = readFileSync11(filePath, "utf8");
526052
526385
  } catch (error41) {
526053
526386
  const code = getErrnoCode(error41);
526054
526387
  if (code === "ENOENT") {
@@ -527424,7 +527757,7 @@ Usage: orbit --remote "your task description"`, () => gracefulShutdown(1));
527424
527757
  pendingHookMessages
527425
527758
  }, renderAndRun);
527426
527759
  }
527427
- }).version("0.1.38 (Orbit AI)", "-v, --version", "Output the version number");
527760
+ }).version("0.1.40 (Orbit AI)", "-v, --version", "Output the version number");
527428
527761
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
527429
527762
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
527430
527763
  if (canUserConfigureAdvisor()) {
@@ -527946,7 +528279,7 @@ if (false) {}
527946
528279
  async function main2() {
527947
528280
  const args = process.argv.slice(2);
527948
528281
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
527949
- console.log(`${"0.1.38"} (Orbit AI)`);
528282
+ console.log(`${"0.1.40"} (Orbit AI)`);
527950
528283
  return;
527951
528284
  }
527952
528285
  if (args.includes("--provider")) {
@@ -528054,4 +528387,4 @@ async function main2() {
528054
528387
  }
528055
528388
  main2();
528056
528389
 
528057
- //# debugId=915C704C919EC95E64756E2164756E21
528390
+ //# debugId=7191C892F3DDD05064756E2164756E21