copilot-statusline 0.1.9 → 0.1.11

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.
@@ -52913,7 +52913,7 @@ import { execSync as execSync3 } from "child_process";
52913
52913
  import * as fs5 from "fs";
52914
52914
  import * as path4 from "path";
52915
52915
  var __dirname = "/Users/ts/workspace/active/statusline/copilot_statusline/src/utils";
52916
- var PACKAGE_VERSION = "0.1.9";
52916
+ var PACKAGE_VERSION = "0.1.11";
52917
52917
  function getPackageVersion() {
52918
52918
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
52919
52919
  return PACKAGE_VERSION;
@@ -53915,8 +53915,29 @@ class SessionIdWidget {
53915
53915
  }
53916
53916
  }
53917
53917
  // src/utils/display-name-parser.ts
53918
- var EFFORT_LEVELS = new Set(["low", "medium", "high"]);
53918
+ var THINKING_EFFORT_LEVELS = ["minimal", "low", "medium", "high", "xhigh", "max"];
53919
+ var EFFORT_LEVELS = new Set(THINKING_EFFORT_LEVELS);
53920
+ var EFFORT_LEVEL_PATTERN = THINKING_EFFORT_LEVELS.join("|");
53919
53921
  var MULTIPLIER_REGEX = /^(\d+)x$/;
