codemini-cli 0.5.10 → 0.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/OPERATIONS.md +242 -242
  2. package/README.md +588 -588
  3. package/codemini-web/dist/assets/{highlighted-body-OFNGDK62-7HL7yft8.js → highlighted-body-OFNGDK62-CANOG7Xg.js} +1 -1
  4. package/codemini-web/dist/assets/{index-BK75hMb2.js → index-B71xykPM.js} +108 -108
  5. package/codemini-web/dist/assets/index-Dkq1DdDX.css +2 -0
  6. package/codemini-web/dist/assets/mermaid-GHXKKRXX-Z_w7M93P.js +1 -0
  7. package/codemini-web/dist/index.html +23 -23
  8. package/codemini-web/lib/approval-manager.js +32 -32
  9. package/codemini-web/lib/runtime-bridge.js +17 -11
  10. package/codemini-web/server.js +534 -205
  11. package/deployment.md +212 -212
  12. package/package.json +1 -1
  13. package/skills/brainstorm/SKILL.md +77 -77
  14. package/skills/codemini.skills.json +40 -40
  15. package/skills/grill-me/SKILL.md +30 -30
  16. package/skills/superpowers-lite/SKILL.md +82 -82
  17. package/src/cli.js +74 -74
  18. package/src/commands/chat.js +210 -210
  19. package/src/commands/run.js +313 -313
  20. package/src/commands/skill.js +438 -304
  21. package/src/commands/web.js +57 -57
  22. package/src/core/agent-loop.js +980 -980
  23. package/src/core/ast.js +309 -307
  24. package/src/core/chat-runtime.js +6261 -6253
  25. package/src/core/command-evaluator.js +72 -72
  26. package/src/core/command-loader.js +311 -311
  27. package/src/core/command-policy.js +301 -301
  28. package/src/core/command-risk.js +156 -156
  29. package/src/core/config-store.js +289 -289
  30. package/src/core/constants.js +18 -1
  31. package/src/core/context-compact.js +365 -365
  32. package/src/core/default-system-prompt.js +114 -107
  33. package/src/core/dream-audit.js +105 -105
  34. package/src/core/dream-consolidate.js +229 -229
  35. package/src/core/dream-evaluator.js +185 -185
  36. package/src/core/fff-adapter.js +383 -383
  37. package/src/core/memory-store.js +543 -543
  38. package/src/core/project-index.js +737 -548
  39. package/src/core/project-instructions.js +98 -98
  40. package/src/core/provider/anthropic.js +514 -514
  41. package/src/core/provider/openai-compatible.js +501 -501
  42. package/src/core/reflect-skill.js +178 -178
  43. package/src/core/reply-language.js +40 -40
  44. package/src/core/session-store.js +474 -474
  45. package/src/core/shell-profile.js +237 -237
  46. package/src/core/shell.js +323 -323
  47. package/src/core/soul.js +69 -69
  48. package/src/core/system-prompt-composer.js +52 -52
  49. package/src/core/tool-args.js +199 -154
  50. package/src/core/tool-output.js +184 -184
  51. package/src/core/tool-result-store.js +206 -206
  52. package/src/core/tools.js +3024 -2893
  53. package/src/core/version.js +11 -11
  54. package/src/tui/chat-app.js +5171 -5171
  55. package/src/tui/tool-activity/presenters/misc.js +30 -30
  56. package/src/tui/tool-activity/presenters/system.js +20 -20
  57. package/templates/project-requirements/report-shell.html +582 -582
  58. package/codemini-web/dist/assets/index-BSdIdn3L.css +0 -2
  59. package/codemini-web/dist/assets/mermaid-GHXKKRXX-Dg9qh8mg.js +0 -1
