@kubbisec/ai-linux-arm64 0.1.21 → 0.1.22

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 (130) hide show
  1. package/bundled/clarify/clarify-gate-state.d.ts +1 -1
  2. package/bundled/clarify/clarify-gate-state.js +3 -3
  3. package/bundled/clarify/clarify-gate.d.ts +21 -14
  4. package/bundled/clarify/clarify-gate.js +118 -111
  5. package/bundled/clarify/clarify-select-panel.d.ts +16 -9
  6. package/bundled/clarify/clarify-select-panel.js +65 -67
  7. package/bundled/clarify/clarify-ui-state.d.ts +12 -10
  8. package/bundled/clarify/clarify-ui-state.js +26 -26
  9. package/bundled/clarify/parse-clarify-answer.d.ts +29 -18
  10. package/bundled/clarify/parse-clarify-answer.js +39 -45
  11. package/bundled/clarify/question-format.d.ts +34 -23
  12. package/bundled/clarify/question-format.js +112 -119
  13. package/bundled/clarify/questionnaire-tool.d.ts +28 -17
  14. package/bundled/clarify/questionnaire-tool.js +180 -144
  15. package/bundled/clarify/scope-discovery.d.ts +8 -5
  16. package/bundled/clarify/scope-discovery.js +102 -110
  17. package/bundled/clarify/session-questionnaire.d.ts +48 -13
  18. package/bundled/clarify/session-questionnaire.js +304 -312
  19. package/bundled/clarify/session-questionnaire.types.d.ts +29 -27
  20. package/bundled/clarify/session-questionnaire.types.js +10 -10
  21. package/bundled/components/kubbisec-model-selector.d.ts +47 -34
  22. package/bundled/components/kubbisec-model-selector.js +187 -177
  23. package/bundled/config/config.d.ts +6 -6
  24. package/bundled/config/config.js +55 -55
  25. package/bundled/config/detect-local-llm-providers.d.ts +26 -16
  26. package/bundled/config/detect-local-llm-providers.js +130 -142
  27. package/bundled/config/ensure-kubbisec-project-settings.d.ts +9 -9
  28. package/bundled/config/ensure-kubbisec-project-settings.js +44 -48
  29. package/bundled/config/extended-context.d.ts +5 -6
  30. package/bundled/config/extended-context.js +23 -22
  31. package/bundled/config/feature-flags.d.ts +10 -2
  32. package/bundled/config/feature-flags.js +8 -2
  33. package/bundled/config/format-kubbisec-footer-status.d.ts +1 -1
  34. package/bundled/config/format-kubbisec-footer-status.js +26 -31
  35. package/bundled/config/kubbisec-extension-manifest.d.ts +22 -2
  36. package/bundled/config/kubbisec-extension-manifest.js +20 -20
  37. package/bundled/config/llm-config-mutations.d.ts +51 -25
  38. package/bundled/config/llm-config-mutations.js +173 -182
  39. package/bundled/config/llm-config.d.ts +54 -41
  40. package/bundled/config/llm-config.js +199 -199
  41. package/bundled/config/llm-provider-catalog.d.ts +18 -15
  42. package/bundled/config/llm-provider-catalog.js +45 -46
  43. package/bundled/config/materialize-kubbisec-pi-resources.d.ts +1 -1
  44. package/bundled/config/materialize-kubbisec-pi-resources.js +174 -183
  45. package/bundled/config/register-custom-llm-providers.d.ts +11 -5
  46. package/bundled/config/register-custom-llm-providers.js +17 -15
  47. package/bundled/config/register-kubbisec-llm-provider.d.ts +14 -10
  48. package/bundled/config/register-kubbisec-llm-provider.js +50 -42
  49. package/bundled/config/resolve-agents-context-file.d.ts +1 -1
  50. package/bundled/config/resolve-agents-context-file.js +33 -34
  51. package/bundled/config/resource-budget.d.ts +12 -12
  52. package/bundled/config/resource-budget.js +28 -28
  53. package/bundled/config/sync-kubbisec-pi-models.d.ts +6 -3
  54. package/bundled/config/sync-kubbisec-pi-models.js +58 -58
  55. package/bundled/copy/cli-reference-index.d.ts +3 -2
  56. package/bundled/copy/cli-reference-index.js +1 -1
  57. package/bundled/copy/kubbisec-shell-copy.d.ts +11 -6
  58. package/bundled/copy/kubbisec-shell-copy.js +1 -1
  59. package/bundled/extensions/cli-local-shared.d.ts +45 -26
  60. package/bundled/extensions/cli-local-shared.js +128 -118
  61. package/bundled/extensions/kubbisec-aspm-local.extension.d.ts +18 -15
  62. package/bundled/extensions/kubbisec-aspm-local.extension.js +118 -114
  63. package/bundled/extensions/kubbisec-brand.extension.d.ts +1 -1
  64. package/bundled/extensions/kubbisec-brand.extension.js +25 -25
  65. package/bundled/extensions/kubbisec-byok-provider.extension.d.ts +1 -1
  66. package/bundled/extensions/kubbisec-byok-provider.extension.js +2 -2
  67. package/bundled/extensions/kubbisec-clarify.extension.d.ts +64 -35
  68. package/bundled/extensions/kubbisec-clarify.extension.js +323 -305
  69. package/bundled/extensions/kubbisec-exit.extension.d.ts +1 -1
  70. package/bundled/extensions/kubbisec-exit.extension.js +29 -32
  71. package/bundled/extensions/kubbisec-extended-context.extension.d.ts +1 -1
  72. package/bundled/extensions/kubbisec-extended-context.extension.js +56 -43
  73. package/bundled/extensions/kubbisec-footer.extension.d.ts +14 -14
  74. package/bundled/extensions/kubbisec-footer.extension.js +205 -215
  75. package/bundled/extensions/kubbisec-github-local.extension.d.ts +26 -18
  76. package/bundled/extensions/kubbisec-github-local.extension.js +123 -116
  77. package/bundled/extensions/kubbisec-llm-config.extension.d.ts +1 -1
  78. package/bundled/extensions/kubbisec-llm-config.extension.js +200 -181
  79. package/bundled/extensions/kubbisec-memory.extension.d.ts +9 -7
  80. package/bundled/extensions/kubbisec-memory.extension.js +88 -95
  81. package/bundled/extensions/kubbisec-naus-local.extension.d.ts +18 -15
  82. package/bundled/extensions/kubbisec-naus-local.extension.js +132 -111
  83. package/bundled/extensions/kubbisec-platform-tools.extension.d.ts +31 -21
  84. package/bundled/extensions/kubbisec-platform-tools.extension.js +152 -152
  85. package/bundled/extensions/kubbisec-runtime-status.extension.d.ts +10 -8
  86. package/bundled/extensions/kubbisec-runtime-status.extension.js +15 -13
  87. package/bundled/extensions/kubbisec-scope.extension.d.ts +12 -7
  88. package/bundled/extensions/kubbisec-scope.extension.js +13 -13
  89. package/bundled/extensions/kubbisec-skill-mentions.extension.d.ts +27 -16
  90. package/bundled/extensions/kubbisec-skill-mentions.extension.js +73 -63
  91. package/bundled/extensions/kubbisec-skill-telemetry.extension.d.ts +2 -3
  92. package/bundled/extensions/kubbisec-skill-telemetry.extension.js +59 -64
  93. package/bundled/extensions/kubbisec-theme-lock.extension.d.ts +1 -1
  94. package/bundled/extensions/kubbisec-theme-lock.extension.js +33 -34
  95. package/bundled/extensions/kubbisec-ui.extension.d.ts +1 -1
  96. package/bundled/extensions/kubbisec-ui.extension.js +114 -109
  97. package/bundled/extensions/kubbisec-workflow.extension.d.ts +20 -18
  98. package/bundled/extensions/kubbisec-workflow.extension.js +138 -140
  99. package/bundled/node_modules/@aspm/shared/dist/redaction.test.d.ts +2 -0
  100. package/bundled/node_modules/@aspm/shared/dist/redaction.test.d.ts.map +1 -0
  101. package/bundled/node_modules/@aspm/shared/dist/redaction.test.js +626 -0
  102. package/bundled/node_modules/@aspm/shared/dist/redaction.test.js.map +1 -0
  103. package/bundled/resolve-bundled-dist-root.js +122 -131
  104. package/bundled/skills/at-path-mentions.d.ts +1 -1
  105. package/bundled/skills/at-path-mentions.js +146 -153
  106. package/bundled/skills/chat-mention-render.d.ts +2 -2
  107. package/bundled/skills/chat-mention-render.js +121 -126
  108. package/bundled/skills/chat-mentions.d.ts +17 -8
  109. package/bundled/skills/chat-mentions.js +76 -76
  110. package/bundled/skills/list-bundled-skills.d.ts +3 -3
  111. package/bundled/skills/list-bundled-skills.js +33 -35
  112. package/bundled/skills/skill-mention.d.ts +10 -2
  113. package/bundled/skills/skill-mention.js +10 -2
  114. package/bundled/theme/clear-terminal.d.ts +1 -1
  115. package/bundled/theme/clear-terminal.js +3 -4
  116. package/bundled/theme/footer-render-hook.d.ts +1 -1
  117. package/bundled/theme/footer-render-hook.js +3 -3
  118. package/bundled/theme/kubbisec-brand-fg.d.ts +1 -1
  119. package/bundled/theme/kubbisec-brand-fg.js +2 -2
  120. package/bundled/theme/kubbisec-menu-themes.d.ts +7 -7
  121. package/bundled/theme/kubbisec-menu-themes.js +30 -31
  122. package/bundled/theme/kubbisec-theme-name.d.ts +1 -1
  123. package/bundled/theme/kubbisec-theme-name.js +1 -1
  124. package/bundled/theme/patch-pi-settings-theme.runtime.d.ts +1 -1
  125. package/bundled/theme/patch-pi-settings-theme.runtime.js +11 -10
  126. package/bundled/theme/render-compact-header.d.ts +13 -5
  127. package/bundled/theme/render-compact-header.js +127 -129
  128. package/bundled/workflow/session-workflow-mode.d.ts +1 -1
  129. package/bundled/workflow/session-workflow-mode.js +33 -33
  130. package/package.json +1 -1
