universal-dev-standards 3.4.2 → 3.5.0-beta.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-dev-standards",
3
- "version": "3.4.2",
3
+ "version": "3.5.0-beta.2",
4
4
  "description": "CLI tool for adopting Universal Development Standards",
5
5
  "keywords": [
6
6
  "documentation",
@@ -183,7 +183,8 @@ export async function checkCommand(options = {}) {
183
183
  }
184
184
 
185
185
  // Interactive mode (default when issues detected)
186
- const hasIssues = fileStatus.modified.length > 0 || fileStatus.missing.length > 0;
186
+ const hasIssues = fileStatus.modified.length > 0 ||
187
+ fileStatus.missing.length > 0;
187
188
  if (hasIssues && !options.noInteractive) {
188
189
  await interactiveMode(projectPath, manifest, fileStatus);
189
190
  } else if (hasIssues) {
@@ -210,7 +211,8 @@ export async function checkCommand(options = {}) {
210
211
  displayCoverageReport(manifest);
211
212
 
212
213
  // Final status
213
- const allGood = fileStatus.missing.length === 0 && fileStatus.modified.length === 0;
214
+ const allGood = fileStatus.missing.length === 0 &&
215
+ fileStatus.modified.length === 0;
214
216
  if (allGood) {
215
217
  console.log(chalk.green('✓ Project is compliant with standards'));
216
218
  } else {
@@ -238,22 +240,26 @@ async function interactiveMode(projectPath, manifest, fileStatus) {
238
240
  console.log(chalk.gray('─'.repeat(50)));
239
241
  if (issue.status === 'modified') {
240
242
  console.log(chalk.yellow(`⚠ Modified: ${issue.file}`));
241
- } else {
243
+ } else if (issue.status === 'missing') {
242
244
  console.log(chalk.red(`✗ Missing: ${issue.file}`));
243
245
  }
244
246
 
245
- const choices = issue.status === 'modified'
246
- ? [
247
- { name: 'view - View diff between current and original', value: 'view' },
248
- { name: 'restore - Restore to original version', value: 'restore' },
249
- { name: 'keep - Keep current version (update hash in manifest)', value: 'keep' },
250
- { name: 'skip - Skip this file for now', value: 'skip' }
251
- ]
252
- : [
253
- { name: 'restore - Download and restore file', value: 'restore' },
254
- { name: 'remove - Remove from manifest (no longer track)', value: 'remove' },
255
- { name: 'skip - Skip this file for now', value: 'skip' }
256
- ];
247
+ let choices;
248
+ if (issue.status === 'modified') {
249
+ choices = [
250
+ { name: 'view - View diff between current and original', value: 'view' },
251
+ { name: 'restore - Restore to original version', value: 'restore' },
252
+ { name: 'keep - Keep current version (update hash in manifest)', value: 'keep' },
253
+ { name: 'skip - Skip this file for now', value: 'skip' }
254
+ ];
255
+ } else {
256
+ // missing
257
+ choices = [
258
+ { name: 'restore - Download and restore file', value: 'restore' },
259
+ { name: 'remove - Remove from manifest (no longer track)', value: 'remove' },
260
+ { name: 'skip - Skip this file for now', value: 'skip' }
261
+ ];
262
+ }
257
263
 
258
264
  const { action } = await inquirer.prompt([
259
265
  {
@@ -1,5 +1,5 @@
1
1
  import { createHash } from 'crypto';
2
- import { readFileSync, statSync, existsSync } from 'fs';
2
+ import { readFileSync, statSync, existsSync, readdirSync } from 'fs';
3
3
  import { join } from 'path';
4
4
 
5
5
  /**
@@ -146,3 +146,74 @@ export function getFileStatusSummary(projectPath, manifest) {
146
146
 
147
147
  return summary;
148
148
  }
149
+
150
+ /**
151
+ * Recursively scan directory for all files
152
+ * @param {string} dirPath - Directory to scan
153
+ * @param {string} basePath - Base path for relative path calculation
154
+ * @returns {string[]} Array of relative paths
155
+ */
156
+ function scanDirectory(dirPath, basePath) {
157
+ const files = [];
158
+ const items = readdirSync(dirPath, { withFileTypes: true });
159
+
160
+ for (const item of items) {
161
+ const fullPath = join(dirPath, item.name);
162
+ // Calculate relative path by removing basePath prefix
163
+ const relativePath = fullPath.slice(basePath.length + 1);
164
+
165
+ if (item.isDirectory()) {
166
+ files.push(...scanDirectory(fullPath, basePath));
167
+ } else if (item.isFile()) {
168
+ files.push(relativePath);
169
+ }
170
+ }
171
+
172
+ return files;
173
+ }
174
+
175
+ /**
176
+ * Scan for untracked files in .standards/ and integration locations
177
+ * @param {string} projectPath - Project root path
178
+ * @param {Object} manifest - Manifest object
179
+ * @returns {string[]} Array of relative paths to untracked files
180
+ */
181
+ export function scanForUntrackedFiles(projectPath, manifest) {
182
+ const untracked = [];
183
+ const trackedPaths = new Set(Object.keys(manifest.fileHashes || {}));
184
+
185
+ // 1. Scan .standards/ directory (excluding manifest.json)
186
+ const standardsDir = join(projectPath, '.standards');
187
+ if (existsSync(standardsDir)) {
188
+ const standardsFiles = scanDirectory(standardsDir, projectPath);
189
+ for (const relPath of standardsFiles) {
190
+ // Skip manifest.json itself
191
+ if (relPath === '.standards/manifest.json' ||
192
+ relPath === '.standards\\manifest.json') {
193
+ continue;
194
+ }
195
+ if (!trackedPaths.has(relPath)) {
196
+ untracked.push(relPath);
197
+ }
198
+ }
199
+ }
200
+
201
+ // 2. Scan for known integration files in project root
202
+ const knownIntegrations = [
203
+ '.cursorrules',
204
+ '.windsurfrules',
205
+ '.clinerules',
206
+ '.github/copilot-instructions.md',
207
+ 'CLAUDE.md',
208
+ 'INSTRUCTIONS.md'
209
+ ];
210
+
211
+ for (const intFile of knownIntegrations) {
212
+ const fullPath = join(projectPath, intFile);
213
+ if (existsSync(fullPath) && !trackedPaths.has(intFile)) {
214
+ untracked.push(intFile);
215
+ }
216
+ }
217
+
218
+ return untracked;
219
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "version": "3.4.2",
4
- "lastUpdated": "2026-01-07",
3
+ "version": "3.5.0-beta.1",
4
+ "lastUpdated": "2026-01-09",
5
5
  "description": "Standards registry for universal-dev-standards with integrated skills and AI-optimized formats",
6
6
  "formats": {
7
7
  "ai": {
@@ -55,7 +55,7 @@
55
55
  "url": "https://github.com/AsiaOstrich/universal-dev-standards",
56
56
  "localPath": "skills/claude-code",
57
57
  "rawUrl": "https://raw.githubusercontent.com/AsiaOstrich/universal-dev-standards/main/skills/claude-code",
58
- "version": "3.4.2",
58
+ "version": "3.5.0-beta.1",
59
59
  "note": "Skills are now included in the main repository under skills/"
60
60
  }
61
61
  },