@kubbisec/ai-linux-arm64 0.1.8 → 0.1.9

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 (183) hide show
  1. package/bin/kubbisec +0 -0
  2. package/bundled/assets/terminal/wordmark-inline.ansi +1 -0
  3. package/bundled/assets/terminal/wordmark.ansi +4 -0
  4. package/bundled/assets/terminal/wordmark.png +0 -0
  5. package/bundled/clarify/clarify-gate-state.d.ts +3 -0
  6. package/bundled/clarify/clarify-gate-state.d.ts.map +1 -0
  7. package/bundled/clarify/clarify-gate-state.js +9 -0
  8. package/bundled/clarify/clarify-gate-state.js.map +1 -0
  9. package/bundled/clarify/clarify-gate.d.ts +2 -1
  10. package/bundled/clarify/clarify-gate.d.ts.map +1 -1
  11. package/bundled/clarify/clarify-gate.js +17 -4
  12. package/bundled/clarify/clarify-gate.js.map +1 -1
  13. package/bundled/clarify/clarify-select-panel.d.ts +14 -0
  14. package/bundled/clarify/clarify-select-panel.d.ts.map +1 -0
  15. package/bundled/clarify/clarify-select-panel.js +82 -0
  16. package/bundled/clarify/clarify-select-panel.js.map +1 -0
  17. package/bundled/clarify/clarify-ui-state.d.ts +10 -1
  18. package/bundled/clarify/clarify-ui-state.d.ts.map +1 -1
  19. package/bundled/clarify/clarify-ui-state.js +24 -3
  20. package/bundled/clarify/clarify-ui-state.js.map +1 -1
  21. package/bundled/clarify/parse-clarify-answer.d.ts +6 -1
  22. package/bundled/clarify/parse-clarify-answer.d.ts.map +1 -1
  23. package/bundled/clarify/parse-clarify-answer.js +35 -2
  24. package/bundled/clarify/parse-clarify-answer.js.map +1 -1
  25. package/bundled/clarify/question-format.d.ts +7 -4
  26. package/bundled/clarify/question-format.d.ts.map +1 -1
  27. package/bundled/clarify/question-format.js +26 -33
  28. package/bundled/clarify/question-format.js.map +1 -1
  29. package/bundled/clarify/questionnaire-tool.d.ts.map +1 -1
  30. package/bundled/clarify/questionnaire-tool.js +16 -9
  31. package/bundled/clarify/questionnaire-tool.js.map +1 -1
  32. package/bundled/clarify/scope-discovery.d.ts +10 -0
  33. package/bundled/clarify/scope-discovery.d.ts.map +1 -0
  34. package/bundled/clarify/scope-discovery.js +130 -0
  35. package/bundled/clarify/scope-discovery.js.map +1 -0
  36. package/bundled/clarify/session-questionnaire.d.ts +4 -1
  37. package/bundled/clarify/session-questionnaire.d.ts.map +1 -1
  38. package/bundled/clarify/session-questionnaire.js +59 -4
  39. package/bundled/clarify/session-questionnaire.js.map +1 -1
  40. package/bundled/clarify/session-questionnaire.types.d.ts +2 -0
  41. package/bundled/clarify/session-questionnaire.types.d.ts.map +1 -1
  42. package/bundled/clarify/session-questionnaire.types.js.map +1 -1
  43. package/bundled/config/detect-local-llm-providers.d.ts +33 -0
  44. package/bundled/config/detect-local-llm-providers.d.ts.map +1 -0
  45. package/bundled/config/detect-local-llm-providers.js +173 -0
  46. package/bundled/config/detect-local-llm-providers.js.map +1 -0
  47. package/bundled/config/ensure-kubbisec-project-settings.d.ts +8 -0
  48. package/bundled/config/ensure-kubbisec-project-settings.d.ts.map +1 -1
  49. package/bundled/config/ensure-kubbisec-project-settings.js +31 -0
  50. package/bundled/config/ensure-kubbisec-project-settings.js.map +1 -1
  51. package/bundled/config/extended-context.d.ts +12 -0
  52. package/bundled/config/extended-context.d.ts.map +1 -0
  53. package/bundled/config/extended-context.js +37 -0
  54. package/bundled/config/extended-context.js.map +1 -0
  55. package/bundled/config/format-kubbisec-footer-status.d.ts.map +1 -1
  56. package/bundled/config/format-kubbisec-footer-status.js +10 -1
  57. package/bundled/config/format-kubbisec-footer-status.js.map +1 -1
  58. package/bundled/config/llm-config-mutations.d.ts +38 -0
  59. package/bundled/config/llm-config-mutations.d.ts.map +1 -0
  60. package/bundled/config/llm-config-mutations.js +207 -0
  61. package/bundled/config/llm-config-mutations.js.map +1 -0
  62. package/bundled/config/llm-config.d.ts +61 -0
  63. package/bundled/config/llm-config.d.ts.map +1 -0
  64. package/bundled/config/llm-config.js +225 -0
  65. package/bundled/config/llm-config.js.map +1 -0
  66. package/bundled/config/llm-provider-catalog.d.ts +22 -0
  67. package/bundled/config/llm-provider-catalog.d.ts.map +1 -0
  68. package/bundled/config/llm-provider-catalog.js +42 -0
  69. package/bundled/config/llm-provider-catalog.js.map +1 -0
  70. package/bundled/config/materialize-kubbisec-pi-resources.d.ts +13 -0
  71. package/bundled/config/materialize-kubbisec-pi-resources.d.ts.map +1 -0
  72. package/bundled/config/materialize-kubbisec-pi-resources.js +142 -0
  73. package/bundled/config/materialize-kubbisec-pi-resources.js.map +1 -0
  74. package/bundled/config/register-custom-llm-providers.d.ts +13 -0
  75. package/bundled/config/register-custom-llm-providers.d.ts.map +1 -0
  76. package/bundled/config/register-custom-llm-providers.js +21 -0
  77. package/bundled/config/register-custom-llm-providers.js.map +1 -0
  78. package/bundled/config/register-kubbisec-llm-provider.d.ts +12 -0
  79. package/bundled/config/register-kubbisec-llm-provider.d.ts.map +1 -0
  80. package/bundled/config/register-kubbisec-llm-provider.js +47 -0
  81. package/bundled/config/register-kubbisec-llm-provider.js.map +1 -0
  82. package/bundled/copy/cli-reference-index.d.ts +6 -0
  83. package/bundled/copy/cli-reference-index.d.ts.map +1 -0
  84. package/bundled/copy/cli-reference-index.js +42 -0
  85. package/bundled/copy/cli-reference-index.js.map +1 -0
  86. package/bundled/copy/kubbisec-shell-copy.d.ts +15 -2
  87. package/bundled/copy/kubbisec-shell-copy.d.ts.map +1 -1
  88. package/bundled/copy/kubbisec-shell-copy.js +15 -2
  89. package/bundled/copy/kubbisec-shell-copy.js.map +1 -1
  90. package/bundled/extensions/cli-local-shared.d.ts +31 -11
  91. package/bundled/extensions/cli-local-shared.d.ts.map +1 -1
  92. package/bundled/extensions/cli-local-shared.js +56 -10
  93. package/bundled/extensions/cli-local-shared.js.map +1 -1
  94. package/bundled/extensions/kubbisec-aspm-local.extension.d.ts +1 -0
  95. package/bundled/extensions/kubbisec-aspm-local.extension.d.ts.map +1 -1
  96. package/bundled/extensions/kubbisec-aspm-local.extension.js +32 -44
  97. package/bundled/extensions/kubbisec-aspm-local.extension.js.map +1 -1
  98. package/bundled/extensions/kubbisec-brand.extension.d.ts.map +1 -1
  99. package/bundled/extensions/kubbisec-brand.extension.js +7 -59
  100. package/bundled/extensions/kubbisec-brand.extension.js.map +1 -1
  101. package/bundled/extensions/kubbisec-byok-provider.extension.d.ts +3 -27
  102. package/bundled/extensions/kubbisec-byok-provider.extension.d.ts.map +1 -1
  103. package/bundled/extensions/kubbisec-byok-provider.extension.js +2 -48
  104. package/bundled/extensions/kubbisec-byok-provider.extension.js.map +1 -1
  105. package/bundled/extensions/kubbisec-clarify.extension.d.ts +6 -1
  106. package/bundled/extensions/kubbisec-clarify.extension.d.ts.map +1 -1
  107. package/bundled/extensions/kubbisec-clarify.extension.js +124 -68
  108. package/bundled/extensions/kubbisec-clarify.extension.js.map +1 -1
  109. package/bundled/extensions/kubbisec-exit.extension.d.ts +3 -0
  110. package/bundled/extensions/kubbisec-exit.extension.d.ts.map +1 -0
  111. package/bundled/extensions/kubbisec-exit.extension.js +38 -0
  112. package/bundled/extensions/kubbisec-exit.extension.js.map +1 -0
  113. package/bundled/extensions/kubbisec-extended-context.extension.d.ts +6 -0
  114. package/bundled/extensions/kubbisec-extended-context.extension.d.ts.map +1 -0
  115. package/bundled/extensions/kubbisec-extended-context.extension.js +50 -0
  116. package/bundled/extensions/kubbisec-extended-context.extension.js.map +1 -0
  117. package/bundled/extensions/kubbisec-footer.extension.d.ts +21 -0
  118. package/bundled/extensions/kubbisec-footer.extension.d.ts.map +1 -1
  119. package/bundled/extensions/kubbisec-footer.extension.js +121 -66
  120. package/bundled/extensions/kubbisec-footer.extension.js.map +1 -1
  121. package/bundled/extensions/kubbisec-github-local.extension.d.ts.map +1 -1
  122. package/bundled/extensions/kubbisec-github-local.extension.js +52 -22
  123. package/bundled/extensions/kubbisec-github-local.extension.js.map +1 -1
  124. package/bundled/extensions/kubbisec-llm-config.extension.d.ts +3 -0
  125. package/bundled/extensions/kubbisec-llm-config.extension.d.ts.map +1 -0
  126. package/bundled/extensions/kubbisec-llm-config.extension.js +207 -0
  127. package/bundled/extensions/kubbisec-llm-config.extension.js.map +1 -0
  128. package/bundled/extensions/kubbisec-naus-local.extension.d.ts +1 -0
  129. package/bundled/extensions/kubbisec-naus-local.extension.d.ts.map +1 -1
  130. package/bundled/extensions/kubbisec-naus-local.extension.js +54 -58
  131. package/bundled/extensions/kubbisec-naus-local.extension.js.map +1 -1
  132. package/bundled/extensions/kubbisec-platform-tools.extension.d.ts.map +1 -1
  133. package/bundled/extensions/kubbisec-platform-tools.extension.js +57 -16
  134. package/bundled/extensions/kubbisec-platform-tools.extension.js.map +1 -1
  135. package/bundled/extensions/kubbisec-skill-mentions.extension.d.ts +1 -0
  136. package/bundled/extensions/kubbisec-skill-mentions.extension.d.ts.map +1 -1
  137. package/bundled/extensions/kubbisec-skill-mentions.extension.js +24 -8
  138. package/bundled/extensions/kubbisec-skill-mentions.extension.js.map +1 -1
  139. package/bundled/extensions/kubbisec-theme-lock.extension.d.ts +6 -0
  140. package/bundled/extensions/kubbisec-theme-lock.extension.d.ts.map +1 -0
  141. package/bundled/extensions/kubbisec-theme-lock.extension.js +40 -0
  142. package/bundled/extensions/kubbisec-theme-lock.extension.js.map +1 -0
  143. package/bundled/extensions/kubbisec-ui.extension.d.ts +1 -1
  144. package/bundled/extensions/kubbisec-ui.extension.d.ts.map +1 -1
  145. package/bundled/extensions/kubbisec-ui.extension.js +97 -82
  146. package/bundled/extensions/kubbisec-ui.extension.js.map +1 -1
  147. package/bundled/extensions/kubbisec-workflow.extension.d.ts.map +1 -1
  148. package/bundled/extensions/kubbisec-workflow.extension.js +31 -21
  149. package/bundled/extensions/kubbisec-workflow.extension.js.map +1 -1
  150. package/bundled/skills/aspm-platform/SKILL.md +55 -25
  151. package/bundled/skills/at-path-mentions.d.ts +7 -0
  152. package/bundled/skills/at-path-mentions.d.ts.map +1 -0
  153. package/bundled/skills/at-path-mentions.js +186 -0
  154. package/bundled/skills/at-path-mentions.js.map +1 -0
  155. package/bundled/skills/at-path-mentions.test.ts +64 -0
  156. package/bundled/skills/at-path-mentions.ts +211 -0
  157. package/bundled/skills/chat-mention-render.d.ts.map +1 -1
  158. package/bundled/skills/chat-mention-render.js +69 -31
  159. package/bundled/skills/chat-mention-render.js.map +1 -1
  160. package/bundled/skills/chat-mention-render.test.ts +24 -1
  161. package/bundled/skills/chat-mention-render.ts +87 -34
  162. package/bundled/skills/chat-mentions.d.ts +3 -2
  163. package/bundled/skills/chat-mentions.d.ts.map +1 -1
  164. package/bundled/skills/chat-mentions.js +9 -3
  165. package/bundled/skills/chat-mentions.js.map +1 -1
  166. package/bundled/skills/chat-mentions.test.ts +12 -5
  167. package/bundled/skills/chat-mentions.ts +12 -3
  168. package/bundled/skills/naus-pipelines/SKILL.md +111 -16
  169. package/bundled/skills/sec-clarify/SKILL.md +8 -23
  170. package/bundled/skills/sec-using-skills/SKILL.md +2 -0
  171. package/bundled/theme/clear-terminal.d.ts +3 -0
  172. package/bundled/theme/clear-terminal.d.ts.map +1 -0
  173. package/bundled/theme/clear-terminal.js +7 -0
  174. package/bundled/theme/clear-terminal.js.map +1 -0
  175. package/bundled/theme/kubbisec-theme-name.d.ts +2 -0
  176. package/bundled/theme/kubbisec-theme-name.d.ts.map +1 -0
  177. package/bundled/theme/kubbisec-theme-name.js +2 -0
  178. package/bundled/theme/kubbisec-theme-name.js.map +1 -0
  179. package/bundled/theme/render-compact-header.d.ts +16 -0
  180. package/bundled/theme/render-compact-header.d.ts.map +1 -0
  181. package/bundled/theme/render-compact-header.js +132 -0
  182. package/bundled/theme/render-compact-header.js.map +1 -0
  183. package/package.json +1 -1