@@ -1,160 +1,155 @@
1
1
  import { visibleWidth } from "@earendil-works/pi-tui";
2
2
  import { PLAN_MENTION_ALIASES } from "./chat-mentions.js";
3
+
3
4
  const SKILL_SLASH_RE = /\/skill:([a-z0-9_-]+)/gi;
4
5
  const AT_SKILL_RE = /@skill\s+([^\s@/]+)/gi;
5
6
  const PLAN_TOKEN_RE = /\/mode:plan\b/gi;
6
7
  const AT_PLAN_PATTERN = PLAN_MENTION_ALIASES.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
7
- .sort((a, b) => b.length - a.length)
8
- .join("|");
8
+ .sort((a, b) => b.length - a.length)
9
+ .join("|");
9
10
  const AT_PLAN_RE = new RegExp(`(?:^|[\\s"'=])(${AT_PLAN_PATTERN})(?=\\s|$)`, "gi");
10
11
  const PLAN_VISIBLE_LABEL = "@plan";
11
12
  function findNextMentionMatch(line, cursor) {
12
- const candidates = [];
13
- SKILL_SLASH_RE.lastIndex = cursor;
14
- const slashMatch = SKILL_SLASH_RE.exec(line);
15
- if (slashMatch?.index !== undefined) {
16
- candidates.push({
17
- index: slashMatch.index,
18
- length: slashMatch[0].length,
19
- span: { kind: "skill", name: slashMatch[1] ?? "", source: "slash" },
20
- });
21
- }
22
- AT_SKILL_RE.lastIndex = cursor;
23
- const atMatch = AT_SKILL_RE.exec(line);
24
- if (atMatch?.index !== undefined) {
25
- candidates.push({
26
- index: atMatch.index,
27
- length: atMatch[0].length,
28
- span: { kind: "skill", name: atMatch[1] ?? "", source: "at" },
29
- });
30
- }
31
- PLAN_TOKEN_RE.lastIndex = cursor;
32
- const planMatch = PLAN_TOKEN_RE.exec(line);
33
- if (planMatch?.index !== undefined) {
34
- candidates.push({
35
- index: planMatch.index,
36
- length: planMatch[0].length,
37
- span: { kind: "plan", logicalToken: planMatch[0] },
38
- });
39
- }
40
- AT_PLAN_RE.lastIndex = cursor;
41
- const atPlanMatch = AT_PLAN_RE.exec(line);
42
- if (atPlanMatch?.index !== undefined) {
43
- const token = atPlanMatch[1] ?? "@plan";
44
- const leading = atPlanMatch[0].length - token.length;
45
- const index = atPlanMatch.index + leading;
46
- candidates.push({
47
- index,
48
- length: token.length,
49
- span: { kind: "plan", logicalToken: token },
50
- });
51
- }
52
- if (candidates.length === 0)
53
- return null;
54
- return candidates.reduce((earliest, candidate) => candidate.index < earliest.index ? candidate : earliest);
13
+ const candidates = [];
14
+ SKILL_SLASH_RE.lastIndex = cursor;
15
+ const slashMatch = SKILL_SLASH_RE.exec(line);
16
+ if (slashMatch?.index !== undefined) {
17
+ candidates.push({
18
+ index: slashMatch.index,
19
+ length: slashMatch[0].length,
20
+ span: { kind: "skill", name: slashMatch[1] ?? "", source: "slash" },
21
+ });
22
+ }
23
+ AT_SKILL_RE.lastIndex = cursor;
24
+ const atMatch = AT_SKILL_RE.exec(line);
25
+ if (atMatch?.index !== undefined) {
26
+ candidates.push({
27
+ index: atMatch.index,
28
+ length: atMatch[0].length,
29
+ span: { kind: "skill", name: atMatch[1] ?? "", source: "at" },
30
+ });
31
+ }
32
+ PLAN_TOKEN_RE.lastIndex = cursor;
33
+ const planMatch = PLAN_TOKEN_RE.exec(line);
34
+ if (planMatch?.index !== undefined) {
35
+ candidates.push({
36
+ index: planMatch.index,
37
+ length: planMatch[0].length,
38
+ span: { kind: "plan", logicalToken: planMatch[0] },
39
+ });
40
+ }
41
+ AT_PLAN_RE.lastIndex = cursor;
42
+ const atPlanMatch = AT_PLAN_RE.exec(line);
43
+ if (atPlanMatch?.index !== undefined) {
44
+ const token = atPlanMatch[1] ?? "@plan";
45
+ const leading = atPlanMatch[0].length - token.length;
46
+ const index = atPlanMatch.index + leading;
47
+ candidates.push({
48
+ index,
49
+ length: token.length,
50
+ span: { kind: "plan", logicalToken: token },
51
+ });
52
+ }
53
+ if (candidates.length === 0) return null;
54
+ return candidates.reduce((earliest, candidate) =>
55
+ candidate.index < earliest.index ? candidate : earliest,
56
+ );
55
57
  }
