@powerbuilder/skill 1.0.2 → 1.0.5
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/README.md +3 -8
- package/bin/codeapp +15 -1
- package/bin/skill +15 -1
- package/lib/banner.js +1 -3
- package/lib/detect-targets.js +3 -0
- package/lib/wizard-codeapp.js +33 -15
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
# @powerbuilder/skill
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Install production-ready AI agent skills into your **.cursor**, **.claude**, or **.gemini** workspace folders with a single command.
|
|
2
|
+
**PowerBuilder** — a toolkit for the Microsoft Power Platform.
|
|
6
3
|
|
|
7
4
|
---
|
|
8
5
|
|
|
@@ -15,7 +12,6 @@ npx @powerbuilder/skill codeapp
|
|
|
15
12
|
|
|
16
13
|
The wizard will:
|
|
17
14
|
1. Auto-detect `.cursor`, `.claude`, and `.gemini` folders in your project
|
|
18
|
-
2. Copy the skill files into each detected agent folder
|
|
19
15
|
3. Install `@playwright/cli` globally for automated testing
|
|
20
16
|
4. Open `make.powerapps.com` in a persistent browser session for first-time login
|
|
21
17
|
|
|
@@ -46,12 +42,11 @@ The installer searches upward from your current directory to your home folder an
|
|
|
46
42
|
## Requirements
|
|
47
43
|
|
|
48
44
|
- Node.js ≥ 18
|
|
49
|
-
- At least one of: Cursor, Claude Code, or Gemini CLI installed in the workspace
|
|
50
45
|
|
|
51
46
|
---
|
|
52
47
|
|
|
53
48
|
## About PowerBuilder
|
|
54
49
|
|
|
55
|
-
**PowerBuilder** is a
|
|
50
|
+
**PowerBuilder** is a toolkit by [TuongDoan](https://github.com/tuongdoan) — a growing collection of AI agent skills, scripts, and utilities for the Microsoft Power Platform.
|
|
56
51
|
|
|
57
|
-
©
|
|
52
|
+
© 2026 TuongDoan
|
package/bin/codeapp
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
|
|
2
|
+
# Cross-platform symlink resolution (macOS + Linux compatible)
|
|
3
|
+
case "$0" in
|
|
4
|
+
/*) script="$0" ;; # already absolute
|
|
5
|
+
*) script="$(pwd)/$0" ;; # make absolute
|
|
6
|
+
esac
|
|
7
|
+
# Follow one level of symlink (relative → absolute)
|
|
8
|
+
link=$(readlink "$script" 2>/dev/null)
|
|
9
|
+
if [ -n "$link" ]; then
|
|
10
|
+
case "$link" in
|
|
11
|
+
/*) script="$link" ;;
|
|
12
|
+
*) script="$(dirname "$script")/$link" ;;
|
|
13
|
+
esac
|
|
14
|
+
fi
|
|
15
|
+
basedir=$(dirname "$script")
|
|
16
|
+
exec node "$basedir/codeapp.js" "$@"
|
package/bin/skill
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
|
|
2
|
+
# Cross-platform symlink resolution (macOS + Linux compatible)
|
|
3
|
+
case "$0" in
|
|
4
|
+
/*) script="$0" ;; # already absolute
|
|
5
|
+
*) script="$(pwd)/$0" ;; # make absolute
|
|
6
|
+
esac
|
|
7
|
+
# Follow one level of symlink (relative → absolute)
|
|
8
|
+
link=$(readlink "$script" 2>/dev/null)
|
|
9
|
+
if [ -n "$link" ]; then
|
|
10
|
+
case "$link" in
|
|
11
|
+
/*) script="$link" ;;
|
|
12
|
+
*) script="$(dirname "$script")/$link" ;;
|
|
13
|
+
esac
|
|
14
|
+
fi
|
|
15
|
+
basedir=$(dirname "$script")
|
|
16
|
+
exec node "$basedir/skill.js" "$@"
|
package/lib/banner.js
CHANGED
|
@@ -14,8 +14,6 @@ export function printBanner() {
|
|
|
14
14
|
console.log(cyan(' ██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║██████╔╝╚██████╔╝██║███████╗██████╔╝███████╗██║ ██║'));
|
|
15
15
|
console.log(cyan(' ╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝'));
|
|
16
16
|
console.log();
|
|
17
|
-
console.log(' ' + yellow('⚡ Power Apps Code App Skill') + dim('
|
|
18
|
-
console.log(' ' + green(' Skill Set by TuongDoan') + dim(' · github.com/tuongdoan · © 2025'));
|
|
19
|
-
console.log(' ' + dim('─'.repeat(85)));
|
|
17
|
+
console.log(' ' + yellow('⚡ Power Apps Code App Skill') + dim(' · by TuongDoan · © 2026'));
|
|
20
18
|
console.log();
|
|
21
19
|
}
|
package/lib/detect-targets.js
CHANGED
|
@@ -34,6 +34,7 @@ export function detectTargets(startDir = process.cwd()) {
|
|
|
34
34
|
if (existsSync(cursorDir)) {
|
|
35
35
|
targets.push({
|
|
36
36
|
target: '.cursor',
|
|
37
|
+
label: 'Cursor',
|
|
37
38
|
agentFolder: cursorDir,
|
|
38
39
|
skillsDir: path.join(cursorDir, 'rules', 'skills'),
|
|
39
40
|
dir,
|
|
@@ -42,6 +43,7 @@ export function detectTargets(startDir = process.cwd()) {
|
|
|
42
43
|
if (existsSync(claudeDir)) {
|
|
43
44
|
targets.push({
|
|
44
45
|
target: '.claude',
|
|
46
|
+
label: 'Claude',
|
|
45
47
|
agentFolder: claudeDir,
|
|
46
48
|
skillsDir: path.join(claudeDir, 'skills'),
|
|
47
49
|
dir,
|
|
@@ -50,6 +52,7 @@ export function detectTargets(startDir = process.cwd()) {
|
|
|
50
52
|
if (existsSync(geminiDir)) {
|
|
51
53
|
targets.push({
|
|
52
54
|
target: '.gemini',
|
|
55
|
+
label: 'Google Antigravity',
|
|
53
56
|
agentFolder: geminiDir,
|
|
54
57
|
skillsDir: path.join(geminiDir, 'antigravity', 'skills'),
|
|
55
58
|
dir,
|
package/lib/wizard-codeapp.js
CHANGED
|
@@ -55,10 +55,6 @@ const SKILL_SRC = path.resolve(__dirname, '..', 'skills', 'codeapp');
|
|
|
55
55
|
// ─── STEP 1 — Detect & confirm targets ───────────────────────────────────────
|
|
56
56
|
|
|
57
57
|
async function stepDetectTargets() {
|
|
58
|
-
hr();
|
|
59
|
-
log(chalk.bold('Step 1/4 · Detecting AI agent folders…'));
|
|
60
|
-
hr();
|
|
61
|
-
|
|
62
58
|
const detected = detectTargets();
|
|
63
59
|
|
|
64
60
|
if (detected.length === 0) {
|
|
@@ -67,21 +63,45 @@ async function stepDetectTargets() {
|
|
|
67
63
|
process.exit(1);
|
|
68
64
|
}
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
return detected;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ─── SUMMARY — Show plan & confirm before doing anything ──────────────────────
|
|
70
|
+
|
|
71
|
+
async function stepShowSummary(targets) {
|
|
72
|
+
console.log();
|
|
73
|
+
log(chalk.bold.yellowBright(' 📋 Installation Plan'));
|
|
74
|
+
console.log();
|
|
75
|
+
|
|
76
|
+
// Item 1 — skill files, list human-friendly target names
|
|
77
|
+
log(` ${chalk.cyanBright('1.')} Power Apps Code App Skill for:`);
|
|
78
|
+
for (const t of targets) {
|
|
79
|
+
log(` ${chalk.greenBright('•')} ${chalk.white(t.label)}`);
|
|
73
80
|
}
|
|
74
81
|
console.log();
|
|
75
82
|
|
|
76
|
-
|
|
83
|
+
// Item 2 — playwright (description inline)
|
|
84
|
+
log(` ${chalk.cyanBright('2.')} Playwright CLI ${chalk.dim('(used for automated E2E testing of your Power Apps)')}`);
|
|
85
|
+
console.log();
|
|
86
|
+
|
|
87
|
+
// Login heads-up
|
|
88
|
+
log(chalk.bold.yellowBright(' ⚠️ One-time login required after install:'));
|
|
89
|
+
log(` After Playwright CLI is installed, a browser window will open`);
|
|
90
|
+
log(` and you will need to log in to ${chalk.white('Power Apps')} ${chalk.dim('(make.powerapps.com)')}`);
|
|
91
|
+
log(` This saves a persistent session so future test runs won't ask`);
|
|
92
|
+
log(` you to log in again.`);
|
|
93
|
+
console.log();
|
|
94
|
+
|
|
95
|
+
const proceed = await askConfirm('Proceed with installation?', true);
|
|
77
96
|
if (!proceed) {
|
|
78
|
-
warn('Installation cancelled.');
|
|
97
|
+
warn('Installation cancelled. Nothing was changed.');
|
|
79
98
|
process.exit(0);
|
|
80
99
|
}
|
|
81
|
-
|
|
82
|
-
return detected;
|
|
100
|
+
console.log();
|
|
83
101
|
}
|
|
84
102
|
|
|
103
|
+
|
|
104
|
+
|
|
85
105
|
// ─── STEP 2 — Copy skill files ────────────────────────────────────────────────
|
|
86
106
|
|
|
87
107
|
async function stepCopySkill(targets) {
|
|
@@ -185,11 +205,9 @@ async function stepOpenPowerApps() {
|
|
|
185
205
|
// ─── MAIN ─────────────────────────────────────────────────────────────────────
|
|
186
206
|
|
|
187
207
|
export async function runCodeAppWizard() {
|
|
188
|
-
|
|
189
|
-
console.log(chalk.dim(' This wizard will install the skill into your AI agent folders'));
|
|
190
|
-
console.log(chalk.dim(' and set up Playwright for automated testing.\n'));
|
|
191
|
-
|
|
208
|
+
// Detect first, show summary, confirm — then execute
|
|
192
209
|
const targets = await stepDetectTargets();
|
|
210
|
+
await stepShowSummary(targets);
|
|
193
211
|
await stepCopySkill(targets);
|
|
194
212
|
await stepInstallPlaywright();
|
|
195
213
|
await stepOpenPowerApps();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerbuilder/skill",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "PowerBuilder skill installer — drop production-ready AI agent skills into .cursor, .claude, or .gemini folders with one command.",
|
|
5
5
|
"author": "TuongDoan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,4 +40,4 @@
|
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
42
|
"type": "module"
|
|
43
|
-
}
|
|
43
|
+
}
|