53922
+ var LABELED_EFFORT_REGEX = new RegExp(`^(?:thinking|reasoning|effort)(?:[-_ ](?:effort|level))?\\s*[:=]\\s*(${EFFORT_LEVEL_PATTERN})$`);
53923
+ function normalizeThinkingEffort(value) {
53924
+ if (!value) {
53925
+ return null;
53926
+ }
53927
+ const normalized = value.trim().toLowerCase();
53928
+ if (EFFORT_LEVELS.has(normalized)) {
53929
+ return normalized;
53930
+ }
53931
+ const match = LABELED_EFFORT_REGEX.exec(normalized);
53932
+ return match?.[1] ? match[1] : null;
53933
+ }
53934
+ function trustThinkingEffort(value) {
53935
+ if (!value) {
53936
+ return null;
53937
+ }
53938
+ const normalized = value.trim().toLowerCase();
53939
+ return normalized || null;
53940
+ }
53920
53941
  function parseDisplayName(displayName) {
53921
53942
  if (!displayName) {
53922
53943
  return { thinkingEffort: null, multiplier: null, multiplierValue: null };
@@ -53934,9 +53955,19 @@ function parseDisplayName(displayName) {
53934
53955
  let multiplier = null;
53935
53956
  let multiplierValue = null;
53936
53957
  for (let i = groups.length - 1;i >= 0; i--) {
53937
- const group = groups[i]?.toLowerCase();
53938
- if (group && EFFORT_LEVELS.has(group)) {
53939
- thinkingEffort = group;
53958
+ const group = groups[i];
53959
+ if (!group) {
53960
+ continue;
53961
+ }
53962
+ const parts = group.split(/[,;|]/).map((part) => part.trim());
53963
+ for (let partIndex = parts.length - 1;partIndex >= 0; partIndex--) {
53964
+ const effort = normalizeThinkingEffort(parts[partIndex]);
53965
+ if (effort) {
53966
+ thinkingEffort = effort;
53967
+ break;
53968
+ }
53969
+ }
53970
+ if (thinkingEffort) {
53940
53971
  break;
53941
53972
  }
53942
53973
  }
@@ -53944,10 +53975,16 @@ function parseDisplayName(displayName) {
53944
53975
  if (!group) {
53945
53976
  continue;
53946
53977
  }
53947
- const multMatch = MULTIPLIER_REGEX.exec(group);
53948
- if (multMatch?.[1]) {
53949
- multiplier = group;
53950
- multiplierValue = parseInt(multMatch[1], 10);
53978
+ const parts = group.split(/[,;|]/).map((part) => part.trim());
53979
+ for (const part of parts) {
53980
+ const multMatch = MULTIPLIER_REGEX.exec(part);
53981
+ if (multMatch?.[1]) {
53982
+ multiplier = part;
53983
+ multiplierValue = parseInt(multMatch[1], 10);
53984
+ break;
53985
+ }
53986
+ }
53987
+ if (multiplier) {
53951
53988
  break;
53952
53989
  }
53953
53990
  }
@@ -53960,7 +53997,7 @@ class ThinkingEffortWidget {
53960
53997
  return "magenta";
53961
53998
  }
53962
53999
  getDescription() {
53963
- return "Displays the thinking effort level parsed from model.display_name (low, medium, high)";
54000
+ return "Displays the thinking effort level from the Copilot model payload";
53964
54001
  }
53965
54002
  getDisplayName() {
53966
54003
  return "Thinking Effort";
@@ -53975,9 +54012,10 @@ class ThinkingEffortWidget {
53975
54012
  if (context.isPreview) {
53976
54013
  return item.rawValue ? "high" : "Thinking: high";
53977
54014
  }
53978
- const parsed = parseDisplayName(context.data?.model?.display_name);
53979
- if (parsed.thinkingEffort) {
53980
- return item.rawValue ? parsed.thinkingEffort : `Thinking: ${parsed.thinkingEffort}`;
54015
+ const model = context.data?.model;
54016
+ const thinkingEffort = trustThinkingEffort(model?.thinking_effort_level) ?? normalizeThinkingEffort(model?.thinking_effort) ?? normalizeThinkingEffort(model?.reasoning_effort) ?? parseDisplayName(model?.display_name).thinkingEffort;
54017
+ if (thinkingEffort) {
54018
+ return item.rawValue ? thinkingEffort : `Thinking: ${thinkingEffort}`;
53981
54019
  }
53982
54020
  return null;
53983
54021
  }
@@ -54983,51 +55021,131 @@ function getGitShortSha(context) {
54983
55021
  return runGit("rev-parse --short HEAD", context);
54984
55022
  }
54985
55023
 
54986
- // src/utils/hyperlink.ts
54987
- var IDE_LINK_MODES = [
54988
- "vscode",
54989
- "cursor"
54990
- ];
54991
- function renderOsc8Link(url2, text) {
54992
- return `\x1B]8;;${url2}\x1B\\${text}\x1B]8;;\x1B\\`;
54993
- }
54994
- function parseGitHubRepositoryPath(pathname) {
54995
- const trimmedPath = pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
54996
- const segments = trimmedPath.split("/").filter(Boolean);
54997
- if (segments.length !== 2) {
54998
- return null;
54999
- }
55000
- return `${segments[0]}/${segments[1]}`;
55001
- }
55002
- function parseGitHubBaseUrl(remoteUrl) {
55003
- const trimmed = remoteUrl.trim();
55024
+ // src/utils/git-remote.ts
55025
+ function parseRemoteUrl(url2) {
55026
+ const trimmed = url2.trim();
55004
55027
  if (trimmed.length === 0) {
55005
55028
  return null;
55006
55029
  }
55007
- const sshMatch = /^(?:[^@]+@)?github\.com:([^/]+\/[^/]+?)(?:\.git)?\/?$/.exec(trimmed);
55008
- if (sshMatch?.[1]) {
55009
- return `https://github.com/${sshMatch[1]}`;
55030
+ const sshMatch = !trimmed.includes("://") ? /^(?:[^@]+@)?([^:]+):(.+?)(?:\.git)?\/?$/.exec(trimmed) : null;
55031
+ if (sshMatch?.[1] && sshMatch[2]) {
55032
+ const pathSegments = sshMatch[2].split("/").filter(Boolean);
55033
+ const repo = pathSegments.at(-1);
55034
+ const owner = pathSegments.slice(0, -1).join("/");
55035
+ if (!owner || !repo) {
55036
+ return null;
55037
+ }
55038
+ return {
55039
+ host: sshMatch[1],
55040
+ owner,
55041
+ repo
55042
+ };
55010
55043
  }
55011
55044
  try {
55012
55045
  const parsedUrl = new URL(trimmed);
55013
- const supportedProtocols = new Set([
55014
- "http:",
55015
- "https:",
55016
- "ssh:",
55017
- "git:"
55018
- ]);
55019
- if (parsedUrl.hostname.toLowerCase() !== "github.com" || !supportedProtocols.has(parsedUrl.protocol)) {
55046
+ const supportedProtocols = new Set(["http:", "https:", "ssh:", "git:"]);
55047
+ if (!supportedProtocols.has(parsedUrl.protocol)) {
55020
55048
  return null;
55021
55049
  }
55022
- const repoPath = parseGitHubRepositoryPath(parsedUrl.pathname);
55023
- if (!repoPath) {
55050
+ const pathname = parsedUrl.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
55051
+ const segments = pathname.split("/").filter(Boolean);
55052
+ const repo = segments.at(-1);
55053
+ const owner = segments.slice(0, -1).join("/");
55054
+ if (!owner || !repo) {
55024
55055
  return null;
55025
55056
  }
55026
- return `https://github.com/${repoPath}`;
55057
+ return {
55058
+ host: parsedUrl.hostname,
55059
+ owner,
55060
+ repo
55061
+ };
55027
55062
  } catch {
55028
55063
  return null;
55029
55064
  }
55030
55065
  }
55066
+ function getRemoteInfo(remoteName, context) {
55067
+ const url2 = runGit(`remote get-url ${remoteName}`, context);
55068
+ if (!url2) {
55069
+ return null;
55070
+ }
55071
+ const parsed = parseRemoteUrl(url2);
55072
+ if (!parsed) {
55073
+ return null;
55074
+ }
55075
+ return {
55076
+ name: remoteName,
55077
+ url: url2,
55078
+ host: parsed.host,
55079
+ owner: parsed.owner,
55080
+ repo: parsed.repo
55081
+ };
55082
+ }
55083
+ function getTrackingRemoteName(context) {
55084
+ const upstreamRef = runGit("rev-parse --abbrev-ref --symbolic-full-name @{upstream}", context);
55085
+ if (!upstreamRef) {
55086
+ return null;
55087
+ }
55088
+ const remotes = listRemotes(context).slice().sort((left, right) => right.length - left.length);
55089
+ return remotes.find((remote) => upstreamRef === remote || upstreamRef.startsWith(`${remote}/`)) ?? null;
55090
+ }
55091
+ function getUpstreamRemoteInfo(context) {
55092
+ const namedUpstream = getRemoteInfo("upstream", context);
55093
+ if (namedUpstream) {
55094
+ return namedUpstream;
55095
+ }
55096
+ const trackingRemoteName = getTrackingRemoteName(context);
55097
+ if (!trackingRemoteName) {
55098
+ return null;
55099
+ }
55100
+ return getRemoteInfo(trackingRemoteName, context);
55101
+ }
55102
+ function getForkStatus(context) {
55103
+ const origin = getRemoteInfo("origin", context);
55104
+ const upstream = getRemoteInfo("upstream", context);
55105
+ const isFork = Boolean(origin && upstream && (origin.owner !== upstream.owner || origin.repo !== upstream.repo));
55106
+ return {
55107
+ isFork,
55108
+ origin,
55109
+ upstream
55110
+ };
55111
+ }
55112
+ function listRemotes(context) {
55113
+ const output = runGit("remote", context);
55114
+ if (!output) {
55115
+ return [];
55116
+ }
55117
+ return output.split(`
55118
+ `).filter(Boolean);
55119
+ }
55120
+ function buildRepoWebUrl(remote) {
55121
+ let webHost = remote.host;
55122
+ try {
55123
+ const parsedUrl = new URL(remote.url);
55124
+ if (parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:") {
55125
+ webHost = parsedUrl.host;
55126
+ }
55127
+ } catch {}
55128
+ return `https://${webHost}/${remote.owner}/${remote.repo}`;
55129
+ }
55130
+ function getBranchWebPath(remote) {
55131
+ const host = remote.host.toLowerCase().replace(/:\d+$/, "");
55132
+ if (host === "gitlab.com" || /^[^.]+\.gitlab\.com$/.test(host)) {
55133
+ return "/-/tree/";
55134
+ }
55135
+ return "/tree/";
55136
+ }
55137
+ function buildBranchWebUrl(remote, encodedBranch) {
55138
+ return `${buildRepoWebUrl(remote)}${getBranchWebPath(remote)}${encodedBranch}`;
55139
+ }
55140
+
55141
+ // src/utils/hyperlink.ts
55142
+ var IDE_LINK_MODES = [
55143
+ "vscode",
55144
+ "cursor"
55145
+ ];
55146
+ function renderOsc8Link(url2, text) {
55147
+ return `\x1B]8;;${url2}\x1B\\${text}\x1B]8;;\x1B\\`;
55148
+ }
55031
55149
  function encodeGitRefForUrlPath(ref) {
55032
55150
  return ref.split("/").map((segment) => encodeURIComponent(segment)).join("/");
55033
55151
  }
@@ -55074,8 +55192,30 @@ function getHideNoGitKeybinds() {
55074
55192
  }
55075
55193
 
55076
55194
  // src/widgets/GitBranch.ts
55077
- var LINK_KEY = "linkToGitHub";
55195
+ var LINK_KEY = "linkToRepo";
55196
+ var LEGACY_LINK_KEY = "linkToGitHub";
55078
55197
  var TOGGLE_LINK_ACTION = "toggle-link";
55198
+ var PREVIEW_REMOTE = {
55199
+ name: "origin",
55200
+ url: "https://example.com/owner/repo.git",
55201
+ host: "example.com",
55202
+ owner: "owner",
55203
+ repo: "repo"
55204
+ };
55205
+ function isLinkEnabled(item) {
55206
+ return isMetadataFlagEnabled(item, LINK_KEY) || item.metadata?.[LINK_KEY] === undefined && isMetadataFlagEnabled(item, LEGACY_LINK_KEY);
55207
+ }
55208
+ function toggleLink(item) {
55209
+ const nextEnabled = !isLinkEnabled(item);
55210
+ const nextMetadata = Object.fromEntries(Object.entries(item.metadata ?? {}).filter(([key]) => key !== LINK_KEY && key !== LEGACY_LINK_KEY));
55211
+ if (nextEnabled) {
55212
+ nextMetadata[LINK_KEY] = "true";
55213
+ }
55214
+ return {
55215
+ ...item,
55216
+ metadata: Object.keys(nextMetadata).length > 0 ? nextMetadata : undefined
55217
+ };
55218
+ }
55079
55219
 
55080
55220
  class GitBranchWidget {
55081
55221
  getDefaultColor() {
@@ -55091,13 +55231,13 @@ class GitBranchWidget {
55091
55231
  return "Git";
55092
55232
  }
55093
55233
  getEditorDisplay(item) {
55094
- const isLink = isMetadataFlagEnabled(item, LINK_KEY);
55234
+ const isLink = isLinkEnabled(item);
55095
55235
  const modifiers = [];
55096
55236
  const noGitText = getHideNoGitModifierText(item);
55097
55237
  if (noGitText)
55098
55238
  modifiers.push("hide 'no git'");
55099
55239
  if (isLink)
55100
- modifiers.push("GitHub link");
55240
+ modifiers.push("repo link");
55101
55241
  return {
55102
55242
  displayText: this.getDisplayName(),
55103
55243
  modifierText: makeModifierText(modifiers)
@@ -55105,16 +55245,16 @@ class GitBranchWidget {
55105
55245
  }
55106
55246
  handleEditorAction(action, item) {
55107
55247
  if (action === TOGGLE_LINK_ACTION) {
55108
- return toggleMetadataFlag(item, LINK_KEY);
55248
+ return toggleLink(item);
55109
55249
  }
55110
55250
  return handleToggleNoGitAction(action, item);
55111
55251
  }
55112
55252
  render(item, context, settings) {
55113
55253
  const hideNoGit = isHideNoGitEnabled(item);
55114
- const isLink = isMetadataFlagEnabled(item, LINK_KEY);
55254
+ const isLink = isLinkEnabled(item);
55115
55255
  if (context.isPreview) {
55116
55256
  const text = item.rawValue ? "main" : "⎇ main";
55117
- return isLink ? renderOsc8Link("https://github.com/owner/repo/tree/main", text) : text;
55257
+ return isLink ? renderOsc8Link(buildBranchWebUrl(PREVIEW_REMOTE, "main"), text) : text;
55118
55258
  }
55119
55259
  if (!isInsideGitWorkTree(context)) {
55120
55260
  return hideNoGit ? null : "⎇ no git";
@@ -55125,10 +55265,9 @@ class GitBranchWidget {
55125
55265
  }
55126
55266
  const displayText = item.rawValue ? branch : `⎇ ${branch}`;
55127
55267
  if (isLink) {
55128
- const remoteUrl = runGit("remote get-url origin", context);
55129
- const baseUrl = remoteUrl ? parseGitHubBaseUrl(remoteUrl) : null;
55130
- if (baseUrl) {
55131
- return renderOsc8Link(`${baseUrl}/tree/${encodeGitRefForUrlPath(branch)}`, displayText);
55268
+ const origin = getRemoteInfo("origin", context);
55269
+ if (origin) {
55270
+ return renderOsc8Link(buildBranchWebUrl(origin, encodeGitRefForUrlPath(branch)), displayText);
55132
55271
  }
55133
55272
  }
55134
55273
  return displayText;
@@ -55139,7 +55278,7 @@ class GitBranchWidget {
55139
55278
  getCustomKeybinds() {
55140
55279
  return [
55141
55280
  ...getHideNoGitKeybinds(),
55142
- { key: "l", label: "(l)ink to GitHub", action: TOGGLE_LINK_ACTION }
55281
+ { key: "l", label: "(l)ink to repo", action: TOGGLE_LINK_ACTION }
55143
55282
  ];
55144
55283
  }
55145
55284
  supportsRawValue() {
@@ -56064,106 +56203,6 @@ class GitShaWidget {
56064
56203
  return true;
56065
56204
  }
56066
56205
  }
56067
- // src/utils/git-remote.ts
56068
- function parseRemoteUrl(url2) {
56069
- const trimmed = url2.trim();
56070
- if (trimmed.length === 0) {
56071
- return null;
56072
- }
56073
- const sshMatch = !trimmed.includes("://") ? /^(?:[^@]+@)?([^:]+):(.+?)(?:\.git)?\/?$/.exec(trimmed) : null;
56074
- if (sshMatch?.[1] && sshMatch[2]) {
56075
- const pathSegments = sshMatch[2].split("/").filter(Boolean);
56076
- const repo = pathSegments.at(-1);
56077
- const owner = pathSegments.slice(0, -1).join("/");
56078
- if (!owner || !repo) {
56079
- return null;
56080
- }
56081
- return {
56082
- host: sshMatch[1],
56083
- owner,
56084
- repo
56085
- };
56086
- }
56087
- try {
56088
- const parsedUrl = new URL(trimmed);
56089
- const supportedProtocols = new Set(["http:", "https:", "ssh:", "git:"]);
56090
- if (!supportedProtocols.has(parsedUrl.protocol)) {
56091
- return null;
56092
- }
56093
- const pathname = parsedUrl.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
56094
- const segments = pathname.split("/").filter(Boolean);
56095
- const repo = segments.at(-1);
56096
- const owner = segments.slice(0, -1).join("/");
56097
- if (!owner || !repo) {
56098
- return null;
56099
- }
56100
- return {
56101
- host: parsedUrl.hostname,
56102
- owner,
56103
- repo
56104
- };
56105
- } catch {
56106
- return null;
56107
- }
56108
- }
56109
- function getRemoteInfo(remoteName, context) {
56110
- const url2 = runGit(`remote get-url ${remoteName}`, context);
56111
- if (!url2) {
56112
- return null;
56113
- }
56114
- const parsed = parseRemoteUrl(url2);
56115
- if (!parsed) {
56116
- return null;
56117
- }
56118
- return {
56119
- name: remoteName,
56120
- url: url2,
56121
- host: parsed.host,
56122
- owner: parsed.owner,
56123
- repo: parsed.repo
56124
- };
56125
- }
56126
- function getTrackingRemoteName(context) {
56127
- const upstreamRef = runGit("rev-parse --abbrev-ref --symbolic-full-name @{upstream}", context);
56128
- if (!upstreamRef) {
56129
- return null;
56130
- }
56131
- const remotes = listRemotes(context).slice().sort((left, right) => right.length - left.length);
56132
- return remotes.find((remote) => upstreamRef === remote || upstreamRef.startsWith(`${remote}/`)) ?? null;
56133
- }
56134
- function getUpstreamRemoteInfo(context) {
56135
- const namedUpstream = getRemoteInfo("upstream", context);
56136
- if (namedUpstream) {
56137
- return namedUpstream;
56138
- }
56139
- const trackingRemoteName = getTrackingRemoteName(context);
56140
- if (!trackingRemoteName) {
56141
- return null;
56142
- }
56143
- return getRemoteInfo(trackingRemoteName, context);
56144
- }
56145
- function getForkStatus(context) {
56146
- const origin = getRemoteInfo("origin", context);
56147
- const upstream = getRemoteInfo("upstream", context);
56148
- const isFork = Boolean(origin && upstream && (origin.owner !== upstream.owner || origin.repo !== upstream.repo));
56149
- return {
56150
- isFork,
56151
- origin,
56152
- upstream
56153
- };
56154
- }
56155
- function listRemotes(context) {
56156
- const output = runGit("remote", context);
56157
- if (!output) {
56158
- return [];
56159
- }
56160
- return output.split(`
56161
- `).filter(Boolean);
56162
- }
56163
- function buildRepoWebUrl(remote) {
56164
- return `https://${remote.host}/${remote.owner}/${remote.repo}`;
56165
- }
56166
-
56167
56206
  // src/widgets/shared/git-remote.ts
56168
56207
  var HIDE_NO_REMOTE_KEY = "hideNoRemote";
56169
56208
  var TOGGLE_NO_REMOTE_ACTION = "toggle-no-remote";
@@ -58336,7 +58375,7 @@ function List({
58336
58375
  initialSelection = 0,
58337
58376
  showBackButton,
58338
58377
  color,
58339
- wrapNavigation = false,
58378
+ wrapNavigation = true,
58340
58379
  ...boxProps
58341
58380
  }) {
58342
58381
  const [selectedIndex, setSelectedIndex] = import_react34.useState(initialSelection);
@@ -58364,6 +58403,9 @@ function List({
58364
58403
  }
58365
58404
  }, [selectedIndex, selectedValue]);
58366
58405
  use_input_default((_, key) => {
58406
+ if (selectableItems.length === 0) {
58407
+ return;
58408
+ }
58367
58409
  if (key.upArrow) {
58368
58410
  const prev = selectedIndex - 1;
58369
58411
  const prevIndex = prev < 0 ? wrapNavigation ? selectableItems.length - 1 : 0 : prev;
@@ -59532,6 +59574,21 @@ function setPickerState(setWidgetPicker, normalizeState, updater) {
59532
59574
  function getPickerCategories(widgetCategories) {
59533
59575
  return [...widgetCategories];
59534
59576
  }
59577
+ function wrapIndex(index, length) {
59578
+ if (length === 0) {
59579
+ return -1;
59580
+ }
59581
+ if (index < 0) {
59582
+ return length - 1;
59583
+ }
59584
+ if (index > length - 1) {
59585
+ return 0;
59586
+ }
59587
+ return index;
59588
+ }
59589
+ function getAdjacentIndex(currentIndex, length, isForward) {
59590
+ return wrapIndex(currentIndex + (isForward ? 1 : -1), length);
59591
+ }
59535
59592
  function normalizePickerState(state, widgetCatalog, widgetCategories) {
59536
59593
  const filteredCategories = getPickerCategories(widgetCategories);
59537
59594
  const selectedCategory = state.selectedCategory && filteredCategories.includes(state.selectedCategory) ? state.selectedCategory : filteredCategories[0] ?? null;
@@ -59614,7 +59671,7 @@ function handlePickerInputMode({
59614
59671
  if (currentIndex === -1) {
59615
59672
  currentIndex = 0;
59616
59673
  }
59617
- const nextIndex = key.downArrow ? Math.min(topLevelSearchEntries.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
59674
+ const nextIndex = getAdjacentIndex(currentIndex, topLevelSearchEntries.length, Boolean(key.downArrow));
59618
59675
  const nextType = topLevelSearchEntries[nextIndex]?.type ?? null;
59619
59676
  setPickerState(setWidgetPicker, normalizeState, (prev) => ({
59620
59677
  ...prev,
@@ -59628,7 +59685,7 @@ function handlePickerInputMode({
59628
59685
  if (currentIndex === -1) {
59629
59686
  currentIndex = 0;
59630
59687
  }
59631
- const nextIndex = key.downArrow ? Math.min(filteredCategories.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
59688
+ const nextIndex = getAdjacentIndex(currentIndex, filteredCategories.length, Boolean(key.downArrow));
59632
59689
  const nextCategory = filteredCategories[nextIndex] ?? null;
59633
59690
  setPickerState(setWidgetPicker, normalizeState, (prev) => ({
59634
59691
  ...prev,
@@ -59673,7 +59730,7 @@ function handlePickerInputMode({
59673
59730
  if (currentIndex === -1) {
59674
59731
  currentIndex = 0;
59675
59732
  }
59676
- const nextIndex = key.downArrow ? Math.min(filteredWidgets.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
59733
+ const nextIndex = getAdjacentIndex(currentIndex, filteredWidgets.length, Boolean(key.downArrow));
59677
59734
  const nextType = filteredWidgets[nextIndex]?.type ?? null;
59678
59735
  setPickerState(setWidgetPicker, normalizeState, (prev) => ({
59679
59736
  ...prev,
@@ -59702,24 +59759,26 @@ function handleMoveInputMode({
59702
59759
  setSelectedIndex,
59703
59760
  setMoveMode
59704
59761
  }) {
59705
- if (key.upArrow && selectedIndex > 0) {
59762
+ if (key.upArrow && widgets.length > 1) {
59706
59763
  const newWidgets = [...widgets];
59764
+ const targetIndex = getAdjacentIndex(selectedIndex, widgets.length, false);
59707
59765
  const temp = newWidgets[selectedIndex];
59708
- const prev = newWidgets[selectedIndex - 1];
59766
+ const prev = newWidgets[targetIndex];
59709
59767
  if (temp && prev) {
59710
- [newWidgets[selectedIndex], newWidgets[selectedIndex - 1]] = [prev, temp];
59768
+ [newWidgets[selectedIndex], newWidgets[targetIndex]] = [prev, temp];
59711
59769
  }
59712
59770
  onUpdate(newWidgets);
59713
- setSelectedIndex(selectedIndex - 1);
59714
- } else if (key.downArrow && selectedIndex < widgets.length - 1) {
59771
+ setSelectedIndex(targetIndex);
59772
+ } else if (key.downArrow && widgets.length > 1) {
59715
59773
  const newWidgets = [...widgets];
59774
+ const targetIndex = getAdjacentIndex(selectedIndex, widgets.length, true);
59716
59775
  const temp = newWidgets[selectedIndex];
59717
- const next = newWidgets[selectedIndex + 1];
59776
+ const next = newWidgets[targetIndex];
59718
59777
  if (temp && next) {
59719
- [newWidgets[selectedIndex], newWidgets[selectedIndex + 1]] = [next, temp];
59778
+ [newWidgets[selectedIndex], newWidgets[targetIndex]] = [next, temp];
59720
59779
  }
59721
59780
  onUpdate(newWidgets);
59722
- setSelectedIndex(selectedIndex + 1);
59781
+ setSelectedIndex(targetIndex);
59723
59782
  } else if (key.escape || key.return) {
59724
59783
  setMoveMode(false);
59725
59784
  }
@@ -59737,12 +59796,13 @@ function handleNormalInputMode({
59737
59796
  setShowClearConfirm,
59738
59797
  openWidgetPicker,
59739
59798
  getCustomKeybindsForWidget,
59740
- setCustomEditorWidget
59799
+ setCustomEditorWidget,
59800
+ getUniqueBackgroundColor
59741
59801
  }) {
59742
59802
  if (key.upArrow && widgets.length > 0) {
59743
- setSelectedIndex(Math.max(0, selectedIndex - 1));
59803
+ setSelectedIndex(getAdjacentIndex(selectedIndex, widgets.length, false));
59744
59804
  } else if (key.downArrow && widgets.length > 0) {
59745
- setSelectedIndex(Math.min(widgets.length - 1, selectedIndex + 1));
59805
+ setSelectedIndex(getAdjacentIndex(selectedIndex, widgets.length, true));
59746
59806
  } else if (key.leftArrow && widgets.length > 0) {
59747
59807
  openWidgetPicker("change");
59748
59808
  } else if (key.rightArrow && widgets.length > 0) {
@@ -59759,6 +59819,26 @@ function handleNormalInputMode({
59759
59819
  if (selectedIndex >= newWidgets.length && selectedIndex > 0) {
59760
59820
  setSelectedIndex(selectedIndex - 1);
59761
59821
  }
59822
+ } else if (input === "k" && widgets.length > 0) {
59823
+ const source = widgets[selectedIndex];
59824
+ if (!source) {
59825
+ return;
59826
+ }
59827
+ const cloneInsertPosition = selectedIndex + 1;
59828
+ const uniqueBackgroundColor = getUniqueBackgroundColor?.(cloneInsertPosition);
59829
+ const clone3 = {
59830
+ ...source,
59831
+ id: generateGuid(),
59832
+ ...source.metadata ? { metadata: { ...source.metadata } } : {},
59833
+ ...uniqueBackgroundColor && { backgroundColor: uniqueBackgroundColor }
59834
+ };
59835
+ const newWidgets = [
59836
+ ...widgets.slice(0, cloneInsertPosition),
59837
+ clone3,
59838
+ ...widgets.slice(cloneInsertPosition)
59839
+ ];
59840
+ onUpdate(newWidgets);
59841
+ setSelectedIndex(cloneInsertPosition);
59762
59842
  } else if (input === "c") {
59763
59843
  if (widgets.length > 0) {
59764
59844
  setShowClearConfirm(true);
@@ -59959,7 +60039,8 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
59959
60039
  setShowClearConfirm,
59960
60040
  openWidgetPicker,
59961
60041
  getCustomKeybindsForWidget,
59962
- setCustomEditorWidget
60042
+ setCustomEditorWidget,
60043
+ getUniqueBackgroundColor
59963
60044
  });
59964
60045
  });
59965
60046
  const getWidgetDisplay = (widget) => {
@@ -60007,7 +60088,7 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
60007
60088
  helpText += ", Space edit separator";
60008
60089
  }
60009
60090
  if (hasWidgets) {
60010
- helpText += ", Enter to move, (a)dd via picker, (i)nsert via picker, (d)elete, (c)lear line";
60091
+ helpText += ", Enter to move, (a)dd via picker, (i)nsert via picker, (d)elete, (k)lone, (c)lear line";
60011
60092
  }
60012
60093
  if (canToggleRaw) {
60013
60094
  helpText += ", (r)aw value";
@@ -60440,26 +60521,28 @@ var LineSelector = ({
60440
60521
  return;
60441
60522
  }
60442
60523
  if (moveMode) {
60443
- if (key.upArrow && selectedIndex > 0) {
60524
+ if (key.upArrow && localLines.length > 1) {
60444
60525
  const newLines = [...localLines];
60526
+ const targetIndex = selectedIndex - 1 < 0 ? localLines.length - 1 : selectedIndex - 1;
60445
60527
  const temp = newLines[selectedIndex];
60446
- const prev = newLines[selectedIndex - 1];
60528
+ const prev = newLines[targetIndex];
60447
60529
  if (temp && prev) {
60448
- [newLines[selectedIndex], newLines[selectedIndex - 1]] = [prev, temp];
60530
+ [newLines[selectedIndex], newLines[targetIndex]] = [prev, temp];
60449
60531
  }
60450
60532
  setLocalLines(newLines);
60451
60533
  onLinesUpdate(newLines);
60452
- setSelectedIndex(selectedIndex - 1);
60453
- } else if (key.downArrow && selectedIndex < localLines.length - 1) {
60534
+ setSelectedIndex(targetIndex);
60535
+ } else if (key.downArrow && localLines.length > 1) {
60454
60536
  const newLines = [...localLines];
60537
+ const targetIndex = selectedIndex + 1 > localLines.length - 1 ? 0 : selectedIndex + 1;
60455
60538
  const temp = newLines[selectedIndex];
60456
- const next = newLines[selectedIndex + 1];
60539
+ const next = newLines[targetIndex];
60457
60540
  if (temp && next) {
60458
- [newLines[selectedIndex], newLines[selectedIndex + 1]] = [next, temp];
60541
+ [newLines[selectedIndex], newLines[targetIndex]] = [next, temp];
60459
60542
  }
60460
60543
  setLocalLines(newLines);
60461
60544
  onLinesUpdate(newLines);
60462
- setSelectedIndex(selectedIndex + 1);
60545
+ setSelectedIndex(targetIndex);
60463
60546
  } else if (key.escape || key.return) {
60464
60547
  setMoveMode(false);
60465
60548
  }
@@ -63223,7 +63306,10 @@ var CopilotPayloadSchema = exports_external.object({
63223
63306
  transcript_path: exports_external.string().optional(),
63224
63307
  model: exports_external.object({
63225
63308
  id: exports_external.string().nullable().optional(),
63226
- display_name: exports_external.string().nullable().optional()
63309
+ display_name: exports_external.string().nullable().optional(),
63310
+ thinking_effort: exports_external.string().nullable().optional(),
63311
+ thinking_effort_level: exports_external.string().nullable().optional(),
63312
+ reasoning_effort: exports_external.string().nullable().optional()
63227
63313
  }).optional(),
63228
63314
  workspace: exports_external.object({ current_dir: exports_external.string().optional() }).optional(),
63229
63315
  version: exports_external.string().optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copilot-statusline",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "A customizable status line formatter for GitHub Copilot CLI — based on ccstatusline",
5
5
  "module": "src/copilot-statusline.ts",
6
6
  "type": "module",