56
58
  function parseMentionSpans(line) {
57
- const spans = [];
58
- let cursor = 0;
59
- while (cursor < line.length) {
60
- const nextMatch = findNextMentionMatch(line, cursor);
61
- if (!nextMatch) {
62
- spans.push({ kind: "text", value: line.slice(cursor) });
63
- break;
64
- }
65
- if (nextMatch.index > cursor) {
66
- spans.push({ kind: "text", value: line.slice(cursor, nextMatch.index) });
67
- }
68
- spans.push(nextMatch.span);
69
- cursor = nextMatch.index + nextMatch.length;
59
+ const spans = [];
60
+ let cursor = 0;
61
+ while (cursor < line.length) {
62
+ const nextMatch = findNextMentionMatch(line, cursor);
63
+ if (!nextMatch) {
64
+ spans.push({ kind: "text", value: line.slice(cursor) });
65
+ break;
70
66
  }
71
- if (spans.length === 0) {
72
- spans.push({ kind: "text", value: line });
67
+ if (nextMatch.index > cursor) {
68
+ spans.push({ kind: "text", value: line.slice(cursor, nextMatch.index) });
73
69
  }
74
- return spans;
70
+ spans.push(nextMatch.span);
71
+ cursor = nextMatch.index + nextMatch.length;
72
+ }
73
+ if (spans.length === 0) {
74
+ spans.push({ kind: "text", value: line });
75
+ }
76
+ return spans;
75
77
  }
76
78
  function skillVisibleText(span) {
77
- return span.source === "at" ? `@${span.name}` : span.name;
79
+ return span.source === "at" ? `@${span.name}` : span.name;
78
80
  }
79
81
  function skillLogicalText(span) {
80
- return span.source === "at" ? `@skill ${span.name}` : `/skill:${span.name}`;
82
+ return span.source === "at" ? `@skill ${span.name}` : `/skill:${span.name}`;
81
83
  }
82
84
  function renderSpan(span, theme) {
83
- if (span.kind === "text")
84
- return span.value;
85
- if (span.kind === "skill") {
86
- const text = skillVisibleText(span);
87
- try {
88
- return theme.fg("accent", text);
89
- }
90
- catch {
91
- return theme.fg("text", text);
92
- }
93
- }
85
+ if (span.kind === "text") return span.value;
86
+ if (span.kind === "skill") {
87
+ const text = skillVisibleText(span);
94
88
  try {
95
- return theme.fg("planAccent", PLAN_VISIBLE_LABEL);
96
- }
97
- catch {
98
- return theme.fg("text", PLAN_VISIBLE_LABEL);
89
+ return theme.fg("accent", text);
90
+ } catch {
91
+ return theme.fg("text", text);
99
92
  }
93
+ }
94
+ try {
95
+ return theme.fg("planAccent", PLAN_VISIBLE_LABEL);
96
+ } catch {
97
+ return theme.fg("text", PLAN_VISIBLE_LABEL);
98
+ }
100
99
  }
101
100
  function spanLogicalWidth(span) {
102
- if (span.kind === "text")
103
- return span.value.length;
104
- if (span.kind === "skill")
105
- return skillLogicalText(span).length;
106
- return span.logicalToken.length;
101
+ if (span.kind === "text") return span.value.length;
102
+ if (span.kind === "skill") return skillLogicalText(span).length;
103
+ return span.logicalToken.length;
107
104
  }
108
105
  function spanVisibleText(span) {
109
- if (span.kind === "text")
110
- return span.value;
111
- if (span.kind === "skill")
112
- return skillVisibleText(span);
113
- return PLAN_VISIBLE_LABEL;
106
+ if (span.kind === "text") return span.value;
107
+ if (span.kind === "skill") return skillVisibleText(span);
108
+ return PLAN_VISIBLE_LABEL;
114
109
  }
115
110
  export function renderLineWithMentionChips(line, theme) {
116
- return parseMentionSpans(line)
117
- .map((span) => renderSpan(span, theme))
118
- .join("");
111
+ return parseMentionSpans(line)
112
+ .map((span) => renderSpan(span, theme))
113
+ .join("");
119
114
  }
120
115
  export function logicalToVisibleCol(line, logicalCol) {
121
- const clamped = Math.max(0, Math.min(logicalCol, line.length));
122
- let logical = 0;
123
- let visible = 0;
124
- for (const span of parseMentionSpans(line)) {
125
- const logicalLen = spanLogicalWidth(span);
126
- const visibleLen = visibleWidth(spanVisibleText(span));
127
- if (logical + logicalLen >= clamped) {
128
- const offset = clamped - logical;
129
- if (span.kind === "text") {
130
- return visible + offset;
131
- }
132
- const ratio = logicalLen > 0 ? offset / logicalLen : 0;
133
- return visible + Math.round(visibleLen * ratio);
134
- }
135
- logical += logicalLen;
136
- visible += visibleLen;
116
+ const clamped = Math.max(0, Math.min(logicalCol, line.length));
117
+ let logical = 0;
118
+ let visible = 0;
119
+ for (const span of parseMentionSpans(line)) {
120
+ const logicalLen = spanLogicalWidth(span);
121
+ const visibleLen = visibleWidth(spanVisibleText(span));
122
+ if (logical + logicalLen >= clamped) {
123
+ const offset = clamped - logical;
124
+ if (span.kind === "text") {
125
+ return visible + offset;
126
+ }
127
+ const ratio = logicalLen > 0 ? offset / logicalLen : 0;
128
+ return visible + Math.round(visibleLen * ratio);
137
129
  }
138
- return visible;
130
+ logical += logicalLen;
131
+ visible += visibleLen;
132
+ }
133
+ return visible;
139
134
  }
140
135
  export function visibleToLogicalCol(line, visibleCol) {
141
- const clamped = Math.max(0, visibleCol);
142
- let logical = 0;
143
- let visible = 0;
144
- for (const span of parseMentionSpans(line)) {
145
- const logicalLen = spanLogicalWidth(span);
146
- const visibleLen = visibleWidth(spanVisibleText(span));
147
- if (visible + visibleLen >= clamped) {
148
- const offset = clamped - visible;
149
- if (span.kind === "text") {
150
- return logical + offset;
151
- }
152
- const ratio = visibleLen > 0 ? offset / visibleLen : 0;
153
- return logical + Math.round(logicalLen * ratio);
154
- }
155
- logical += logicalLen;
156
- visible += visibleLen;
136
+ const clamped = Math.max(0, visibleCol);
137
+ let logical = 0;
138
+ let visible = 0;
139
+ for (const span of parseMentionSpans(line)) {
140
+ const logicalLen = spanLogicalWidth(span);
141
+ const visibleLen = visibleWidth(spanVisibleText(span));
142
+ if (visible + visibleLen >= clamped) {
143
+ const offset = clamped - visible;
144
+ if (span.kind === "text") {
145
+ return logical + offset;
146
+ }
147
+ const ratio = visibleLen > 0 ? offset / visibleLen : 0;
148
+ return logical + Math.round(logicalLen * ratio);
157
149
  }
158
- return line.length;
150
+ logical += logicalLen;
151
+ visible += visibleLen;
152
+ }
153
+ return line.length;
159
154
  }
160
- //# sourceMappingURL=chat-mention-render.js.map
155
+ //# sourceMappingURL=chat-mention-render.js.map
@@ -7,12 +7,15 @@ export declare function extractAtPrefix(textBeforeCursor: string): string | null
7
7
  /** KubbiSec: `@skill` may include a space and partial name (not only the last @ token). */
8
8
  export declare function extractSkillMentionPrefix(textBeforeCursor: string): string | null;
9
9
  export declare function parseSkillMentionPrefix(atPrefix: string | null): {
10
- query: string;
10
+ query: string;
11
11
  } | null;
12
12
  export declare function parsePlanMentionPrefix(atPrefix: string | null): {
13
- query: string;
13
+ query: string;
14
14
  } | null;
15
- export declare function filterSkillSuggestions(skills: KubbisecSkillEntry[], query: string): AutocompleteItem[];
15
+ export declare function filterSkillSuggestions(
16
+ skills: KubbisecSkillEntry[],
17
+ query: string,
18
+ ): AutocompleteItem[];
16
19
  /** Pi expands `/skill:name` — map `@skill name` before submit. */
17
20
  export declare function transformAtSkillMentions(text: string): string;
18
21
  /** Legacy: map `@plan` / `@planejar` to `/mode:plan` (prefer session state + visible @plan). */
@@ -20,9 +23,15 @@ export declare function transformAtPlanMentions(text: string): string;
20
23
  /** Apply @skill → /skill:name only. @plan stays visible; plan mode is set via session state. */
21
24
  export declare function transformChatMentions(text: string): string;
22
25
  export declare function messageActivatesPlanMode(text: string): boolean;
23
- export declare function applySkillMentionCompletion(lines: string[], cursorLine: number, cursorCol: number, item: AutocompleteItem, prefix: string): {
24
- lines: string[];
25
- cursorLine: number;
26
- cursorCol: number;
26
+ export declare function applySkillMentionCompletion(
27
+ lines: string[],
28
+ cursorLine: number,
29
+ cursorCol: number,
30
+ item: AutocompleteItem,
31
+ prefix: string,
32
+ ): {
33
+ lines: string[];
34
+ cursorLine: number;
35
+ cursorCol: number;
27
36
  };
28
- //# sourceMappingURL=chat-mentions.d.ts.map
37
+ //# sourceMappingURL=chat-mentions.d.ts.map
@@ -1,108 +1,108 @@
1
1
  import { fuzzyFilter } from "@earendil-works/pi-tui";
2
2
  export const SKILL_MENTION_TOKEN = "@skill";
3
3
  export const PLAN_MENTION_ALIASES = ["@plan", "@planejar"];
4
- const PLAN_MENTION_TOKENS_LONGEST_FIRST = [...PLAN_MENTION_ALIASES].sort((a, b) => b.length - a.length);
4
+ const PLAN_MENTION_TOKENS_LONGEST_FIRST = [...PLAN_MENTION_ALIASES].sort(
5
+ (a, b) => b.length - a.length,
6
+ );
5
7
  const PATH_DELIMITERS = new Set([" ", "\t", '"', "'", "="]);
6
8
  function findLastDelimiter(text) {
7
- for (let i = text.length - 1; i >= 0; i -= 1) {
8
- if (PATH_DELIMITERS.has(text[i] ?? "")) {
9
- return i;
10
- }
9
+ for (let i = text.length - 1; i >= 0; i -= 1) {
10
+ if (PATH_DELIMITERS.has(text[i] ?? "")) {
11
+ return i;
11
12
  }
12
- return -1;
13
+ }
14
+ return -1;
13
15
  }
14
16
  /** Same token rules as Pi CombinedAutocompleteProvider.extractAtPrefix. */
15
17
  export function extractAtPrefix(textBeforeCursor) {
16
- const lastDelimiterIndex = findLastDelimiter(textBeforeCursor);
17
- const tokenStart = lastDelimiterIndex === -1 ? 0 : lastDelimiterIndex + 1;
18
- if (textBeforeCursor[tokenStart] === "@") {
19
- return textBeforeCursor.slice(tokenStart);
20
- }
21
- return null;
18
+ const lastDelimiterIndex = findLastDelimiter(textBeforeCursor);
19
+ const tokenStart = lastDelimiterIndex === -1 ? 0 : lastDelimiterIndex + 1;
20
+ if (textBeforeCursor[tokenStart] === "@") {
21
+ return textBeforeCursor.slice(tokenStart);
22
+ }
23
+ return null;
22
24
  }
23
25
  /** KubbiSec: `@skill` may include a space and partial name (not only the last @ token). */
24
26
  export function extractSkillMentionPrefix(textBeforeCursor) {
25
- const idx = textBeforeCursor.lastIndexOf(SKILL_MENTION_TOKEN);
26
- if (idx === -1)
27
- return null;
28
- if (idx > 0 && !PATH_DELIMITERS.has(textBeforeCursor[idx - 1] ?? "")) {
29
- return null;
30
- }
31
- const slice = textBeforeCursor.slice(idx);
32
- if (!parseSkillMentionPrefix(slice))
33
- return null;
34
- return slice;
27
+ const idx = textBeforeCursor.lastIndexOf(SKILL_MENTION_TOKEN);
28
+ if (idx === -1) return null;
29
+ if (idx > 0 && !PATH_DELIMITERS.has(textBeforeCursor[idx - 1] ?? "")) {
30
+ return null;
31
+ }
32
+ const slice = textBeforeCursor.slice(idx);
33
+ if (!parseSkillMentionPrefix(slice)) return null;
34
+ return slice;
35
35
  }
36
36
  export function parseSkillMentionPrefix(atPrefix) {
37
- if (!atPrefix?.startsWith(SKILL_MENTION_TOKEN))
38
- return null;
39
- const tail = atPrefix.slice(SKILL_MENTION_TOKEN.length);
40
- if (tail.length > 0 && !tail.startsWith(" "))
41
- return null;
42
- return { query: tail.startsWith(" ") ? tail.trimStart() : "" };
37
+ if (!atPrefix?.startsWith(SKILL_MENTION_TOKEN)) return null;
38
+ const tail = atPrefix.slice(SKILL_MENTION_TOKEN.length);
39
+ if (tail.length > 0 && !tail.startsWith(" ")) return null;
40
+ return { query: tail.startsWith(" ") ? tail.trimStart() : "" };
43
41
  }
44
42
  export function parsePlanMentionPrefix(atPrefix) {
45
- if (!atPrefix)
46
- return null;
47
- for (const token of PLAN_MENTION_TOKENS_LONGEST_FIRST) {
48
- if (!atPrefix.startsWith(token))
49
- continue;
50
- const tail = atPrefix.slice(token.length);
51
- if (tail.length > 0 && !tail.startsWith(" "))
52
- continue;
53
- return { query: tail.startsWith(" ") ? tail.trimStart() : "" };
54
- }
55
- return null;
43
+ if (!atPrefix) return null;
44
+ for (const token of PLAN_MENTION_TOKENS_LONGEST_FIRST) {
45
+ if (!atPrefix.startsWith(token)) continue;
46
+ const tail = atPrefix.slice(token.length);
47
+ if (tail.length > 0 && !tail.startsWith(" ")) continue;
48
+ return { query: tail.startsWith(" ") ? tail.trimStart() : "" };
49
+ }
50
+ return null;
56
51
  }
57
52
  export function filterSkillSuggestions(skills, query) {
58
- const items = skills.map((skill) => ({
59
- value: skill.name,
60
- label: skill.name,
61
- description: skill.description,
62
- }));
63
- if (!query)
64
- return items;
65
- return fuzzyFilter(items, query, (item) => `${item.label} ${item.description ?? ""}`).map((item) => ({
66
- value: item.value,
67
- label: item.label,
68
- description: item.description,
69
- }));
53
+ const items = skills.map((skill) => ({
54
+ value: skill.name,
55
+ label: skill.name,
56
+ description: skill.description,
57
+ }));
58
+ if (!query) return items;
59
+ return fuzzyFilter(items, query, (item) => `${item.label} ${item.description ?? ""}`).map(
60
+ (item) => ({
61
+ value: item.value,
62
+ label: item.label,
63
+ description: item.description,
64
+ }),
65
+ );
70
66
  }
71
67
  /** Pi expands `/skill:name` — map `@skill name` before submit. */
72
68
  export function transformAtSkillMentions(text) {
73
- return text.replace(/@skill\s+([^\s@/]+)/g, "/skill:$1");
69
+ return text.replace(/@skill\s+([^\s@/]+)/g, "/skill:$1");
74
70
  }
75
71
  /** Legacy: map `@plan` / `@planejar` to `/mode:plan` (prefer session state + visible @plan). */
76
72
  export function transformAtPlanMentions(text) {
77
- const tokenPattern = PLAN_MENTION_TOKENS_LONGEST_FIRST.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
78
- const pattern = new RegExp(`(^|[\\s"'=])(${tokenPattern})(\\s[\\s\\S]*)?`, "g");
79
- return text.replace(pattern, (_match, delim, _token, tail) => {
80
- const query = tail ? tail.trimStart() : "";
81
- return `${delim}/mode:plan${query ? ` ${query}` : ""}`;
82
- });
73
+ const tokenPattern = PLAN_MENTION_TOKENS_LONGEST_FIRST.map((t) =>
74
+ t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
75
+ ).join("|");
76
+ const pattern = new RegExp(`(^|[\\s"'=])(${tokenPattern})(\\s[\\s\\S]*)?`, "g");
77
+ return text.replace(pattern, (_match, delim, _token, tail) => {
78
+ const query = tail ? tail.trimStart() : "";
79
+ return `${delim}/mode:plan${query ? ` ${query}` : ""}`;
80
+ });
83
81
  }
84
82
  /** Apply @skill → /skill:name only. @plan stays visible; plan mode is set via session state. */
85
83
  export function transformChatMentions(text) {
86
- return transformAtSkillMentions(text);
84
+ return transformAtSkillMentions(text);
87
85
  }
88
86
  export function messageActivatesPlanMode(text) {
89
- const trimmed = text.trim();
90
- return (trimmed.startsWith("/mode:plan") || /^@plan\b/i.test(trimmed) || /^@planejar\b/i.test(trimmed));
87
+ const trimmed = text.trim();
88
+ return (
89
+ trimmed.startsWith("/mode:plan") || /^@plan\b/i.test(trimmed) || /^@planejar\b/i.test(trimmed)
90
+ );
91
91
  }
92
92
  export function applySkillMentionCompletion(lines, cursorLine, cursorCol, item, prefix) {
93
- const currentLine = lines[cursorLine] ?? "";
94
- const beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
95
- const afterCursor = currentLine.slice(cursorCol);
96
- const atIndex = beforePrefix.lastIndexOf(SKILL_MENTION_TOKEN);
97
- const head = atIndex >= 0 ? beforePrefix.slice(0, atIndex) : beforePrefix;
98
- const insertion = `${SKILL_MENTION_TOKEN} ${item.value} `;
99
- const newLine = `${head}${insertion}${afterCursor}`;
100
- const newLines = [...lines];
101
- newLines[cursorLine] = newLine;
102
- return {
103
- lines: newLines,
104
- cursorLine,
105
- cursorCol: head.length + insertion.length,
106
- };
93
+ const currentLine = lines[cursorLine] ?? "";
94
+ const beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
95
+ const afterCursor = currentLine.slice(cursorCol);
96
+ const atIndex = beforePrefix.lastIndexOf(SKILL_MENTION_TOKEN);
97
+ const head = atIndex >= 0 ? beforePrefix.slice(0, atIndex) : beforePrefix;
98
+ const insertion = `${SKILL_MENTION_TOKEN} ${item.value} `;
99
+ const newLine = `${head}${insertion}${afterCursor}`;
100
+ const newLines = [...lines];
101
+ newLines[cursorLine] = newLine;
102
+ return {
103
+ lines: newLines,
104
+ cursorLine,
105
+ cursorCol: head.length + insertion.length,
106
+ };
107
107
  }
108
- //# sourceMappingURL=chat-mentions.js.map
108
+ //# sourceMappingURL=chat-mentions.js.map
@@ -1,7 +1,7 @@
1
1
  export type KubbisecSkillEntry = {
2
- name: string;
3
- description: string;
2
+ name: string;
3
+ description: string;
4
4
  };
5
5
  /** Skills shipped under dist/skills (same dirs passed as Pi --skill). */
6
6
  export declare function listBundledKubbisecSkills(): KubbisecSkillEntry[];
7
- //# sourceMappingURL=list-bundled-skills.d.ts.map
7
+ //# sourceMappingURL=list-bundled-skills.d.ts.map
@@ -1,44 +1,42 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import { resolveBundledDistRoot, resolveSnapshotBundledDistDir, } from "../resolve-bundled-dist-root.js";
3
+ import {
4
+ resolveBundledDistRoot,
5
+ resolveSnapshotBundledDistDir,
6
+ } from "../resolve-bundled-dist-root.js";
7
+
4
8
  function parseSkillFrontmatter(raw) {
5
- const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
6
- if (!match)
7
- return {};
8
- const block = match[1];
9
- const name = block.match(/^name:\s*(.+)$/m)?.[1]?.trim();
10
- const description = block.match(/^description:\s*(.+)$/m)?.[1]?.trim();
11
- return { name, description };
9
+ const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
10
+ if (!match) return {};
11
+ const block = match[1];
12
+ const name = block.match(/^name:\s*(.+)$/m)?.[1]?.trim();
13
+ const description = block.match(/^description:\s*(.+)$/m)?.[1]?.trim();
14
+ return { name, description };
12
15
  }
13
16
  function resolveSkillsDir() {
14
- const distDir = path.join(resolveBundledDistRoot(), "skills");
15
- if (fs.existsSync(distDir))
16
- return distDir;
17
- const entryDir = path.dirname(resolveSnapshotBundledDistDir());
18
- const srcDir = path.join(entryDir, "src/skills");
19
- if (fs.existsSync(srcDir))
20
- return srcDir;
21
- return null;
17
+ const distDir = path.join(resolveBundledDistRoot(), "skills");
18
+ if (fs.existsSync(distDir)) return distDir;
19
+ const entryDir = path.dirname(resolveSnapshotBundledDistDir());
20
+ const srcDir = path.join(entryDir, "src/skills");
21
+ if (fs.existsSync(srcDir)) return srcDir;
22
+ return null;
22
23
  }
23
24
  /** Skills shipped under dist/skills (same dirs passed as Pi --skill). */
24
25
  export function listBundledKubbisecSkills() {
25
- const skillsDir = resolveSkillsDir();
26
- if (!skillsDir)
27
- return [];
28
- const entries = [];
29
- for (const dir of fs.readdirSync(skillsDir, { withFileTypes: true })) {
30
- if (!dir.isDirectory())
31
- continue;
32
- const skillMd = path.join(skillsDir, dir.name, "SKILL.md");
33
- if (!fs.existsSync(skillMd))
34
- continue;
35
- const raw = fs.readFileSync(skillMd, "utf8");
36
- const meta = parseSkillFrontmatter(raw);
37
- entries.push({
38
- name: meta.name?.trim() || dir.name,
39
- description: meta.description?.trim() || dir.name,
40
- });
41
- }
42
- return entries.sort((a, b) => a.name.localeCompare(b.name));
26
+ const skillsDir = resolveSkillsDir();
27
+ if (!skillsDir) return [];
28
+ const entries = [];
29
+ for (const dir of fs.readdirSync(skillsDir, { withFileTypes: true })) {
30
+ if (!dir.isDirectory()) continue;
31
+ const skillMd = path.join(skillsDir, dir.name, "SKILL.md");
32
+ if (!fs.existsSync(skillMd)) continue;
33
+ const raw = fs.readFileSync(skillMd, "utf8");
34
+ const meta = parseSkillFrontmatter(raw);
35
+ entries.push({
36
+ name: meta.name?.trim() || dir.name,
37
+ description: meta.description?.trim() || dir.name,
38
+ });
39
+ }
40
+ return entries.sort((a, b) => a.name.localeCompare(b.name));
43
41
  }
44
- //# sourceMappingURL=list-bundled-skills.js.map
42
+ //# sourceMappingURL=list-bundled-skills.js.map
@@ -1,3 +1,11 @@
1
1
  /** @deprecated Import from chat-mentions.js — re-export shim for backward compatibility. */
2
- export { applySkillMentionCompletion, extractAtPrefix, extractSkillMentionPrefix, filterSkillSuggestions, parseSkillMentionPrefix, SKILL_MENTION_TOKEN, transformAtSkillMentions, } from "./chat-mentions.js";
3
- //# sourceMappingURL=skill-mention.d.ts.map
2
+ export {
3
+ applySkillMentionCompletion,
4
+ extractAtPrefix,
5
+ extractSkillMentionPrefix,
6
+ filterSkillSuggestions,
7
+ parseSkillMentionPrefix,
8
+ SKILL_MENTION_TOKEN,
9
+ transformAtSkillMentions,
10
+ } from "./chat-mentions.js";
11
+ //# sourceMappingURL=skill-mention.d.ts.map
@@ -1,3 +1,11 @@
1
1
  /** @deprecated Import from chat-mentions.js — re-export shim for backward compatibility. */
2
- export { applySkillMentionCompletion, extractAtPrefix, extractSkillMentionPrefix, filterSkillSuggestions, parseSkillMentionPrefix, SKILL_MENTION_TOKEN, transformAtSkillMentions, } from "./chat-mentions.js";
3
- //# sourceMappingURL=skill-mention.js.map
2
+ export {
3
+ applySkillMentionCompletion,
4
+ extractAtPrefix,
5
+ extractSkillMentionPrefix,
6
+ filterSkillSuggestions,
7
+ parseSkillMentionPrefix,
8
+ SKILL_MENTION_TOKEN,
9
+ transformAtSkillMentions,
10
+ } from "./chat-mentions.js";
11
+ //# sourceMappingURL=skill-mention.js.map
@@ -1,3 +1,3 @@
1
1
  /** Clear visible screen and scrollback when stdout is a TTY (chat TUI takeover). */
2
2
  export declare function clearTerminal(): void;
3
- //# sourceMappingURL=clear-terminal.d.ts.map
3
+ //# sourceMappingURL=clear-terminal.d.ts.map
@@ -1,7 +1,6 @@
1
1
  /** Clear visible screen and scrollback when stdout is a TTY (chat TUI takeover). */
2
2
  export function clearTerminal() {
3
- if (!process.stdout.isTTY)
4
- return;
5
- process.stdout.write("\x1b[2J\x1b[3J\x1b[H");
3
+ if (!process.stdout.isTTY) return;
4
+ process.stdout.write("\x1b[2J\x1b[3J\x1b[H");
6
5
  }
7
- //# sourceMappingURL=clear-terminal.js.map
6
+ //# sourceMappingURL=clear-terminal.js.map