@gajae-code/tui 0.8.0 → 0.8.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@gajae-code/tui",
4
- "version": "0.8.0",
4
+ "version": "0.8.1",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://gajae-code.com",
7
7
  "author": "Yeachan-Heo",
@@ -38,8 +38,8 @@
38
38
  "fmt": "biome format --write ."
39
39
  },
40
40
  "dependencies": {
41
- "@gajae-code/natives": "0.8.0",
42
- "@gajae-code/utils": "0.8.0",
41
+ "@gajae-code/natives": "0.8.1",
42
+ "@gajae-code/utils": "0.8.1",
43
43
  "lru-cache": "11.3.6",
44
44
  "marked": "^18.0.3"
45
45
  },
@@ -1152,7 +1152,7 @@ export class Editor implements Component, Focusable {
1152
1152
  // Check for stale autocomplete state due to debounce
1153
1153
  const currentLine = this.#state.lines[this.#state.cursorLine] ?? "";
1154
1154
  const currentTextBeforeCursor = currentLine.slice(0, this.#state.cursorCol);
1155
- if (currentTextBeforeCursor !== this.#autocompletePrefix) {
1155
+ if (!currentTextBeforeCursor.endsWith(this.#autocompletePrefix)) {
1156
1156
  // Autocomplete is stale - cancel and fall through to normal submission
1157
1157
  this.#cancelAutocomplete();
1158
1158
  } else {
@@ -1290,8 +1290,8 @@ export class Editor implements Component, Focusable {
1290
1290
  const currentLine = this.#state.lines[this.#state.cursorLine] ?? "";
1291
1291
  const textBeforeCursor = currentLine.slice(0, this.#state.cursorCol);
1292
1292
  if (
1293
- textBeforeCursor.startsWith("/") &&
1294
- this.#isInSubmittedSlashCommandContext() &&
1293
+ (this.#isInSubmittedSlashCommandContext() ||
1294
+ this.#getSlashTokenBeforeCursor()?.startsWith("/skill") === true) &&
1295
1295
  this.#autocompleteProvider?.trySyncSlashCompletion
1296
1296
  ) {
1297
1297
  const syncResult = this.#autocompleteProvider.trySyncSlashCompletion(textBeforeCursor);
@@ -1728,7 +1728,8 @@ export class Editor implements Component, Focusable {
1728
1728
 
1729
1729
  // Check if we should trigger or update autocomplete
1730
1730
  if (!this.#autocompleteState) {
1731
- // Auto-trigger for "/" at the start of a line (slash commands)
1731
+ // Auto-trigger for "/" at the start of a submitted command.
1732
+ // Inline skill autocomplete starts after the token becomes "/skill...".
1732
1733
  if (char === "/" && this.#isAtStartOfSubmittedMessage()) {
1733
1734
  this.#tryTriggerAutocomplete();
1734
1735
  }
@@ -1750,8 +1751,8 @@ export class Editor implements Component, Focusable {
1750
1751
  else if (/[a-zA-Z0-9.\-_/]/.test(char)) {
1751
1752
  const currentLine = this.#state.lines[this.#state.cursorLine] || "";
1752
1753
  const textBeforeCursor = currentLine.slice(0, this.#state.cursorCol);
1753
- // Check if we're in a slash command (with or without space for arguments)
1754
- if (this.#isInSubmittedSlashCommandContext()) {
1754
+ // Check if we're in a slash command or inline slash token
1755
+ if (this.#isInSubmittedSlashCommandContext() || this.#isInSlashTokenContext()) {
1755
1756
  this.#tryTriggerAutocomplete();
1756
1757
  }
1757
1758
  // Check if we're in an @ file reference context
@@ -1946,8 +1947,8 @@ export class Editor implements Component, Focusable {
1946
1947
  // If autocomplete was cancelled (no matches), re-trigger if we're in a completable context
1947
1948
  const currentLine = this.#state.lines[this.#state.cursorLine] || "";
1948
1949
  const textBeforeCursor = currentLine.slice(0, this.#state.cursorCol);
1949
- // Slash command context
1950
- if (this.#isInSubmittedSlashCommandContext()) {
1950
+ // Slash command or inline slash token context
1951
+ if (this.#isInSubmittedSlashCommandContext() || this.#isInSlashTokenContext()) {
1951
1952
  this.#tryTriggerAutocomplete();
1952
1953
  }
1953
1954
  // @ file reference context
@@ -2103,7 +2104,7 @@ export class Editor implements Component, Focusable {
2103
2104
  } else {
2104
2105
  const currentLine = this.#state.lines[this.#state.cursorLine] || "";
2105
2106
  const textBeforeCursor = currentLine.slice(0, this.#state.cursorCol);
2106
- if (this.#isInSubmittedSlashCommandContext()) {
2107
+ if (this.#isInSubmittedSlashCommandContext() || this.#isInSlashTokenContext()) {
2107
2108
  this.#tryTriggerAutocomplete();
2108
2109
  } else if (textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/)) {
2109
2110
  this.#tryTriggerAutocomplete();
@@ -2417,8 +2418,8 @@ export class Editor implements Component, Focusable {
2417
2418
  } else {
2418
2419
  const currentLine = this.#state.lines[this.#state.cursorLine] || "";
2419
2420
  const textBeforeCursor = currentLine.slice(0, this.#state.cursorCol);
2420
- // Slash command context
2421
- if (this.#isInSubmittedSlashCommandContext()) {
2421
+ // Slash command or inline slash token context
2422
+ if (this.#isInSubmittedSlashCommandContext() || this.#isInSlashTokenContext()) {
2422
2423
  this.#tryTriggerAutocomplete();
2423
2424
  }
2424
2425
  // @ file reference context
@@ -2647,6 +2648,17 @@ export class Editor implements Component, Focusable {
2647
2648
  return this.#hasOnlyWhitespaceBeforeCursorLine() && beforeCursor.trimStart().startsWith("/");
2648
2649
  }
2649
2650
 
2651
+ #getSlashTokenBeforeCursor(): string | null {
2652
+ const currentLine = this.#state.lines[this.#state.cursorLine] || "";
2653
+ const beforeCursor = currentLine.slice(0, this.#state.cursorCol);
2654
+ const match = beforeCursor.match(/(?:^|\s)(\/[^\s]*)$/);
2655
+ return match?.[1] ?? null;
2656
+ }
2657
+
2658
+ #isInSlashTokenContext(): boolean {
2659
+ return this.#getSlashTokenBeforeCursor()?.startsWith("/skill") === true;
2660
+ }
2661
+
2650
2662
  #isSlashCommandNameAutocompleteSelection(): boolean {
2651
2663
  if (this.#autocompleteState !== "regular") {
2652
2664
  return false;