@@ -1,32 +1,63 @@
1
1
  import { visibleWidth } from "@earendil-works/pi-tui";
2
- const SKILL_TOKEN_RE = /\/skill:([a-z0-9_-]+)/gi;
2
+ import { PLAN_MENTION_ALIASES } from "./chat-mentions.js";
3
+ const SKILL_SLASH_RE = /\/skill:([a-z0-9_-]+)/gi;
4
+ const AT_SKILL_RE = /@skill\s+([^\s@/]+)/gi;
3
5
  const PLAN_TOKEN_RE = /\/mode:plan\b/gi;
6
+ const AT_PLAN_PATTERN = PLAN_MENTION_ALIASES.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
7
+ .sort((a, b) => b.length - a.length)
8
+ .join("|");
9
+ const AT_PLAN_RE = new RegExp(`(?:^|[\\s"'=])(${AT_PLAN_PATTERN})(?=\\s|$)`, "gi");
10
+ const PLAN_VISIBLE_LABEL = "@plan";
11
+ 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);
55
+ }
4
56
  function parseMentionSpans(line) {
5
57
  const spans = [];
6
58
  let cursor = 0;
7
59
  while (cursor < line.length) {
8
- SKILL_TOKEN_RE.lastIndex = cursor;
9
- PLAN_TOKEN_RE.lastIndex = cursor;
10
- const skillMatch = SKILL_TOKEN_RE.exec(line);
11
- const planMatch = PLAN_TOKEN_RE.exec(line);
12
- let nextMatch = null;
13
- if (skillMatch?.index !== undefined) {
14
- nextMatch = {
15
- index: skillMatch.index,
16
- length: skillMatch[0].length,
17
- span: { kind: "skill", name: skillMatch[1] ?? "" },
18
- };
19
- }
20
- if (planMatch?.index !== undefined) {
21
- const candidate = {
22
- index: planMatch.index,
23
- length: planMatch[0].length,
24
- span: { kind: "plan" },
25
- };
26
- if (!nextMatch || candidate.index < nextMatch.index) {
27
- nextMatch = candidate;
28
- }
29
- }
60
+ const nextMatch = findNextMentionMatch(line, cursor);
30
61
  if (!nextMatch) {
31
62
  spans.push({ kind: "text", value: line.slice(cursor) });
32
63
  break;
@@ -42,37 +73,44 @@ function parseMentionSpans(line) {
42
73
  }
43
74
  return spans;
44
75
  }
76
+ function skillVisibleText(span) {
77
+ return span.source === "at" ? `@${span.name}` : span.name;
78
+ }
79
+ function skillLogicalText(span) {
80
+ return span.source === "at" ? `@skill ${span.name}` : `/skill:${span.name}`;
81
+ }
45
82
  function renderSpan(span, theme) {
46
83
  if (span.kind === "text")
47
84
  return span.value;
48
85
  if (span.kind === "skill") {
86
+ const text = skillVisibleText(span);
49
87
  try {
50
- return theme.fg("accent", span.name);
88
+ return theme.fg("accent", text);
51
89
  }
52
90
  catch {
53
- return theme.fg("text", span.name);
91
+ return theme.fg("text", text);
54
92
  }
55
93
  }
56
94
  try {
57
- return theme.fg("planAccent", "plan");
95
+ return theme.fg("planAccent", PLAN_VISIBLE_LABEL);
58
96
  }
59
97
  catch {
60
- return theme.fg("text", "plan");
98
+ return theme.fg("text", PLAN_VISIBLE_LABEL);
61
99
  }
62
100
  }
63
101
  function spanLogicalWidth(span) {
64
102
  if (span.kind === "text")
65
103
  return span.value.length;
66
104
  if (span.kind === "skill")
67
- return `/skill:${span.name}`.length;
68
- return "/mode:plan".length;
105
+ return skillLogicalText(span).length;
106
+ return span.logicalToken.length;
69
107
  }
70
108
  function spanVisibleText(span) {
71
109
  if (span.kind === "text")
72
110
  return span.value;
73
111
  if (span.kind === "skill")
74
- return span.name;
75
- return "plan";
112
+ return skillVisibleText(span);
113
+ return PLAN_VISIBLE_LABEL;
76
114
  }
77
115
  export function renderLineWithMentionChips(line, theme) {
78
116
  return parseMentionSpans(line)
@@ -1 +1 @@
1
- {"version":3,"file":"chat-mention-render.js","sourceRoot":"","sources":["../../src/skills/chat-mention-render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-mention-render.js","sourceRoot":"","sources":["../../src/skills/chat-mention-render.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,16 @@ describe("chat-mention-render", () => {
21
21
  it("renders plan chip with planAccent token", () => {
22
22
  const theme = mockTheme();
23
23
  renderLineWithMentionChips("/mode:plan scope", theme);
24
- expect(theme.fg).toHaveBeenCalledWith("planAccent", "plan");
24
+ expect(theme.fg).toHaveBeenCalledWith("planAccent", "@plan");
25
+ });
26
+
27
+ it("renders @plan and @planejar as @plan chip", () => {
28
+ const theme = mockTheme();
29
+ renderLineWithMentionChips("@plan scope", theme);
30
+ expect(theme.fg).toHaveBeenCalledWith("planAccent", "@plan");
31
+ theme.fg.mockClear();
32
+ renderLineWithMentionChips("@planejar scope", theme);
33
+ expect(theme.fg).toHaveBeenCalledWith("planAccent", "@plan");
25
34
  });
26
35
 
27
36
  it("leaves lines without tokens unchanged", () => {
@@ -44,4 +53,18 @@ describe("chat-mention-render", () => {
44
53
  expect(theme.fg).toHaveBeenCalledWith("accent", "a");
45
54
  expect(theme.fg).toHaveBeenCalledWith("accent", "b");
46
55
  });
56
+
57
+ it("renders @skill name as @name accent chip in the editor", () => {
58
+ const theme = mockTheme();
59
+ renderLineWithMentionChips("@skill aspm-platform validate", theme);
60
+ expect(theme.fg).toHaveBeenCalledWith("accent", "@aspm-platform");
61
+ });
62
+
63
+ it("maps logical cursor columns for @skill mentions", () => {
64
+ const line = "@skill aspm-platform apply fix";
65
+ const afterMention = logicalToVisibleCol(line, "@skill aspm-platform".length);
66
+ expect(afterMention).toBe("@aspm-platform".length);
67
+ const roundTrip = visibleToLogicalCol(line, afterMention);
68
+ expect(roundTrip).toBe("@skill aspm-platform".length);
69
+ });
47
70
  });
@@ -1,4 +1,5 @@
1
1
  import { visibleWidth } from "@earendil-works/pi-tui";
2
+ import { PLAN_MENTION_ALIASES } from "./chat-mentions.js";
2
3
 
3
4
  export type MentionChipTheme = {
4
5
  fg: (role: string, text: string) => string;
@@ -6,40 +7,83 @@ export type MentionChipTheme = {
6
7
 
7
8
  type MentionSpan =
8
9
  | { kind: "text"; value: string }
9
- | { kind: "skill"; name: string }
10
- | { kind: "plan" };
10
+ | { kind: "skill"; name: string; source: "slash" | "at" }
11
+ | { kind: "plan"; logicalToken: string };
11
12
 
12
- const SKILL_TOKEN_RE = /\/skill:([a-z0-9_-]+)/gi;
13
+ const SKILL_SLASH_RE = /\/skill:([a-z0-9_-]+)/gi;
14
+ const AT_SKILL_RE = /@skill\s+([^\s@/]+)/gi;
13
15
  const PLAN_TOKEN_RE = /\/mode:plan\b/gi;
14
16
 
17
+ const AT_PLAN_PATTERN = PLAN_MENTION_ALIASES.map((t) =>
18
+ t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
19
+ )
20
+ .sort((a, b) => b.length - a.length)
21
+ .join("|");
22
+ const AT_PLAN_RE = new RegExp(`(?:^|[\\s"'=])(${AT_PLAN_PATTERN})(?=\\s|$)`, "gi");
23
+
24
+ const PLAN_VISIBLE_LABEL = "@plan";
25
+
26
+ function findNextMentionMatch(
27
+ line: string,
28
+ cursor: number,
29
+ ): { index: number; length: number; span: MentionSpan } | null {
30
+ const candidates: Array<{ index: number; length: number; span: MentionSpan }> = [];
31
+
32
+ SKILL_SLASH_RE.lastIndex = cursor;
33
+ const slashMatch = SKILL_SLASH_RE.exec(line);
34
+ if (slashMatch?.index !== undefined) {
35
+ candidates.push({
36
+ index: slashMatch.index,
37
+ length: slashMatch[0].length,
38
+ span: { kind: "skill", name: slashMatch[1] ?? "", source: "slash" },
39
+ });
40
+ }
41
+
42
+ AT_SKILL_RE.lastIndex = cursor;
43
+ const atMatch = AT_SKILL_RE.exec(line);
44
+ if (atMatch?.index !== undefined) {
45
+ candidates.push({
46
+ index: atMatch.index,
47
+ length: atMatch[0].length,
48
+ span: { kind: "skill", name: atMatch[1] ?? "", source: "at" },
49
+ });
50
+ }
51
+
52
+ PLAN_TOKEN_RE.lastIndex = cursor;
53
+ const planMatch = PLAN_TOKEN_RE.exec(line);
54
+ if (planMatch?.index !== undefined) {
55
+ candidates.push({
56
+ index: planMatch.index,
57
+ length: planMatch[0].length,
58
+ span: { kind: "plan", logicalToken: planMatch[0] },
59
+ });
60
+ }
61
+
62
+ AT_PLAN_RE.lastIndex = cursor;
63
+ const atPlanMatch = AT_PLAN_RE.exec(line);
64
+ if (atPlanMatch?.index !== undefined) {
65
+ const token = atPlanMatch[1] ?? "@plan";
66
+ const leading = atPlanMatch[0].length - token.length;
67
+ const index = atPlanMatch.index + leading;
68
+ candidates.push({
69
+ index,
70
+ length: token.length,
71
+ span: { kind: "plan", logicalToken: token },
72
+ });
73
+ }
74
+
75
+ if (candidates.length === 0) return null;
76
+ return candidates.reduce((earliest, candidate) =>
77
+ candidate.index < earliest.index ? candidate : earliest,
78
+ );
79
+ }
80
+
15
81
  function parseMentionSpans(line: string): MentionSpan[] {
16
82
  const spans: MentionSpan[] = [];
17
83
  let cursor = 0;
18
84
 
19
85
  while (cursor < line.length) {
20
- SKILL_TOKEN_RE.lastIndex = cursor;
21
- PLAN_TOKEN_RE.lastIndex = cursor;
22
- const skillMatch = SKILL_TOKEN_RE.exec(line);
23
- const planMatch = PLAN_TOKEN_RE.exec(line);
24
-
25
- let nextMatch: { index: number; length: number; span: MentionSpan } | null = null;
26
- if (skillMatch?.index !== undefined) {
27
- nextMatch = {
28
- index: skillMatch.index,
29
- length: skillMatch[0].length,
30
- span: { kind: "skill", name: skillMatch[1] ?? "" },
31
- };
32
- }
33
- if (planMatch?.index !== undefined) {
34
- const candidate = {
35
- index: planMatch.index,
36
- length: planMatch[0].length,
37
- span: { kind: "plan" as const },
38
- };
39
- if (!nextMatch || candidate.index < nextMatch.index) {
40
- nextMatch = candidate;
41
- }
42
- }
86
+ const nextMatch = findNextMentionMatch(line, cursor);
43
87
 
44
88
  if (!nextMatch) {
45
89
  spans.push({ kind: "text", value: line.slice(cursor) });
@@ -60,32 +104,41 @@ function parseMentionSpans(line: string): MentionSpan[] {
60
104
  return spans;
61
105
  }
62
106
 
107
+ function skillVisibleText(span: Extract<MentionSpan, { kind: "skill" }>): string {
108
+ return span.source === "at" ? `@${span.name}` : span.name;
109
+ }
110
+
111
+ function skillLogicalText(span: Extract<MentionSpan, { kind: "skill" }>): string {
112
+ return span.source === "at" ? `@skill ${span.name}` : `/skill:${span.name}`;
113
+ }
114
+
63
115
  function renderSpan(span: MentionSpan, theme: MentionChipTheme): string {
64
116
  if (span.kind === "text") return span.value;
65
117
  if (span.kind === "skill") {
118
+ const text = skillVisibleText(span);
66
119
  try {
67
- return theme.fg("accent", span.name);
120
+ return theme.fg("accent", text);
68
121
  } catch {
69
- return theme.fg("text", span.name);
122
+ return theme.fg("text", text);
70
123
  }
71
124
  }
72
125
  try {
73
- return theme.fg("planAccent", "plan");
126
+ return theme.fg("planAccent", PLAN_VISIBLE_LABEL);
74
127
  } catch {
75
- return theme.fg("text", "plan");
128
+ return theme.fg("text", PLAN_VISIBLE_LABEL);
76
129
  }
77
130
  }
78
131
 
79
132
  function spanLogicalWidth(span: MentionSpan): number {
80
133
  if (span.kind === "text") return span.value.length;
81
- if (span.kind === "skill") return `/skill:${span.name}`.length;
82
- return "/mode:plan".length;
134
+ if (span.kind === "skill") return skillLogicalText(span).length;
135
+ return span.logicalToken.length;
83
136
  }
84
137
 
85
138
  function spanVisibleText(span: MentionSpan): string {
86
139
  if (span.kind === "text") return span.value;
87
- if (span.kind === "skill") return span.name;
88
- return "plan";
140
+ if (span.kind === "skill") return skillVisibleText(span);
141
+ return PLAN_VISIBLE_LABEL;
89
142
  }
90
143
 
91
144
  export function renderLineWithMentionChips(line: string, theme: MentionChipTheme): string {
@@ -15,10 +15,11 @@ export declare function parsePlanMentionPrefix(atPrefix: string | null): {
15
15
  export declare function filterSkillSuggestions(skills: KubbisecSkillEntry[], query: string): AutocompleteItem[];
16
16
  /** Pi expands `/skill:name` — map `@skill name` before submit. */
17
17
  export declare function transformAtSkillMentions(text: string): string;
18
- /** Map `@plan` / `@planejar` to `/mode:plan` before submit. */
18
+ /** Legacy: map `@plan` / `@planejar` to `/mode:plan` (prefer session state + visible @plan). */
19
19
  export declare function transformAtPlanMentions(text: string): string;
20
- /** Apply skill transform first, then plan (CHAT-004). */
20
+ /** Apply @skill /skill:name only. @plan stays visible; plan mode is set via session state. */
21
21
  export declare function transformChatMentions(text: string): string;
22
+ export declare function messageActivatesPlanMode(text: string): boolean;
22
23
  export declare function applySkillMentionCompletion(lines: string[], cursorLine: number, cursorCol: number, item: AutocompleteItem, prefix: string): {
23
24
  lines: string[];
24
25
  cursorLine: number;
@@ -1 +1 @@
1
- {"version":3,"file":"chat-mentions.d.ts","sourceRoot":"","sources":["../../src/skills/chat-mentions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAE5C,eAAO,MAAM,oBAAoB,iCAAkC,CAAC;AAiBpE,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvE;AAED,2FAA2F;AAC3F,wBAAgB,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKzF;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASxF;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,EAAE,EAC5B,KAAK,EAAE,MAAM,GACZ,gBAAgB,EAAE,CAcpB;AAED,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,+DAA+D;AAC/D,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,yDAAyD;AACzD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAe5D"}
1
+ {"version":3,"file":"chat-mentions.d.ts","sourceRoot":"","sources":["../../src/skills/chat-mentions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAE5C,eAAO,MAAM,oBAAoB,iCAAkC,CAAC;AAiBpE,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvE;AAED,2FAA2F;AAC3F,wBAAgB,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKzF;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASxF;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,EAAE,EAC5B,KAAK,EAAE,MAAM,GACZ,gBAAgB,EAAE,CAcpB;AAED,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,gGAAgG;AAChG,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,gGAAgG;AAChG,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO9D;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAe5D"}
@@ -72,7 +72,7 @@ export function filterSkillSuggestions(skills, query) {
72
72
  export function transformAtSkillMentions(text) {
73
73
  return text.replace(/@skill\s+([^\s@/]+)/g, "/skill:$1");
74
74
  }
75
- /** Map `@plan` / `@planejar` to `/mode:plan` before submit. */
75
+ /** Legacy: map `@plan` / `@planejar` to `/mode:plan` (prefer session state + visible @plan). */
76
76
  export function transformAtPlanMentions(text) {
77
77
  const tokenPattern = PLAN_MENTION_TOKENS_LONGEST_FIRST.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
78
78
  const pattern = new RegExp(`(^|[\\s"'=])(${tokenPattern})(\\s[\\s\\S]*)?`, "g");
@@ -81,9 +81,15 @@ export function transformAtPlanMentions(text) {
81
81
  return `${delim}/mode:plan${query ? ` ${query}` : ""}`;
82
82
  });
83
83
  }
84
- /** Apply skill transform first, then plan (CHAT-004). */
84
+ /** Apply @skill /skill:name only. @plan stays visible; plan mode is set via session state. */
85
85
  export function transformChatMentions(text) {
86
- return transformAtPlanMentions(transformAtSkillMentions(text));
86
+ return transformAtSkillMentions(text);
87
+ }
88
+ export function messageActivatesPlanMode(text) {
89
+ const trimmed = text.trim();
90
+ return (trimmed.startsWith("/mode:plan") ||
91
+ /^@plan\b/i.test(trimmed) ||
92
+ /^@planejar\b/i.test(trimmed));
87
93
  }
88
94
  export function applySkillMentionCompletion(lines, cursorLine, cursorCol, item, prefix) {
89
95
  const currentLine = lines[cursorLine] ?? "";
@@ -1 +1 @@
1
- {"version":3,"file":"chat-mentions.js","sourceRoot":"","sources":["../../src/skills/chat-mentions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-mentions.js","sourceRoot":"","sources":["../../src/skills/chat-mentions.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import {
3
+ messageActivatesPlanMode,
3
4
  parsePlanMentionPrefix,
4
5
  PLAN_MENTION_ALIASES,
5
6
  transformAtPlanMentions,
@@ -18,15 +19,21 @@ describe("chat-mentions", () => {
18
19
  expect(parsePlanMentionPrefix("@planful")).toBeNull();
19
20
  });
20
21
 
21
- it("transforms @plan to /mode:plan", () => {
22
+ it("transformAtPlanMentions still maps legacy @plan to /mode:plan", () => {
22
23
  expect(transformAtPlanMentions("@plan fix HIGH SCA")).toBe("/mode:plan fix HIGH SCA");
23
24
  expect(transformAtPlanMentions("@planejar foo")).toBe("/mode:plan foo");
24
- expect(transformAtPlanMentions("@plan")).toBe("/mode:plan");
25
25
  expect(transformAtPlanMentions("x@plan fix")).toBe("x@plan fix");
26
26
  });
27
27
 
28
- it("transforms combined skill and plan mentions (skill first)", () => {
29
- expect(transformChatMentions("@skill naus @plan fix")).toBe("/skill:naus /mode:plan fix");
30
- expect(transformChatMentions("@planejar x")).toBe("/mode:plan x");
28
+ it("transformChatMentions keeps @plan visible (plan mode via session state)", () => {
29
+ expect(transformChatMentions("@plan fix HIGH SCA")).toBe("@plan fix HIGH SCA");
30
+ expect(transformChatMentions("@planejar x")).toBe("@planejar x");
31
+ expect(transformChatMentions("@skill naus @plan fix")).toBe("/skill:naus @plan fix");
32
+ });
33
+
34
+ it("messageActivatesPlanMode detects plan prefixes", () => {
35
+ expect(messageActivatesPlanMode("@plan scope")).toBe(true);
36
+ expect(messageActivatesPlanMode("/mode:plan scope")).toBe(true);
37
+ expect(messageActivatesPlanMode("hello")).toBe(false);
31
38
  });
32
39
  });
@@ -85,7 +85,7 @@ export function transformAtSkillMentions(text: string): string {
85
85
  return text.replace(/@skill\s+([^\s@/]+)/g, "/skill:$1");
86
86
  }
87
87
 
88
- /** Map `@plan` / `@planejar` to `/mode:plan` before submit. */
88
+ /** Legacy: map `@plan` / `@planejar` to `/mode:plan` (prefer session state + visible @plan). */
89
89
  export function transformAtPlanMentions(text: string): string {
90
90
  const tokenPattern = PLAN_MENTION_TOKENS_LONGEST_FIRST.map((t) =>
91
91
  t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
@@ -97,9 +97,18 @@ export function transformAtPlanMentions(text: string): string {
97
97
  });
98
98
  }
99
99
 
100
- /** Apply skill transform first, then plan (CHAT-004). */
100
+ /** Apply @skill /skill:name only. @plan stays visible; plan mode is set via session state. */
101
101
  export function transformChatMentions(text: string): string {
102
- return transformAtPlanMentions(transformAtSkillMentions(text));
102
+ return transformAtSkillMentions(text);
103
+ }
104
+
105
+ export function messageActivatesPlanMode(text: string): boolean {
106
+ const trimmed = text.trim();
107
+ return (
108
+ trimmed.startsWith("/mode:plan") ||
109
+ /^@plan\b/i.test(trimmed) ||
110
+ /^@planejar\b/i.test(trimmed)
111
+ );
103
112
  }
104
113
 
105
114
  export function applySkillMentionCompletion(
@@ -3,29 +3,124 @@ name: naus-pipelines
3
3
  description: NAUS CI/CD — YAML, validação @naus/validation, runners e jobs ASPM no KubbiSec.
4
4
  ---
5
5
 
6
+ ## Estrutura YAML (obrigatório — não é GitHub Actions)
7
+
8
+ | Correto (NAUS) | Errado (não usar) |
9
+ |----------------|-------------------|
10
+ | `run:` (top-level) | `jobs:` |
11
+ | `script:` (array de strings) | `commands:`, `steps:` |
12
+ | `depends_on:` | `needs:` |
13
+ | `variables:` | `env:` no root |
14
+ | `kind: aspm` + `tool: trivy` | `scanner: trivy` + script manual `trivy fs` |
15
+ | `$VAR` / Env Pack | `${{ secrets.* }}`, `${{ vars.* }}` |
16
+
17
+ Top-level: `name`, `description`, `local`, `stages`, `variables`, `volumes`, `repository`, `only`, `run` (obrigatório).
18
+
19
+ **HARD-GATE:** antes de mostrar YAML final → `naus_pipeline_docs` + `naus_validate_yaml` (ou `naus_local_validate` com `--extended-context`).
20
+
21
+ ## NAUS CLI (`npm install -g @kubbisec/naus`)
22
+
23
+ Ficheiro por omissão: `.naus.yml`. **Docs:** `naus_pipeline_docs` secção `naus-commands`.
24
+
25
+ | Comando | Descrição |
26
+ |---------|-----------|
27
+ | `naus register [token] [--renew]` | Registar runner (bootstrap mTLS) |
28
+ | `naus start` | Iniciar runner e aceitar jobs |
29
+ | `naus migrate` | Migrar runner token legado → certificado |
30
+ | `naus validate <file>` / `naus check <file>` | Validar YAML |
31
+ | `naus plan <file> [--format mermaid]` | Ondas de dependências |
32
+ | `naus run <file>` | Executar pipeline localmente |
33
+ | `naus daemon list` / `naus daemon stop` | Sessões background |
34
+ | `naus runner start` | Modo legado (token, sem mTLS) |
35
+ | `naus tools install` | Ferramentas auxiliares |
36
+
37
+ **Variáveis:** `NAUS_BOOTSTRAP_TOKEN`, `NAUS_RENEW_RUNNER=1` (equivale `--renew`).
38
+
39
+ **Chat:** não invocar `register`, `start`, `daemon` — processos persistentes; documentar apenas.
40
+
41
+ ## Exemplo canónico (container + ASPM matrix + gate)
42
+
43
+ ```yaml
44
+ name: exemplo-simples
45
+ stages: [build, security]
46
+
47
+ run:
48
+ - build:
49
+ stage: build
50
+ image: node:20-alpine
51
+ script:
52
+ - npm ci
53
+ - npm run build --if-present
54
+
55
+ - kubbisec_scan:
56
+ stage: security
57
+ kind: aspm_matrix
58
+ mode: scan-and-upload
59
+ matrix_strategy: chain
60
+ depends_on: [build]
61
+ parallel:
62
+ - tool: osv
63
+ - tool: gitleaks
64
+ - tool: syft
65
+
66
+ - kubbisec_gate:
67
+ kind: aspm_gate
68
+ depends_on: [kubbisec_scan]
69
+ rules:
70
+ vulnerabilities:
71
+ max_by_severity:
72
+ CRITICAL: 0
73
+ ```
74
+
75
+ Jobs `kind: aspm` **não** precisam de `script:` — o NAUS expande scanner + upload. Use `tool:` (não `scanner:`).
76
+
77
+ ## Kinds de job
78
+
79
+ | Kind | Campos principais |
80
+ |------|-------------------|
81
+ | `container` (default) | `image:`, `script:`, `depends_on:` |
82
+ | `aspm` | `tool:`, `mode:` scan \| upload \| scan-and-upload |
83
+ | `aspm_matrix` | `parallel: [{ tool: ... }]`, `matrix_strategy:` chain \| fanout |
84
+ | `aspm_gate` | `rules:` (vulnerabilities, coverage, risk_score) |
85
+ | `aspm_preset` | `preset: kubbisec/default-security` |
86
+ | `docker` | `registry:`, `tags:`; opcional `aspm.tool` + `aspm.gate` |
87
+
6
88
  ## Fluxo na plataforma (cloud)
7
89
 
8
- 1. `naus_pipeline_docs` — 20 secções web (paridade `kubbisec://naus/*`) + runner-management + validation.
9
- 2. `naus_schema_overview` — campos e kinds suportados.
10
- 3. `naus_validate_yaml` — validar candidato antes de persistir.
90
+ 1. `naus_pipeline_docs` — secções web (`naus-commands`, `naus-pipeline-overview`, `naus-aspm-integration`, …).
91
+ 2. `naus_schema_overview` — cheat sheet de campos.
92
+ 3. `naus_validate_yaml` — **sempre** validar antes de persistir.
11
93
  4. `set_editor_yaml` (preview) → `set_pipeline_yaml` (bound) → `trigger_run` → `get_run_logs_excerpt`.
12
94
 
13
- ## Fluxo local (`kbs chat --extended-context -w <repo>`)
95
+ ## Secrets e variáveis
96
+
97
+ | Contexto | Onde definir valores sensíveis |
98
+ |----------|-------------------------------|
99
+ | **`naus run` / `naus plan` local** | Por omissão: **`.secrets`** e **`.env`** no cwd. Ou caminhos explícitos: `naus run .naus.yml --env-file .env --secret-file .secrets` (qualquer nome, ex. `.secret`). Flags repetíveis. |
100
+ | **Runner na cloud (KubbiSec)** | **Env Packs** no painel (CI/CD → Env Packs) associados ao pipeline — não usar `.secrets` no runner remoto. |
101
+
102
+ No YAML, referencie apenas `$VAR` — nunca o valor em claro. Chaves em `.secrets` são ofuscadas nos logs locais. **Não commitar** `.secrets`.
14
103
 
15
- - `naus_local_status` — `naus` no PATH.
16
- - `naus_local_validate` `naus validate <path>` no workspace.
17
- - `naus_local_plan` `naus plan <path>` (text ou mermaid).
18
- - `naus_local_run` — `naus run <path>` (até 15 min; preferir `trigger_run` em CI cloud).
104
+ **Anti-padrões (secrets):**
105
+ - Local `naus run` criar `.secrets` no repo; **não** inventar `kubsec_set_secret`, `naus set_env_pack` ou `attach_env_pack` para execução local.
106
+ - Cloud Env Packs na UI; `.secrets` existe na máquina onde corres `naus run`.
107
+
108
+ ## Fluxo local (`kbs chat --extended-context -w <repo>`)
19
109
 
20
- **Não** invocar `naus register`, `naus start` ou `naus daemon` via chat — processos persistentes; ver `naus_pipeline_docs` / runner-management.
110
+ | Tool | Comando |
111
+ |------|---------|
112
+ | `naus_local_status` | `naus` no PATH |
113
+ | `naus_local_validate` | `naus validate <path>` |
114
+ | `naus_local_plan` | `naus plan <path>` (lê `.env` / `.secrets` como `naus run`) |
115
+ | `naus_local_run` | `naus run <path>` (até 15 min; lê `.secrets` por omissão) |
21
116
 
22
- ## Kinds ASPM
117
+ ## Runner enrollment (documentar, não executar no chat)
23
118
 
24
- - `kind: aspm` + `tool` (trivy, gitleaks, syft, osv, semgrep, sonar, nmap, skipfish).
25
- - `kind: aspm_matrix` `parallel` com várias tools.
26
- - `kind: aspm_gate` — políticas após upload.
27
- - `kind: docker` build/registry; `aspm.tool: trivy` para scan de imagem + gate.
119
+ 1. Obter bootstrap token `bt_...` na UI (Runners).
120
+ 2. `naus register <token>` → grava `~/.kubbisec/naus/config.json` + certificados mTLS.
121
+ 3. `naus start` — runner aceita jobs da cloud.
122
+ 4. Re-registo do mesmo runner: token de re-registo na UI ou `naus migrate` (token legado `nau_...`).
28
123
 
29
- ## Scanners locais
124
+ ## Scanners locais (fora do pipeline)
30
125
 
31
- Para `aspm scan` / `aspm upload` no host, skill `aspm-platform` e `aspm_local_*`.
126
+ Para `aspm scan` / `aspm upload` no host skill `aspm-platform` e `aspm_local_*`.