@nolrm/contextkit 0.13.5 → 0.14.0

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.
@@ -1,6 +1,5 @@
1
1
  const chalk = require('chalk');
2
2
  const fs = require('fs-extra');
3
- const path = require('path');
4
3
 
5
4
  class NoteCommand {
6
5
  constructor() {
@@ -14,7 +13,7 @@ class NoteCommand {
14
13
  return;
15
14
  }
16
15
 
17
- if (!await fs.pathExists(this.correctionsPath)) {
16
+ if (!(await fs.pathExists(this.correctionsPath))) {
18
17
  console.log(chalk.red('❌ Corrections log not found'));
19
18
  console.log(chalk.yellow(' Run: contextkit install'));
20
19
  return;
@@ -23,48 +22,42 @@ class NoteCommand {
23
22
  try {
24
23
  const content = await fs.readFile(this.correctionsPath, 'utf-8');
25
24
  const today = new Date().toISOString().split('T')[0];
26
-
25
+
27
26
  // Find or create today's session
28
27
  const sessionHeader = `### ${today} - ${options.task || 'Development Session'}`;
29
-
28
+
30
29
  let updatedContent = content;
31
-
30
+
32
31
  // Check if today's session exists
33
32
  if (content.includes(sessionHeader)) {
34
33
  // Add to existing session
35
34
  const category = options.category || 'AI Behavior';
36
35
  const priority = options.priority || 'MEDIUM';
37
36
  const note = `- ${category} | ${message} [${priority}]`;
38
-
37
+
39
38
  // Find the session and add note to appropriate section
40
39
  const sections = ['Rule Updates', 'AI Behavior', 'Preferences', 'Trend Indicators'];
41
40
  let sectionFound = false;
42
-
41
+
43
42
  for (const section of sections) {
44
43
  if (category.toLowerCase().includes(section.toLowerCase().substring(0, 5))) {
45
44
  const sectionHeader = `#### ${section}`;
46
45
  const sectionRegex = new RegExp(`(${sectionHeader}[\\s\\S]*?)(?=####|###|##|$)`, 'm');
47
46
  const match = content.match(sectionRegex);
48
-
47
+
49
48
  if (match) {
50
- updatedContent = content.replace(
51
- sectionRegex,
52
- `$1\n${note}`
53
- );
49
+ updatedContent = content.replace(sectionRegex, `$1\n${note}`);
54
50
  sectionFound = true;
55
51
  break;
56
52
  }
57
53
  }
58
54
  }
59
-
55
+
60
56
  if (!sectionFound) {
61
57
  // Add to AI Behavior section as default
62
58
  const aiBehaviorRegex = /(#### AI Behavior[\s\S]*?)(?=####|###|##|$)/m;
63
59
  if (content.match(aiBehaviorRegex)) {
64
- updatedContent = content.replace(
65
- aiBehaviorRegex,
66
- `$1\n${note}`
67
- );
60
+ updatedContent = content.replace(aiBehaviorRegex, `$1\n${note}`);
68
61
  }
69
62
  }
70
63
  } else {
@@ -91,7 +84,7 @@ ${sessionHeader}
91
84
  - [No trends yet]
92
85
 
93
86
  `;
94
-
87
+
95
88
  // Insert after "## Recent Sessions"
96
89
  const sessionsRegex = /(## Recent Sessions\n)/;
97
90
  if (content.match(sessionsRegex)) {
@@ -101,7 +94,7 @@ ${sessionHeader}
101
94
  updatedContent = `## Recent Sessions${newSession}\n${content}`;
102
95
  }
103
96
  }
104
-
97
+
105
98
  await fs.writeFile(this.correctionsPath, updatedContent);
106
99
  console.log(chalk.green('✅ Note added to corrections log'));
107
100
  console.log(chalk.dim(` ${message}`));
@@ -117,4 +110,3 @@ async function note(message, options) {
117
110
  }
118
111
 
119
112
  module.exports = note;
120
-
@@ -1,7 +1,5 @@
1
1
  const chalk = require('chalk');
2
2
  const fs = require('fs-extra');
3
- const path = require('path');
4
- const ora = require('ora');
5
3
 
6
4
  class RunCommand {
7
5
  constructor() {
@@ -18,7 +16,7 @@ class RunCommand {
18
16
  const possiblePaths = [
19
17
  `.contextkit/instructions/core/${workflowName}.md`,
20
18
  `.contextkit/instructions/${workflowName}.md`,
21
- `.contextkit/commands/${workflowName}.md`
19
+ `.contextkit/commands/${workflowName}.md`,
22
20
  ];
23
21
 
24
22
  let workflowPath = null;
@@ -32,7 +30,7 @@ class RunCommand {
32
30
  if (!workflowPath) {
33
31
  console.log(chalk.red(`❌ Workflow not found: ${workflowName}`));
34
32
  console.log(chalk.yellow(' Searched in:'));
35
- possiblePaths.forEach(p => console.log(chalk.dim(` - ${p}`)));
33
+ possiblePaths.forEach((p) => console.log(chalk.dim(` - ${p}`)));
36
34
  return;
37
35
  }
38
36
 
@@ -41,7 +39,7 @@ class RunCommand {
41
39
 
42
40
  // Parse workflow
43
41
  const parsed = this.parseWorkflow(this.workflowContent);
44
-
42
+
45
43
  if (!parsed) {
46
44
  console.log(chalk.red('❌ Failed to parse workflow'));
47
45
  return;
@@ -55,15 +53,15 @@ class RunCommand {
55
53
  // Execute workflow steps
56
54
  if (parsed.steps && parsed.steps.length > 0) {
57
55
  console.log(chalk.blue(`\n📋 Executing ${parsed.steps.length} step(s)...\n`));
58
-
56
+
59
57
  for (let i = 0; i < parsed.steps.length; i++) {
60
58
  const step = parsed.steps[i];
61
59
  this.currentStep = i + 1;
62
-
60
+
63
61
  console.log(chalk.cyan(`\n${'─'.repeat(60)}`));
64
62
  console.log(chalk.bold(`Step ${step.number}: ${step.name || 'Unnamed Step'}`));
65
63
  console.log(chalk.cyan(`${'─'.repeat(60)}\n`));
66
-
64
+
67
65
  await this.executeStep(step, options);
68
66
  }
69
67
  }
@@ -80,7 +78,7 @@ class RunCommand {
80
78
  const result = {
81
79
  preFlight: null,
82
80
  steps: [],
83
- postFlight: null
81
+ postFlight: null,
84
82
  };
85
83
 
86
84
  // Extract pre-flight
@@ -93,17 +91,18 @@ class RunCommand {
93
91
  const processFlowMatch = content.match(/<process_flow>([\s\S]*?)<\/process_flow>/);
94
92
  if (processFlowMatch) {
95
93
  const processFlow = processFlowMatch[1];
96
-
94
+
97
95
  // Extract all steps
98
- const stepRegex = /<step\s+number="(\d+)"(?:\s+subagent="([^"]+)")?(?:\s+name="([^"]+)")?>([\s\S]*?)<\/step>/g;
96
+ const stepRegex =
97
+ /<step\s+number="(\d+)"(?:\s+subagent="([^"]+)")?(?:\s+name="([^"]+)")?>([\s\S]*?)<\/step>/g;
99
98
  let stepMatch;
100
-
99
+
101
100
  while ((stepMatch = stepRegex.exec(processFlow)) !== null) {
102
101
  result.steps.push({
103
102
  number: parseInt(stepMatch[1]),
104
103
  subagent: stepMatch[2] || null,
105
104
  name: stepMatch[3] || null,
106
- content: stepMatch[4].trim()
105
+ content: stepMatch[4].trim(),
107
106
  });
108
107
  }
109
108
  }
@@ -119,12 +118,12 @@ class RunCommand {
119
118
 
120
119
  async executePreFlight(preFlightContent) {
121
120
  console.log(chalk.blue('🔍 Pre-flight checks...\n'));
122
-
121
+
123
122
  // Check for EXECUTE directive
124
123
  const executeMatch = preFlightContent.match(/EXECUTE:\s*(.+)/);
125
124
  if (executeMatch) {
126
125
  const filePath = executeMatch[1].trim().replace('@.contextkit/', '.contextkit/');
127
-
126
+
128
127
  if (await fs.pathExists(filePath)) {
129
128
  const preFlightFile = await fs.readFile(filePath, 'utf-8');
130
129
  console.log(chalk.dim(preFlightFile));
@@ -151,7 +150,7 @@ class RunCommand {
151
150
 
152
151
  // Extract instructions from step content
153
152
  const instructions = this.extractInstructions(step.content);
154
-
153
+
155
154
  // For now, display instructions and wait for user/AI to execute
156
155
  if (instructions.length > 0) {
157
156
  console.log(chalk.blue('📝 Instructions to execute:'));
@@ -167,7 +166,7 @@ class RunCommand {
167
166
  if (options.interactive) {
168
167
  const readline = require('readline').createInterface({
169
168
  input: process.stdin,
170
- output: process.stdout
169
+ output: process.stdout,
171
170
  });
172
171
 
173
172
  return new Promise((resolve) => {
@@ -181,7 +180,7 @@ class RunCommand {
181
180
 
182
181
  extractInstructions(content) {
183
182
  const instructions = [];
184
-
183
+
185
184
  // Extract ACTION directives
186
185
  const actionMatches = content.matchAll(/ACTION:\s*(.+)/gi);
187
186
  for (const match of actionMatches) {
@@ -199,17 +198,17 @@ class RunCommand {
199
198
 
200
199
  async executePostFlight(postFlightContent) {
201
200
  console.log(chalk.blue('\n🔍 Post-flight checks...\n'));
202
-
201
+
203
202
  // Check for EXECUTE directive
204
203
  const executeMatch = postFlightContent.match(/EXECUTE:\s*(.+)/);
205
204
  if (executeMatch) {
206
205
  const filePath = executeMatch[1].trim().replace('@.contextkit/', '.contextkit/');
207
-
206
+
208
207
  if (await fs.pathExists(filePath)) {
209
208
  const postFlightFile = await fs.readFile(filePath, 'utf-8');
210
209
  console.log(chalk.dim(postFlightFile));
211
210
  console.log('');
212
-
211
+
213
212
  // Check for corrections log update instructions
214
213
  if (postFlightFile.includes('corrections log')) {
215
214
  console.log(chalk.yellow('💡 Remember to update corrections.md if any issues occurred'));
@@ -229,4 +228,3 @@ async function run(workflowName, options) {
229
228
  }
230
229
 
231
230
  module.exports = run;
232
-
@@ -1,5 +1,4 @@
1
1
  const chalk = require('chalk');
2
- const ora = require('ora');
3
2
  const fs = require('fs-extra');
4
3
  const path = require('path');
5
4
  const StatusManager = require('../utils/status-manager');
@@ -11,49 +10,59 @@ class StatusCommand {
11
10
  }
12
11
 
13
12
  async status() {
14
- if (!await fs.pathExists(this.configPath)) {
13
+ if (!(await fs.pathExists(this.configPath))) {
15
14
  console.log(chalk.red('❌ ContextKit is not installed in this project'));
16
15
  console.log(chalk.yellow('💡 Run: contextkit install'));
17
16
  return;
18
17
  }
19
18
 
20
19
  try {
21
- const config = await this.parseConfig();
22
- const projectType = await this.detectProjectType();
23
- const packageManager = await this.detectPackageManager();
20
+ const _config = await this.parseConfig();
21
+ const _projectType = await this.detectProjectType();
22
+ const _packageManager = await this.detectPackageManager();
24
23
  const status = await this.statusManager.getStatus();
25
24
  const analyzeInfo = await this.statusManager.getAnalyzeInfo();
26
25
 
27
26
  console.log(chalk.green('🎵 ContextKit Status'));
28
27
  console.log('');
29
-
28
+
30
29
  console.log(chalk.blue('📦 Installation:'));
31
30
  console.log(` Version: ${status.version}`);
32
31
  console.log(` Installed: ${new Date(status.installed_at).toLocaleDateString()}`);
33
32
  console.log(` Last Updated: ${new Date(status.last_updated).toLocaleDateString()}`);
34
33
  console.log('');
35
-
34
+
36
35
  console.log(chalk.blue('🔍 Analysis:'));
37
36
  if (analyzeInfo.isFirstTime) {
38
37
  console.log(chalk.yellow(' Status: Not analyzed'));
39
- console.log(chalk.blue(' Recommendation: Run @.contextkit/commands/analyze.md to customize standards'));
38
+ console.log(
39
+ chalk.blue(
40
+ ' Recommendation: Run @.contextkit/commands/analyze.md to customize standards'
41
+ )
42
+ );
40
43
  } else {
41
- console.log(chalk.green(` Status: Completed (${new Date(analyzeInfo.lastRun).toLocaleDateString()})`));
44
+ console.log(
45
+ chalk.green(
46
+ ` Status: Completed (${new Date(analyzeInfo.lastRun).toLocaleDateString()})`
47
+ )
48
+ );
42
49
  console.log(chalk.blue(` Project: ${analyzeInfo.projectType || 'Unknown'}`));
43
50
  console.log(chalk.blue(` Package Manager: ${analyzeInfo.packageManager || 'Unknown'}`));
44
51
  if (analyzeInfo.customizations.length > 0) {
45
- console.log(chalk.blue(` Customizations: ${analyzeInfo.customizations.length} applied`));
52
+ console.log(
53
+ chalk.blue(` Customizations: ${analyzeInfo.customizations.length} applied`)
54
+ );
46
55
  }
47
56
  }
48
57
  console.log('');
49
-
58
+
50
59
  console.log(chalk.blue('✅ Features:'));
51
60
  console.log(` Pre-push hook: ${status.features.pre_push_hook ? '✅' : '❌'}`);
52
61
  console.log(` Commit-msg hook: ${status.features.commit_msg_hook ? '✅' : '❌'}`);
53
62
  console.log(` Standards: ${status.features.standards ? '✅' : '❌'}`);
54
63
  console.log(` Templates: ${status.features.templates ? '✅' : '❌'}`);
55
64
  console.log('');
56
-
65
+
57
66
  // Check context files
58
67
  console.log(chalk.blue('📚 Context Files (Loaded with ck "prompt"):'));
59
68
  const contextFiles = await this.checkContextFiles();
@@ -63,7 +72,7 @@ class StatusCommand {
63
72
  console.log(` architecture.md: ${contextFiles.architecture ? '✅' : '❌'}`);
64
73
  console.log(` ai-guidelines.md: ${contextFiles.guidelines ? '✅' : '❌'}`);
65
74
  console.log(` glossary.md: ${contextFiles.glossary ? '✅' : '❌'}`);
66
-
75
+
67
76
  if (contextFiles.allPresent) {
68
77
  console.log(chalk.green('\n✅ All context files ready for AI prompts!'));
69
78
  } else {
@@ -86,7 +95,6 @@ class StatusCommand {
86
95
  } else {
87
96
  console.log(chalk.green('✅ ContextKit is up to date'));
88
97
  }
89
-
90
98
  } catch (error) {
91
99
  console.log(chalk.red('❌ Error reading ContextKit configuration:'), error.message);
92
100
  }
@@ -95,7 +103,7 @@ class StatusCommand {
95
103
  async parseConfig() {
96
104
  const configContent = await fs.readFile(this.configPath, 'utf8');
97
105
  const config = {};
98
-
106
+
99
107
  // Simple YAML parsing for our config format
100
108
  const lines = configContent.split('\n');
101
109
  for (const line of lines) {
@@ -144,7 +152,10 @@ class StatusCommand {
144
152
  return 'react';
145
153
  } else if (packageJson.dependencies?.vue || packageJson.devDependencies?.vue) {
146
154
  return 'vue';
147
- } else if (packageJson.dependencies?.['@angular/core'] || packageJson.devDependencies?.['@angular/core']) {
155
+ } else if (
156
+ packageJson.dependencies?.['@angular/core'] ||
157
+ packageJson.devDependencies?.['@angular/core']
158
+ ) {
148
159
  return 'angular';
149
160
  } else if (packageJson.dependencies?.next || packageJson.devDependencies?.next) {
150
161
  return 'nextjs';
@@ -154,7 +165,10 @@ class StatusCommand {
154
165
  return 'svelte';
155
166
  }
156
167
  return 'node';
157
- } else if (await fs.pathExists('requirements.txt') || await fs.pathExists('pyproject.toml')) {
168
+ } else if (
169
+ (await fs.pathExists('requirements.txt')) ||
170
+ (await fs.pathExists('pyproject.toml'))
171
+ ) {
158
172
  return 'python';
159
173
  } else if (await fs.pathExists('Cargo.toml')) {
160
174
  return 'rust';
@@ -180,24 +194,27 @@ class StatusCommand {
180
194
  async checkForUpdates(currentVersion) {
181
195
  try {
182
196
  const axios = require('axios');
183
- const response = await axios.get('https://api.github.com/repos/nolrm/contextkit/releases/latest', {
184
- timeout: 5000
185
- });
186
-
197
+ const response = await axios.get(
198
+ 'https://api.github.com/repos/nolrm/contextkit/releases/latest',
199
+ {
200
+ timeout: 5000,
201
+ }
202
+ );
203
+
187
204
  const latestVersion = response.data.tag_name.replace('v', '');
188
205
  const hasUpdate = this.isNewerVersion(latestVersion, currentVersion);
189
-
206
+
190
207
  return {
191
208
  hasUpdate,
192
209
  currentVersion,
193
- latestVersion
210
+ latestVersion,
194
211
  };
195
212
  } catch (error) {
196
213
  return {
197
214
  hasUpdate: false,
198
215
  currentVersion,
199
216
  latestVersion: 'unknown',
200
- error: error.message
217
+ error: error.message,
201
218
  };
202
219
  }
203
220
  }
@@ -205,15 +222,15 @@ class StatusCommand {
205
222
  isNewerVersion(latest, current) {
206
223
  const latestParts = latest.split('.').map(Number);
207
224
  const currentParts = current.split('.').map(Number);
208
-
225
+
209
226
  for (let i = 0; i < Math.max(latestParts.length, currentParts.length); i++) {
210
227
  const latestPart = latestParts[i] || 0;
211
228
  const currentPart = currentParts[i] || 0;
212
-
229
+
213
230
  if (latestPart > currentPart) return true;
214
231
  if (latestPart < currentPart) return false;
215
232
  }
216
-
233
+
217
234
  return false;
218
235
  }
219
236
 
@@ -228,11 +245,17 @@ class StatusCommand {
228
245
  if (allFiles.length === 0) continue;
229
246
 
230
247
  if (result.valid) {
231
- console.log(` ${integration.displayName}: ${chalk.green('✅')} (${result.present.length} files)`);
248
+ console.log(
249
+ ` ${integration.displayName}: ${chalk.green('✅')} (${result.present.length} files)`
250
+ );
232
251
  } else if (result.present.length > 0) {
233
- console.log(` ${integration.displayName}: ${chalk.yellow('⚠️')} (${result.present.length}/${allFiles.length} files)`);
252
+ console.log(
253
+ ` ${integration.displayName}: ${chalk.yellow('⚠️')} (${result.present.length}/${allFiles.length} files)`
254
+ );
234
255
  } else {
235
- console.log(` ${integration.displayName}: ${chalk.dim('not installed')} → run: ck ${name}`);
256
+ console.log(
257
+ ` ${integration.displayName}: ${chalk.dim('not installed')} → run: ck ${name}`
258
+ );
236
259
  }
237
260
  }
238
261
  }
@@ -244,10 +267,16 @@ class StatusCommand {
244
267
  testing: await fs.pathExists('.contextkit/standards/testing.md'),
245
268
  architecture: await fs.pathExists('.contextkit/standards/architecture.md'),
246
269
  guidelines: await fs.pathExists('.contextkit/standards/ai-guidelines.md'),
247
- glossary: await fs.pathExists('.contextkit/standards/glossary.md')
270
+ glossary: await fs.pathExists('.contextkit/standards/glossary.md'),
248
271
  };
249
272
 
250
- checks.allPresent = checks.context && checks.codeStyle && checks.testing && checks.architecture && checks.guidelines && checks.glossary;
273
+ checks.allPresent =
274
+ checks.context &&
275
+ checks.codeStyle &&
276
+ checks.testing &&
277
+ checks.architecture &&
278
+ checks.guidelines &&
279
+ checks.glossary;
251
280
 
252
281
  return checks;
253
282
  }