@kubbisec/ai-linux-arm64 0.1.8 → 0.1.10
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/bin/kubbisec +0 -0
- package/bundled/assets/terminal/wordmark-inline.ansi +1 -0
- package/bundled/assets/terminal/wordmark.ansi +4 -0
- package/bundled/assets/terminal/wordmark.png +0 -0
- package/bundled/clarify/clarify-gate-state.d.ts +3 -0
- package/bundled/clarify/clarify-gate-state.d.ts.map +1 -0
- package/bundled/clarify/clarify-gate-state.js +9 -0
- package/bundled/clarify/clarify-gate-state.js.map +1 -0
- package/bundled/clarify/clarify-gate.d.ts +2 -1
- package/bundled/clarify/clarify-gate.d.ts.map +1 -1
- package/bundled/clarify/clarify-gate.js +17 -4
- package/bundled/clarify/clarify-gate.js.map +1 -1
- package/bundled/clarify/clarify-select-panel.d.ts +14 -0
- package/bundled/clarify/clarify-select-panel.d.ts.map +1 -0
- package/bundled/clarify/clarify-select-panel.js +82 -0
- package/bundled/clarify/clarify-select-panel.js.map +1 -0
- package/bundled/clarify/clarify-ui-state.d.ts +10 -1
- package/bundled/clarify/clarify-ui-state.d.ts.map +1 -1
- package/bundled/clarify/clarify-ui-state.js +24 -3
- package/bundled/clarify/clarify-ui-state.js.map +1 -1
- package/bundled/clarify/parse-clarify-answer.d.ts +6 -1
- package/bundled/clarify/parse-clarify-answer.d.ts.map +1 -1
- package/bundled/clarify/parse-clarify-answer.js +35 -2
- package/bundled/clarify/parse-clarify-answer.js.map +1 -1
- package/bundled/clarify/question-format.d.ts +7 -4
- package/bundled/clarify/question-format.d.ts.map +1 -1
- package/bundled/clarify/question-format.js +26 -33
- package/bundled/clarify/question-format.js.map +1 -1
- package/bundled/clarify/questionnaire-tool.d.ts.map +1 -1
- package/bundled/clarify/questionnaire-tool.js +16 -9
- package/bundled/clarify/questionnaire-tool.js.map +1 -1
- package/bundled/clarify/scope-discovery.d.ts +10 -0
- package/bundled/clarify/scope-discovery.d.ts.map +1 -0
- package/bundled/clarify/scope-discovery.js +130 -0
- package/bundled/clarify/scope-discovery.js.map +1 -0
- package/bundled/clarify/session-questionnaire.d.ts +4 -1
- package/bundled/clarify/session-questionnaire.d.ts.map +1 -1
- package/bundled/clarify/session-questionnaire.js +59 -4
- package/bundled/clarify/session-questionnaire.js.map +1 -1
- package/bundled/clarify/session-questionnaire.types.d.ts +2 -0
- package/bundled/clarify/session-questionnaire.types.d.ts.map +1 -1
- package/bundled/clarify/session-questionnaire.types.js.map +1 -1
- package/bundled/config/detect-local-llm-providers.d.ts +33 -0
- package/bundled/config/detect-local-llm-providers.d.ts.map +1 -0
- package/bundled/config/detect-local-llm-providers.js +173 -0
- package/bundled/config/detect-local-llm-providers.js.map +1 -0
- package/bundled/config/ensure-kubbisec-project-settings.d.ts +8 -0
- package/bundled/config/ensure-kubbisec-project-settings.d.ts.map +1 -1
- package/bundled/config/ensure-kubbisec-project-settings.js +31 -0
- package/bundled/config/ensure-kubbisec-project-settings.js.map +1 -1
- package/bundled/config/extended-context.d.ts +12 -0
- package/bundled/config/extended-context.d.ts.map +1 -0
- package/bundled/config/extended-context.js +37 -0
- package/bundled/config/extended-context.js.map +1 -0
- package/bundled/config/format-kubbisec-footer-status.d.ts.map +1 -1
- package/bundled/config/format-kubbisec-footer-status.js +10 -1
- package/bundled/config/format-kubbisec-footer-status.js.map +1 -1
- package/bundled/config/kubbisec-extension-manifest.d.ts +3 -0
- package/bundled/config/kubbisec-extension-manifest.d.ts.map +1 -0
- package/bundled/config/kubbisec-extension-manifest.js +23 -0
- package/bundled/config/kubbisec-extension-manifest.js.map +1 -0
- package/bundled/config/llm-config-mutations.d.ts +38 -0
- package/bundled/config/llm-config-mutations.d.ts.map +1 -0
- package/bundled/config/llm-config-mutations.js +207 -0
- package/bundled/config/llm-config-mutations.js.map +1 -0
- package/bundled/config/llm-config.d.ts +64 -0
- package/bundled/config/llm-config.d.ts.map +1 -0
- package/bundled/config/llm-config.js +236 -0
- package/bundled/config/llm-config.js.map +1 -0
- package/bundled/config/llm-provider-catalog.d.ts +22 -0
- package/bundled/config/llm-provider-catalog.d.ts.map +1 -0
- package/bundled/config/llm-provider-catalog.js +42 -0
- package/bundled/config/llm-provider-catalog.js.map +1 -0
- package/bundled/config/materialize-kubbisec-pi-resources.d.ts +13 -0
- package/bundled/config/materialize-kubbisec-pi-resources.d.ts.map +1 -0
- package/bundled/config/materialize-kubbisec-pi-resources.js +171 -0
- package/bundled/config/materialize-kubbisec-pi-resources.js.map +1 -0
- package/bundled/config/register-custom-llm-providers.d.ts +13 -0
- package/bundled/config/register-custom-llm-providers.d.ts.map +1 -0
- package/bundled/config/register-custom-llm-providers.js +21 -0
- package/bundled/config/register-custom-llm-providers.js.map +1 -0
- package/bundled/config/register-kubbisec-llm-provider.d.ts +14 -0
- package/bundled/config/register-kubbisec-llm-provider.d.ts.map +1 -0
- package/bundled/config/register-kubbisec-llm-provider.js +53 -0
- package/bundled/config/register-kubbisec-llm-provider.js.map +1 -0
- package/bundled/config/sync-kubbisec-pi-models.d.ts +12 -0
- package/bundled/config/sync-kubbisec-pi-models.d.ts.map +1 -0
- package/bundled/config/sync-kubbisec-pi-models.js +80 -0
- package/bundled/config/sync-kubbisec-pi-models.js.map +1 -0
- package/bundled/copy/cli-reference-index.d.ts +6 -0
- package/bundled/copy/cli-reference-index.d.ts.map +1 -0
- package/bundled/copy/cli-reference-index.js +42 -0
- package/bundled/copy/cli-reference-index.js.map +1 -0
- package/bundled/copy/kubbisec-shell-copy.d.ts +15 -2
- package/bundled/copy/kubbisec-shell-copy.d.ts.map +1 -1
- package/bundled/copy/kubbisec-shell-copy.js +15 -2
- package/bundled/copy/kubbisec-shell-copy.js.map +1 -1
- package/bundled/extensions/cli-local-shared.d.ts +31 -11
- package/bundled/extensions/cli-local-shared.d.ts.map +1 -1
- package/bundled/extensions/cli-local-shared.js +56 -10
- package/bundled/extensions/cli-local-shared.js.map +1 -1
- package/bundled/extensions/kubbisec-aspm-local.extension.d.ts +1 -0
- package/bundled/extensions/kubbisec-aspm-local.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-aspm-local.extension.js +32 -44
- package/bundled/extensions/kubbisec-aspm-local.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-brand.extension.d.ts +2 -19
- package/bundled/extensions/kubbisec-brand.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-brand.extension.js +21 -73
- package/bundled/extensions/kubbisec-brand.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-byok-provider.extension.d.ts +3 -27
- package/bundled/extensions/kubbisec-byok-provider.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-byok-provider.extension.js +2 -48
- package/bundled/extensions/kubbisec-byok-provider.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-clarify.extension.d.ts +6 -1
- package/bundled/extensions/kubbisec-clarify.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-clarify.extension.js +124 -68
- package/bundled/extensions/kubbisec-clarify.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-exit.extension.d.ts +3 -0
- package/bundled/extensions/kubbisec-exit.extension.d.ts.map +1 -0
- package/bundled/extensions/kubbisec-exit.extension.js +38 -0
- package/bundled/extensions/kubbisec-exit.extension.js.map +1 -0
- package/bundled/extensions/kubbisec-extended-context.extension.d.ts +6 -0
- package/bundled/extensions/kubbisec-extended-context.extension.d.ts.map +1 -0
- package/bundled/extensions/kubbisec-extended-context.extension.js +50 -0
- package/bundled/extensions/kubbisec-extended-context.extension.js.map +1 -0
- package/bundled/extensions/kubbisec-footer.extension.d.ts +16 -61
- package/bundled/extensions/kubbisec-footer.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-footer.extension.js +143 -74
- package/bundled/extensions/kubbisec-footer.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-github-local.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-github-local.extension.js +52 -22
- package/bundled/extensions/kubbisec-github-local.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-llm-config.extension.d.ts +3 -0
- package/bundled/extensions/kubbisec-llm-config.extension.d.ts.map +1 -0
- package/bundled/extensions/kubbisec-llm-config.extension.js +211 -0
- package/bundled/extensions/kubbisec-llm-config.extension.js.map +1 -0
- package/bundled/extensions/kubbisec-naus-local.extension.d.ts +1 -0
- package/bundled/extensions/kubbisec-naus-local.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-naus-local.extension.js +54 -58
- package/bundled/extensions/kubbisec-naus-local.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-platform-tools.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-platform-tools.extension.js +57 -16
- package/bundled/extensions/kubbisec-platform-tools.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-skill-mentions.extension.d.ts +1 -0
- package/bundled/extensions/kubbisec-skill-mentions.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-skill-mentions.extension.js +24 -8
- package/bundled/extensions/kubbisec-skill-mentions.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-theme-lock.extension.d.ts +6 -0
- package/bundled/extensions/kubbisec-theme-lock.extension.d.ts.map +1 -0
- package/bundled/extensions/kubbisec-theme-lock.extension.js +43 -0
- package/bundled/extensions/kubbisec-theme-lock.extension.js.map +1 -0
- package/bundled/extensions/kubbisec-ui.extension.d.ts +1 -1
- package/bundled/extensions/kubbisec-ui.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-ui.extension.js +98 -82
- package/bundled/extensions/kubbisec-ui.extension.js.map +1 -1
- package/bundled/extensions/kubbisec-workflow.extension.d.ts.map +1 -1
- package/bundled/extensions/kubbisec-workflow.extension.js +31 -21
- package/bundled/extensions/kubbisec-workflow.extension.js.map +1 -1
- package/bundled/skills/aspm-platform/SKILL.md +55 -25
- package/bundled/skills/at-path-mentions.d.ts +7 -0
- package/bundled/skills/at-path-mentions.d.ts.map +1 -0
- package/bundled/skills/at-path-mentions.js +186 -0
- package/bundled/skills/at-path-mentions.js.map +1 -0
- package/bundled/skills/at-path-mentions.test.ts +64 -0
- package/bundled/skills/at-path-mentions.ts +211 -0
- package/bundled/skills/chat-mention-render.d.ts.map +1 -1
- package/bundled/skills/chat-mention-render.js +69 -31
- package/bundled/skills/chat-mention-render.js.map +1 -1
- package/bundled/skills/chat-mention-render.test.ts +24 -1
- package/bundled/skills/chat-mention-render.ts +87 -34
- package/bundled/skills/chat-mentions.d.ts +3 -2
- package/bundled/skills/chat-mentions.d.ts.map +1 -1
- package/bundled/skills/chat-mentions.js +9 -3
- package/bundled/skills/chat-mentions.js.map +1 -1
- package/bundled/skills/chat-mentions.test.ts +12 -5
- package/bundled/skills/chat-mentions.ts +12 -3
- package/bundled/skills/naus-pipelines/SKILL.md +111 -16
- package/bundled/skills/sec-clarify/SKILL.md +8 -23
- package/bundled/skills/sec-using-skills/SKILL.md +2 -0
- package/bundled/theme/clear-terminal.d.ts +3 -0
- package/bundled/theme/clear-terminal.d.ts.map +1 -0
- package/bundled/theme/clear-terminal.js +7 -0
- package/bundled/theme/clear-terminal.js.map +1 -0
- package/bundled/theme/footer-render-hook.d.ts +3 -0
- package/bundled/theme/footer-render-hook.d.ts.map +1 -0
- package/bundled/theme/footer-render-hook.js +8 -0
- package/bundled/theme/footer-render-hook.js.map +1 -0
- package/bundled/theme/kubbisec-brand-fg.d.ts +4 -0
- package/bundled/theme/kubbisec-brand-fg.d.ts.map +1 -0
- package/bundled/theme/kubbisec-brand-fg.js +7 -0
- package/bundled/theme/kubbisec-brand-fg.js.map +1 -0
- package/bundled/theme/kubbisec-menu-themes.d.ts +16 -0
- package/bundled/theme/kubbisec-menu-themes.d.ts.map +1 -0
- package/bundled/theme/kubbisec-menu-themes.js +47 -0
- package/bundled/theme/kubbisec-menu-themes.js.map +1 -0
- package/bundled/theme/kubbisec-theme-name.d.ts +2 -0
- package/bundled/theme/kubbisec-theme-name.d.ts.map +1 -0
- package/bundled/theme/kubbisec-theme-name.js +2 -0
- package/bundled/theme/kubbisec-theme-name.js.map +1 -0
- package/bundled/theme/patch-pi-settings-theme.runtime.d.ts +3 -0
- package/bundled/theme/patch-pi-settings-theme.runtime.d.ts.map +1 -0
- package/bundled/theme/patch-pi-settings-theme.runtime.js +16 -0
- package/bundled/theme/patch-pi-settings-theme.runtime.js.map +1 -0
- package/bundled/theme/render-compact-header.d.ts +21 -0
- package/bundled/theme/render-compact-header.d.ts.map +1 -0
- package/bundled/theme/render-compact-header.js +198 -0
- package/bundled/theme/render-compact-header.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,32 +1,63 @@
|
|
|
1
1
|
import { visibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
-
|
|
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
|
-
|
|
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",
|
|
88
|
+
return theme.fg("accent", text);
|
|
51
89
|
}
|
|
52
90
|
catch {
|
|
53
|
-
return theme.fg("text",
|
|
91
|
+
return theme.fg("text", text);
|
|
54
92
|
}
|
|
55
93
|
}
|
|
56
94
|
try {
|
|
57
|
-
return theme.fg("planAccent",
|
|
95
|
+
return theme.fg("planAccent", PLAN_VISIBLE_LABEL);
|
|
58
96
|
}
|
|
59
97
|
catch {
|
|
60
|
-
return theme.fg("text",
|
|
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
|
|
68
|
-
return
|
|
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
|
|
75
|
-
return
|
|
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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
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
|
|
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
|
-
|
|
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",
|
|
120
|
+
return theme.fg("accent", text);
|
|
68
121
|
} catch {
|
|
69
|
-
return theme.fg("text",
|
|
122
|
+
return theme.fg("text", text);
|
|
70
123
|
}
|
|
71
124
|
}
|
|
72
125
|
try {
|
|
73
|
-
return theme.fg("planAccent",
|
|
126
|
+
return theme.fg("planAccent", PLAN_VISIBLE_LABEL);
|
|
74
127
|
} catch {
|
|
75
|
-
return theme.fg("text",
|
|
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
|
|
82
|
-
return
|
|
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
|
|
88
|
-
return
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
84
|
+
/** Apply @skill → /skill:name only. @plan stays visible; plan mode is set via session state. */
|
|
85
85
|
export function transformChatMentions(text) {
|
|
86
|
-
return
|
|
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("
|
|
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("
|
|
29
|
-
expect(transformChatMentions("@
|
|
30
|
-
expect(transformChatMentions("@planejar x")).toBe("
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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` —
|
|
9
|
-
2. `naus_schema_overview` —
|
|
10
|
-
3. `naus_validate_yaml` — validar
|
|
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
|
-
##
|
|
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
|
-
-
|
|
16
|
-
- `
|
|
17
|
-
-
|
|
18
|
-
|
|
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` só existe na máquina onde corres `naus run`.
|
|
107
|
+
|
|
108
|
+
## Fluxo local (`kbs chat --extended-context -w <repo>`)
|
|
19
109
|
|
|
20
|
-
|
|
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
|
-
##
|
|
117
|
+
## Runner enrollment (documentar, não executar no chat)
|
|
23
118
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
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
|
|
126
|
+
Para `aspm scan` / `aspm upload` no host → skill `aspm-platform` e `aspm_local_*`.
|