@@ -1,184 +1,184 @@
1
- import cliTruncate from 'cli-truncate';
2
- import stripAnsi from 'strip-ansi';
3
- import { classifyCommandIntent } from './shell.js';
4
-
5
- const CONTROL_CHARS_RE = /[\u0000-\u0008\u000B-\u001F\u007F]/g;
6
-
7
- export function sanitizeTextForModel(
8
- value,
9
- {
10
- maxChars = 0,
11
- maxLineLength = 220,
12
- maxConsecutiveBlankLines = 1
13
- } = {}
14
- ) {
15
- if (value == null) return '';
16
-
17
- const lines = String(value)
18
- .replace(/\r\n?/g, '\n')
19
- .split('\n');
20
- const output = [];
21
- let blankRun = 0;
22
-
23
- for (const rawLine of lines) {
24
- const line = stripAnsi(rawLine).replace(CONTROL_CHARS_RE, '').replace(/[ \t]+$/g, '');
25
- if (!line.trim()) {
26
- blankRun += 1;
27
- if (blankRun > maxConsecutiveBlankLines) continue;
28
- output.push('');
29
- continue;
30
- }
31
-
32
- blankRun = 0;
33
- output.push(
34
- maxLineLength > 0
35
- ? cliTruncate(line, maxLineLength, { position: 'end' })
36
- : line
37
- );
38
- }
39
-
40
- let sanitized = output.join('\n').trimEnd();
41
- if (maxChars > 0 && sanitized.length > maxChars) {
42
- sanitized = `${sanitized.slice(0, maxChars)}\n... [sanitized output truncated ${sanitized.length - maxChars} chars]`;
43
- }
44
- return sanitized;
45
- }
46
-
47
- export function getToolOutputSanitizeOptions(toolName) {
48
- const name = String(toolName || '').trim();
49
- if (name === 'read' || name === 'read_ast_node' || name === 'run' || name === 'web_fetch') {
50
- return {
51
- maxLineLength: 0
52
- };
53
- }
54
- return {};
55
- }
56
-
57
- export function sanitizePreviewLines(value, { maxLineLength = 220 } = {}) {
58
- const sanitized = sanitizeTextForModel(value, {
59
- maxLineLength,
60
- maxConsecutiveBlankLines: 0
61
- });
62
- if (!sanitized) return [];
63
- return sanitized
64
- .split('\n')
65
- .map((line) => line.trim())
66
- .filter(Boolean);
67
- }
68
-
69
- function summarizeGitStatusPorcelain(stdout) {
70
- const modified = [];
71
- const added = [];
72
- const deleted = [];
73
- const untracked = [];
74
-
75
- for (const line of String(stdout || '').split('\n')) {
76
- const trimmed = line.trimEnd();
77
- if (!trimmed) continue;
78
- const status = trimmed.slice(0, 2);
79
- const file = trimmed.slice(3).trim();
80
- if (!file) continue;
81
- if (status === '??') {
82
- untracked.push(file);
83
- continue;
84
- }
85
- if (status.includes('A')) added.push(file);
86
- else if (status.includes('D')) deleted.push(file);
87
- else modified.push(file);
88
- }
89
-
90
- const total = modified.length + added.length + deleted.length + untracked.length;
91
- if (total === 0) return '';
92
- const lines = [`[git status: ${total} file(s)]`];
93
- if (modified.length) lines.push(`modified: ${modified.join(', ')}`);
94
- if (added.length) lines.push(`added: ${added.join(', ')}`);
95
- if (deleted.length) lines.push(`deleted: ${deleted.join(', ')}`);
96
- if (untracked.length) lines.push(`untracked: ${untracked.join(', ')}`);
97
- return lines.join('\n');
98
- }
99
-
100
- function summarizeTestFailure(command, code, stdout, stderr) {
101
- if (classifyCommandIntent(command).kind !== 'test') {
102
- return '';
103
- }
104
- if (Number(code ?? 0) === 0) return '';
105
-
106
- const lines = sanitizePreviewLines([stdout, stderr].filter(Boolean).join('\n'), { maxLineLength: 220 });
107
- const kept = [];
108
-
109
- for (const line of lines) {
110
- if (
111
- /^FAIL\b/.test(line) ||
112
- /^Test Suites:/.test(line) ||
113
- /^Tests:/.test(line) ||
114
- /AssertionError|Error:|Expected|expected .* to /i.test(line) ||
115
- /^\s*at\b/.test(line) ||
116
- /:\d+:\d+\)?$/.test(line)
117
- ) {
118
- kept.push(line);
119
- }
120
- }
121
-
122
- if (kept.length === 0) return '';
123
- return [`[test failure: exit ${code ?? 1}]`, ...kept.slice(0, 8)].join('\n');
124
- }
125
-
126
- function summarizeInstallOutput(command, code, stdout) {
127
- if (classifyCommandIntent(command).kind !== 'install') return '';
128
-
129
- const lines = sanitizePreviewLines(stdout, { maxLineLength: 220 });
130
- const kept = [];
131
- for (const line of lines) {
132
- if (
133
- /\b(?:added|removed|changed|audited) \d+ package/i.test(line) ||
134
- /\bvulnerabilit(?:y|ies)\b/i.test(line) ||
135
- /looking for funding/i.test(line)
136
- ) {
137
- kept.push(line);
138
- }
139
- }
140
- if (kept.length === 0) return '';
141
- return [`[install summary: exit ${code ?? 0}]`, ...kept.slice(0, 6)].join('\n');
142
- }
143
-
144
- function summarizeBuildOutput(command, code, stdout, stderr) {
145
- if (classifyCommandIntent(command).kind !== 'build') return '';
146
- if (Number(code ?? 0) === 0) return '';
147
-
148
- const lines = sanitizePreviewLines([stdout, stderr].filter(Boolean).join('\n'), { maxLineLength: 220 });
149
- const kept = [];
150
- for (const line of lines) {
151
- if (
152
- /\berror\b/i.test(line) ||
153
- /Build failed/i.test(line) ||
154
- /failed with/i.test(line)
155
- ) {
156
- kept.push(line);
157
- }
158
- }
159
- if (kept.length === 0) return '';
160
- return [`[build failure: exit ${code ?? 1}]`, ...kept.slice(0, 8)].join('\n');
161
- }
162
-
163
- export function summarizeRunOutput(result) {
164
- const command = String(result?.command || '').trim();
165
- const stdout = String(result?.stdout || '');
166
- const stderr = String(result?.stderr || '');
167
- const code = result?.code ?? 0;
168
-
169
- if (/^git\s+status\b.*(?:--short|-s)\b/i.test(command)) {
170
- const gitSummary = summarizeGitStatusPorcelain(stdout);
171
- if (gitSummary) return gitSummary;
172
- }
173
-
174
- const installSummary = summarizeInstallOutput(command, code, stdout);
175
- if (installSummary) return installSummary;
176
-
177
- const buildSummary = summarizeBuildOutput(command, code, stdout, stderr);
178
- if (buildSummary) return buildSummary;
179
-
180
- const testSummary = summarizeTestFailure(command, code, stdout, stderr);
181
- if (testSummary) return testSummary;
182
-
183
- return '';
184
- }
1
+ import cliTruncate from 'cli-truncate';
2
+ import stripAnsi from 'strip-ansi';
3
+ import { classifyCommandIntent } from './shell.js';
4
+
5
+ const CONTROL_CHARS_RE = /[\u0000-\u0008\u000B-\u001F\u007F]/g;
6
+
7
+ export function sanitizeTextForModel(
8
+ value,
9
+ {
10
+ maxChars = 0,
11
+ maxLineLength = 220,
12
+ maxConsecutiveBlankLines = 1
13
+ } = {}
14
+ ) {
15
+ if (value == null) return '';
16
+
17
+ const lines = String(value)
18
+ .replace(/\r\n?/g, '\n')
19
+ .split('\n');
20
+ const output = [];
21
+ let blankRun = 0;
22
+
23
+ for (const rawLine of lines) {
24
+ const line = stripAnsi(rawLine).replace(CONTROL_CHARS_RE, '').replace(/[ \t]+$/g, '');
25
+ if (!line.trim()) {
26
+ blankRun += 1;
27
+ if (blankRun > maxConsecutiveBlankLines) continue;
28
+ output.push('');
29
+ continue;
30
+ }
31
+
32
+ blankRun = 0;
33
+ output.push(
34
+ maxLineLength > 0
35
+ ? cliTruncate(line, maxLineLength, { position: 'end' })
36
+ : line
37
+ );
38
+ }
39
+
40
+ let sanitized = output.join('\n').trimEnd();
41
+ if (maxChars > 0 && sanitized.length > maxChars) {
42
+ sanitized = `${sanitized.slice(0, maxChars)}\n... [sanitized output truncated ${sanitized.length - maxChars} chars]`;
43
+ }
44
+ return sanitized;
45
+ }
46
+
47
+ export function getToolOutputSanitizeOptions(toolName) {
48
+ const name = String(toolName || '').trim();
49
+ if (name === 'read' || name === 'read_ast_node' || name === 'run' || name === 'web_fetch') {
50
+ return {
51
+ maxLineLength: 0
52
+ };
53
+ }
54
+ return {};
55
+ }
56
+
57
+ export function sanitizePreviewLines(value, { maxLineLength = 220 } = {}) {
58
+ const sanitized = sanitizeTextForModel(value, {
59
+ maxLineLength,
60
+ maxConsecutiveBlankLines: 0
61
+ });
62
+ if (!sanitized) return [];
63
+ return sanitized
64
+ .split('\n')
65
+ .map((line) => line.trim())
66
+ .filter(Boolean);
67
+ }
68
+
69
+ function summarizeGitStatusPorcelain(stdout) {
70
+ const modified = [];
71
+ const added = [];
72
+ const deleted = [];
73
+ const untracked = [];
74
+
75
+ for (const line of String(stdout || '').split('\n')) {
76
+ const trimmed = line.trimEnd();
77
+ if (!trimmed) continue;
78
+ const status = trimmed.slice(0, 2);
79
+ const file = trimmed.slice(3).trim();
80
+ if (!file) continue;
81
+ if (status === '??') {
82
+ untracked.push(file);
83
+ continue;
84
+ }
85
+ if (status.includes('A')) added.push(file);
86
+ else if (status.includes('D')) deleted.push(file);
87
+ else modified.push(file);
88
+ }
89
+
90
+ const total = modified.length + added.length + deleted.length + untracked.length;
91
+ if (total === 0) return '';
92
+ const lines = [`[git status: ${total} file(s)]`];
93
+ if (modified.length) lines.push(`modified: ${modified.join(', ')}`);
94
+ if (added.length) lines.push(`added: ${added.join(', ')}`);
95
+ if (deleted.length) lines.push(`deleted: ${deleted.join(', ')}`);
96
+ if (untracked.length) lines.push(`untracked: ${untracked.join(', ')}`);
97
+ return lines.join('\n');
98
+ }
99
+
100
+ function summarizeTestFailure(command, code, stdout, stderr) {
101
+ if (classifyCommandIntent(command).kind !== 'test') {
102
+ return '';
103
+ }
104
+ if (Number(code ?? 0) === 0) return '';
105
+
106
+ const lines = sanitizePreviewLines([stdout, stderr].filter(Boolean).join('\n'), { maxLineLength: 220 });
107
+ const kept = [];
108
+
109
+ for (const line of lines) {
110
+ if (
111
+ /^FAIL\b/.test(line) ||
112
+ /^Test Suites:/.test(line) ||
113
+ /^Tests:/.test(line) ||
114
+ /AssertionError|Error:|Expected|expected .* to /i.test(line) ||
115
+ /^\s*at\b/.test(line) ||
116
+ /:\d+:\d+\)?$/.test(line)
117
+ ) {
118
+ kept.push(line);
119
+ }
120
+ }
121
+
122
+ if (kept.length === 0) return '';
123
+ return [`[test failure: exit ${code ?? 1}]`, ...kept.slice(0, 8)].join('\n');
124
+ }
125
+
126
+ function summarizeInstallOutput(command, code, stdout) {
127
+ if (classifyCommandIntent(command).kind !== 'install') return '';
128
+
129
+ const lines = sanitizePreviewLines(stdout, { maxLineLength: 220 });
130
+ const kept = [];
131
+ for (const line of lines) {
132
+ if (
133
+ /\b(?:added|removed|changed|audited) \d+ package/i.test(line) ||
134
+ /\bvulnerabilit(?:y|ies)\b/i.test(line) ||
135
+ /looking for funding/i.test(line)
136
+ ) {
137
+ kept.push(line);
138
+ }
139
+ }
140
+ if (kept.length === 0) return '';
141
+ return [`[install summary: exit ${code ?? 0}]`, ...kept.slice(0, 6)].join('\n');
142
+ }
143
+
144
+ function summarizeBuildOutput(command, code, stdout, stderr) {
145
+ if (classifyCommandIntent(command).kind !== 'build') return '';
146
+ if (Number(code ?? 0) === 0) return '';
147
+
148
+ const lines = sanitizePreviewLines([stdout, stderr].filter(Boolean).join('\n'), { maxLineLength: 220 });
149
+ const kept = [];
150
+ for (const line of lines) {
151
+ if (
152
+ /\berror\b/i.test(line) ||
153
+ /Build failed/i.test(line) ||
154
+ /failed with/i.test(line)
155
+ ) {
156
+ kept.push(line);
157
+ }
158
+ }
159
+ if (kept.length === 0) return '';
160
+ return [`[build failure: exit ${code ?? 1}]`, ...kept.slice(0, 8)].join('\n');
161
+ }
162
+
163
+ export function summarizeRunOutput(result) {
164
+ const command = String(result?.command || '').trim();
165
+ const stdout = String(result?.stdout || '');
166
+ const stderr = String(result?.stderr || '');
167
+ const code = result?.code ?? 0;
168
+
169
+ if (/^git\s+status\b.*(?:--short|-s)\b/i.test(command)) {
170
+ const gitSummary = summarizeGitStatusPorcelain(stdout);
171
+ if (gitSummary) return gitSummary;
172
+ }
173
+
174
+ const installSummary = summarizeInstallOutput(command, code, stdout);
175
+ if (installSummary) return installSummary;
176
+
177
+ const buildSummary = summarizeBuildOutput(command, code, stdout, stderr);
178
+ if (buildSummary) return buildSummary;
179
+
180
+ const testSummary = summarizeTestFailure(command, code, stdout, stderr);
181
+ if (testSummary) return testSummary;
182
+
183
+ return '';
184
+ }