@nqlib/nqui 0.5.3 → 0.5.4
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/dist/styles.css +3 -11
- package/docs/nqui-skills/SKILL.md +3 -8
- package/package.json +1 -1
- package/scripts/publish-npmjs.js +147 -99
package/dist/styles.css
CHANGED
|
@@ -792,14 +792,11 @@
|
|
|
792
792
|
nqui Additional System Variables
|
|
793
793
|
============================================ */
|
|
794
794
|
|
|
795
|
-
/*
|
|
796
|
-
|
|
795
|
+
/* Default light theme variables (.mid / .dark blocks follow) */
|
|
796
|
+
/* ============================================
|
|
797
797
|
nqui Color System & Design Tokens
|
|
798
798
|
============================================ */
|
|
799
799
|
|
|
800
|
-
:root + html.light = warm paper; html.mid = separate token block (showcase / comparison).
|
|
801
|
-
* Dark = .dark. Showcase app uses next-themes classes light | mid | dark.
|
|
802
|
-
*/
|
|
803
800
|
:root {
|
|
804
801
|
/* ============================================
|
|
805
802
|
Z-Index Elevation Scale
|
|
@@ -1205,9 +1202,4 @@
|
|
|
1205
1202
|
--sidebar-accent-foreground: oklch(0.92 0 0);
|
|
1206
1203
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
1207
1204
|
--sidebar-ring: oklch(0.556 0 0);
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
/*
|
|
1211
|
-
* html.light — next-themes; surface tokens match :root (warm paper).
|
|
1212
|
-
* html.mid — next-themes; surfaces use .mid block above (distinct from light).
|
|
1213
|
-
*/
|
|
1205
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
## name: nqui
|
|
4
|
-
|
|
2
|
+
name: nqui
|
|
5
3
|
description: Hub for nqui component library skills and impeccable design skills. Use /nqui-components, /nqui-design-system, /impeccable, /audit, or specific skill names to invoke them.
|
|
4
|
+
---
|
|
6
5
|
|
|
7
6
|
# nqui Skills (Hub)
|
|
8
7
|
|
|
@@ -14,7 +13,6 @@ Installed into `.cursor/nqui-skills/` via `npx @nqlib/nqui init-skills`.
|
|
|
14
13
|
|
|
15
14
|
## nqui Component Library
|
|
16
15
|
|
|
17
|
-
|
|
18
16
|
| Skill | When to use |
|
|
19
17
|
| ------------------------------- | ------------------------------------------------------------------ |
|
|
20
18
|
| **nqui-components** | Implementing UI, choosing components, component props and examples |
|
|
@@ -24,14 +22,12 @@ Installed into `.cursor/nqui-skills/` via `npx @nqlib/nqui init-skills`.
|
|
|
24
22
|
| **nqui-bundle-size** | Bundle size best practices when adding deps or creating packages |
|
|
25
23
|
| **nqui-local-published-toggle** | Switching between local and published @nqlib/nqui |
|
|
26
24
|
|
|
27
|
-
|
|
28
25
|
---
|
|
29
26
|
|
|
30
27
|
## Impeccable Design Skills
|
|
31
28
|
|
|
32
29
|
Design quality and anti-pattern detection. Run `/impeccable teach` first to establish design context.
|
|
33
30
|
|
|
34
|
-
|
|
35
31
|
| Skill | When to use |
|
|
36
32
|
| -------------- | ----------------------------------------------------------------------------- |
|
|
37
33
|
| **impeccable** | Build distinctive, production-grade UI; avoid AI slop aesthetics |
|
|
@@ -52,7 +48,6 @@ Design quality and anti-pattern detection. Run `/impeccable teach` first to esta
|
|
|
52
48
|
| **/critique** | Heuristic-based UI review |
|
|
53
49
|
| **/overdrive** | Push good UI to excellent |
|
|
54
50
|
|
|
55
|
-
|
|
56
51
|
---
|
|
57
52
|
|
|
58
53
|
## Usage
|
|
@@ -62,4 +57,4 @@ Skills are invoked by name — e.g. `/nqui-components`, `/impeccable`, `/audit i
|
|
|
62
57
|
For component questions, always read the relevant doc first:
|
|
63
58
|
|
|
64
59
|
- `.cursor/nqui-skills/components/nqui-<name>.md` (after init-skills)
|
|
65
|
-
- `node_modules/@nqlib/nqui/docs/components/nqui-<name>.md` (npm install)
|
|
60
|
+
- `node_modules/@nqlib/nqui/docs/components/nqui-<name>.md` (npm install)
|
package/package.json
CHANGED
package/scripts/publish-npmjs.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
9
|
-
import { execSync } from 'child_process';
|
|
9
|
+
import { execSync, spawn } from 'child_process';
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
11
|
import { dirname, join } from 'path';
|
|
12
12
|
|
|
@@ -16,116 +16,164 @@ const rootDir = join(__dirname, '..');
|
|
|
16
16
|
const packageJsonPath = join(rootDir, 'package.json');
|
|
17
17
|
const npmrcPath = join(rootDir, '.npmrc');
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
function printSslTroubleshooting() {
|
|
20
|
+
console.error(`
|
|
21
|
+
💡 TLS / network (e.g. ERR_SSL_SSL\\TLS_ALERT_BAD_RECORD_MAC) is usually environmental:
|
|
22
|
+
• Run publish again; transient failures often work on a second attempt
|
|
23
|
+
• Disable VPN or try another network; corporate proxies and inspection break TLS
|
|
24
|
+
• Update Node LTS; ensure no antivirus is MITM’ing npm traffic
|
|
25
|
+
• Retry later if registry.npmjs.com is flaking
|
|
26
|
+
• Set NPM_PUBLISH_RETRIES=5 for more attempts (default 3)
|
|
27
|
+
`);
|
|
28
|
+
}
|
|
21
29
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
30
|
+
async function main() {
|
|
31
|
+
// Read package.json
|
|
32
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
25
33
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
for (const name of workspaceDeps) {
|
|
30
|
-
if (packageJson.dependencies?.[name] === 'workspace:*') {
|
|
31
|
-
delete packageJson.dependencies[name];
|
|
32
|
-
console.log(` Removed ${name} (workspace dep)`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
34
|
+
// Save originals for restore
|
|
35
|
+
const originalPublishConfig = packageJson.publishConfig;
|
|
36
|
+
const originalDependencies = { ...packageJson.dependencies };
|
|
35
37
|
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// Write modified package.json
|
|
43
|
-
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
44
|
-
|
|
45
|
-
// Handle .npmrc file if it exists
|
|
46
|
-
let originalNpmrc = null;
|
|
47
|
-
let npmrcExists = false;
|
|
48
|
-
|
|
49
|
-
if (existsSync(npmrcPath)) {
|
|
50
|
-
npmrcExists = true;
|
|
51
|
-
originalNpmrc = readFileSync(npmrcPath, 'utf-8');
|
|
52
|
-
|
|
53
|
-
// Remove or comment out scoped registry line that points to GitHub Packages
|
|
54
|
-
const lines = originalNpmrc.split('\n');
|
|
55
|
-
const modifiedLines = lines.map(line => {
|
|
56
|
-
// Comment out scoped registry lines for @nqlib
|
|
57
|
-
if (line.trim().startsWith('@nqlib:registry=')) {
|
|
58
|
-
return `# ${line} # Temporarily disabled for npmjs.com publish`;
|
|
38
|
+
// Remove workspace:* deps (npm doesn't support workspace: protocol).
|
|
39
|
+
const workspaceDeps = ['@nqlib/nqcode', '@nqlib/nqappbuilder'];
|
|
40
|
+
for (const name of workspaceDeps) {
|
|
41
|
+
if (packageJson.dependencies?.[name] === 'workspace:*') {
|
|
42
|
+
delete packageJson.dependencies[name];
|
|
43
|
+
console.log(` Removed ${name} (workspace dep)`);
|
|
59
44
|
}
|
|
60
|
-
|
|
61
|
-
});
|
|
45
|
+
}
|
|
62
46
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
47
|
+
packageJson.publishConfig = {
|
|
48
|
+
registry: 'https://registry.npmjs.com',
|
|
49
|
+
access: 'public',
|
|
50
|
+
};
|
|
66
51
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
52
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
53
|
+
|
|
54
|
+
let originalNpmrc = null;
|
|
55
|
+
let npmrcExists = false;
|
|
56
|
+
|
|
57
|
+
if (existsSync(npmrcPath)) {
|
|
58
|
+
npmrcExists = true;
|
|
59
|
+
originalNpmrc = readFileSync(npmrcPath, 'utf-8');
|
|
60
|
+
const lines = originalNpmrc.split('\n');
|
|
61
|
+
const modifiedLines = lines.map((line) => {
|
|
62
|
+
if (line.trim().startsWith('@nqlib:registry=')) {
|
|
63
|
+
return `# ${line} # Temporarily disabled for npmjs.com publish`;
|
|
77
64
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
console.
|
|
82
|
-
console.error('💡 Please run: npm login --registry=https://registry.npmjs.com');
|
|
83
|
-
console.error('💡 Or create an access token at: https://www.npmjs.com/settings/YOUR_USERNAME/tokens');
|
|
84
|
-
throw new Error('Authentication required. Please login to npmjs.com first.');
|
|
65
|
+
return line;
|
|
66
|
+
});
|
|
67
|
+
writeFileSync(npmrcPath, modifiedLines.join('\n'));
|
|
68
|
+
console.log('📝 Temporarily modified .npmrc');
|
|
85
69
|
}
|
|
86
70
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
71
|
+
try {
|
|
72
|
+
console.log('🔐 Checking npm authentication...');
|
|
73
|
+
try {
|
|
74
|
+
const whoami = execSync('npm whoami --registry=https://registry.npmjs.com', {
|
|
75
|
+
encoding: 'utf-8',
|
|
76
|
+
cwd: rootDir,
|
|
77
|
+
env: {
|
|
78
|
+
...process.env,
|
|
79
|
+
npm_config_registry: 'https://registry.npmjs.com',
|
|
80
|
+
},
|
|
81
|
+
}).trim();
|
|
82
|
+
console.log(`✅ Logged in as: ${whoami}`);
|
|
83
|
+
} catch {
|
|
84
|
+
console.error('❌ Not logged in to npmjs.com');
|
|
85
|
+
console.error('💡 Please run: npm login --registry=https://registry.npmjs.com');
|
|
86
|
+
console.error(
|
|
87
|
+
'💡 Or create an access token at: https://www.npmjs.com/settings/YOUR_USERNAME/tokens'
|
|
88
|
+
);
|
|
89
|
+
throw new Error('Authentication required. Please login to npmjs.com first.');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const publishEnv = {
|
|
92
93
|
...process.env,
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
npm_config_registry: 'https://registry.npmjs.com',
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const maxAttempts = Math.min(
|
|
98
|
+
5,
|
|
99
|
+
Math.max(1, parseInt(process.env.NPM_PUBLISH_RETRIES || '3', 10) || 3)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const runPublish = () =>
|
|
103
|
+
new Promise((resolve, reject) => {
|
|
104
|
+
const child = spawn(
|
|
105
|
+
'npm',
|
|
106
|
+
['publish', '--registry=https://registry.npmjs.com', '--access', 'public'],
|
|
107
|
+
{ stdio: 'inherit', cwd: rootDir, env: publishEnv, shell: false }
|
|
108
|
+
);
|
|
109
|
+
child.on('error', reject);
|
|
110
|
+
child.on('close', (code) => {
|
|
111
|
+
if (code === 0) resolve();
|
|
112
|
+
else {
|
|
113
|
+
const err = new Error(`npm publish exited with code ${code}`);
|
|
114
|
+
err.status = code;
|
|
115
|
+
reject(err);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
console.log('📦 Publishing to npmjs.com...');
|
|
121
|
+
let lastError;
|
|
122
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
123
|
+
try {
|
|
124
|
+
await runPublish();
|
|
125
|
+
lastError = null;
|
|
126
|
+
break;
|
|
127
|
+
} catch (e) {
|
|
128
|
+
lastError = e;
|
|
129
|
+
if (attempt < maxAttempts) {
|
|
130
|
+
const wait = attempt * 2000;
|
|
131
|
+
console.warn(
|
|
132
|
+
`⚠️ Publish failed (attempt ${attempt}/${maxAttempts}). Retrying in ${wait / 1000}s (transient TLS/network often succeeds on retry)…`
|
|
133
|
+
);
|
|
134
|
+
await new Promise((r) => setTimeout(r, wait));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
95
137
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
} catch (error) {
|
|
99
|
-
|
|
100
|
-
|
|
138
|
+
if (lastError) throw lastError;
|
|
139
|
+
console.log('✅ Published to npmjs.com successfully!');
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error('❌ Failed to publish to npmjs.com');
|
|
142
|
+
if (error.message && error.message.includes('Authentication required')) {
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
const errText = `${error.message || ''} ${(error.output && error.output.toString()) || ''}`;
|
|
146
|
+
if (error.status === 404 || errText.includes('404')) {
|
|
147
|
+
console.error('💡 Package not found. This might be the first publish.');
|
|
148
|
+
console.error('💡 Make sure the @nqlib scope exists on npmjs.com');
|
|
149
|
+
console.error('💡 For scoped packages, you need to own the scope or be added to it');
|
|
150
|
+
}
|
|
151
|
+
if (error.status === 401 || errText.includes('401')) {
|
|
152
|
+
console.error(
|
|
153
|
+
'💡 Authentication failed. Please login: npm login --registry=https://registry.npmjs.com'
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
printSslTroubleshooting();
|
|
101
157
|
throw error;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
delete packageJson.publishConfig;
|
|
118
|
-
}
|
|
119
|
-
if (originalDependencies) {
|
|
120
|
-
packageJson.dependencies = originalDependencies;
|
|
121
|
-
}
|
|
122
|
-
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
123
|
-
console.log('🔄 Restored package.json');
|
|
124
|
-
|
|
125
|
-
// Restore .npmrc if it existed
|
|
126
|
-
if (npmrcExists && originalNpmrc !== null) {
|
|
127
|
-
writeFileSync(npmrcPath, originalNpmrc);
|
|
128
|
-
console.log('🔄 Restored .npmrc');
|
|
158
|
+
} finally {
|
|
159
|
+
if (originalPublishConfig) {
|
|
160
|
+
packageJson.publishConfig = originalPublishConfig;
|
|
161
|
+
} else {
|
|
162
|
+
delete packageJson.publishConfig;
|
|
163
|
+
}
|
|
164
|
+
if (originalDependencies) {
|
|
165
|
+
packageJson.dependencies = originalDependencies;
|
|
166
|
+
}
|
|
167
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
168
|
+
console.log('🔄 Restored package.json');
|
|
169
|
+
if (npmrcExists && originalNpmrc !== null) {
|
|
170
|
+
writeFileSync(npmrcPath, originalNpmrc);
|
|
171
|
+
console.log('🔄 Restored .npmrc');
|
|
172
|
+
}
|
|
129
173
|
}
|
|
130
174
|
}
|
|
131
175
|
|
|
176
|
+
main().catch((e) => {
|
|
177
|
+
if (e && e.message) console.error(e.message);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
});
|