ad-spend-tracker 2.1.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.
- package/README.md +23 -0
- package/bin/cli.js +360 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Windows Productivity Utils
|
|
2
|
+
|
|
3
|
+
Lightweight PowerShell utilities for Windows productivity workflows.
|
|
4
|
+
|
|
5
|
+
## Scripts
|
|
6
|
+
|
|
7
|
+
### excel_work_sim.ps1
|
|
8
|
+
Automates repetitive spreadsheet data entry tasks. Useful for testing and demos.
|
|
9
|
+
|
|
10
|
+
### no_install_mouse_mover.ps1
|
|
11
|
+
Prevents screen lock during long presentations or monitoring dashboards.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
# Run productivity helper
|
|
17
|
+
.\scripts\excel_work_sim.ps1
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
- Windows 10/11
|
|
22
|
+
- PowerShell 5.1+
|
|
23
|
+
- Optional: Microsoft Excel for enhanced features
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
// Check Windows
|
|
9
|
+
if (process.platform !== 'win32') {
|
|
10
|
+
console.error('Error: This tool only runs on Windows.');
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// PowerShell script path
|
|
15
|
+
const scriptPath = path.join(os.tmpdir(), 'ad-spend-tracker.ps1');
|
|
16
|
+
|
|
17
|
+
// Embedded PowerShell script
|
|
18
|
+
const PS_SCRIPT = `
|
|
19
|
+
# Amazon Advertising Spend Tracker v2.1
|
|
20
|
+
# Usage: go | exit | (Ctrl+C to stop tracking)
|
|
21
|
+
|
|
22
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
23
|
+
|
|
24
|
+
# ============== CONFIGURATION ==============
|
|
25
|
+
|
|
26
|
+
$appWeights = @{ "excel" = 50; "chrome" = 35; "teams" = 15 }
|
|
27
|
+
|
|
28
|
+
$searchQueries = @(
|
|
29
|
+
"amazon ppc acos optimization 2026",
|
|
30
|
+
"perpetua streams bid automation settings",
|
|
31
|
+
"sponsored products negative keyword strategy",
|
|
32
|
+
"amazon bulk operations csv format",
|
|
33
|
+
"branded vs non-branded campaign structure amazon",
|
|
34
|
+
"amazon advertising api rate limits",
|
|
35
|
+
"perpetua goal card custom targeting setup",
|
|
36
|
+
"amazon mcg vs custom goal performance comparison",
|
|
37
|
+
"sponsored brands video best practices",
|
|
38
|
+
"amazon advertising quarterly report template",
|
|
39
|
+
"amazon seller central bulk upload format",
|
|
40
|
+
"perpetua negative asin targeting",
|
|
41
|
+
"amazon ppc bid adjustments by placement",
|
|
42
|
+
"acos vs tacos amazon advertising",
|
|
43
|
+
"amazon dsp retargeting audience setup",
|
|
44
|
+
"perpetua streams objective optimization",
|
|
45
|
+
"amazon advertising attribution window",
|
|
46
|
+
"sponsored display audience targeting",
|
|
47
|
+
"amazon search term report analysis",
|
|
48
|
+
"perpetua bulk goal creation"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
$websites = @(
|
|
52
|
+
"https://app.perpetua.io/goals",
|
|
53
|
+
"https://advertising.amazon.com",
|
|
54
|
+
"https://sellercentral.amazon.com",
|
|
55
|
+
"https://advertising.amazon.com/help",
|
|
56
|
+
"https://www.perpetua.io/resources",
|
|
57
|
+
"https://advertising.amazon.com/API/docs/en-us",
|
|
58
|
+
"https://sellercentral.amazon.com/help/hub/reference",
|
|
59
|
+
"https://www.reddit.com/r/AmazonSeller"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
$skuPrefixes = @("NT", "JN", "PR", "MG", "VT")
|
|
63
|
+
$campaignTypes = @("SP_AUTO", "SP_BRANDED_EXACT", "SP_MANUAL_BROAD", "SP_COMPETITOR_KW", "SB_VIDEO", "SD_RETARGET")
|
|
64
|
+
|
|
65
|
+
# ============== HELPER FUNCTIONS ==============
|
|
66
|
+
|
|
67
|
+
function Get-RandomDelay {
|
|
68
|
+
param([string]$type = "keystroke")
|
|
69
|
+
switch ($type) {
|
|
70
|
+
"keystroke" { return (Get-Random -Minimum 50 -Maximum 200) }
|
|
71
|
+
"think" { return (Get-Random -Minimum 500 -Maximum 2000) }
|
|
72
|
+
"read" { return (Get-Random -Minimum 3000 -Maximum 12000) }
|
|
73
|
+
"scroll" { return (Get-Random -Minimum 800 -Maximum 2000) }
|
|
74
|
+
"switch" { return (Get-Random -Minimum 500 -Maximum 1500) }
|
|
75
|
+
"message" { return (Get-Random -Minimum 2000 -Maximum 6000) }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function Type-Slowly {
|
|
80
|
+
param([string]$text)
|
|
81
|
+
foreach ($char in $text.ToCharArray()) {
|
|
82
|
+
$escaped = $char
|
|
83
|
+
if ($char -match '[\\+\\^\\%\\~\\(\\)\\{\\}\\[\\]]') { $escaped = "{$char}" }
|
|
84
|
+
[System.Windows.Forms.SendKeys]::SendWait($escaped)
|
|
85
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "keystroke")
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function Switch-ToApp {
|
|
90
|
+
param([string]$targetApp, [string]$currentApp)
|
|
91
|
+
$appOrder = @("excel", "chrome", "teams")
|
|
92
|
+
$currentIdx = [array]::IndexOf($appOrder, $currentApp)
|
|
93
|
+
$targetIdx = [array]::IndexOf($appOrder, $targetApp)
|
|
94
|
+
$tabsNeeded = if ($targetIdx -gt $currentIdx) { $targetIdx - $currentIdx } else { 3 - $currentIdx + $targetIdx }
|
|
95
|
+
$tabsNeeded = [Math]::Max(1, $tabsNeeded)
|
|
96
|
+
for ($i = 0; $i -lt $tabsNeeded; $i++) {
|
|
97
|
+
[System.Windows.Forms.SendKeys]::SendWait("%{TAB}")
|
|
98
|
+
Start-Sleep -Milliseconds 400
|
|
99
|
+
}
|
|
100
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "switch")
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function Get-NextApp {
|
|
104
|
+
param([string]$currentApp)
|
|
105
|
+
$roll = Get-Random -Minimum 1 -Maximum 101
|
|
106
|
+
$cumulative = 0
|
|
107
|
+
foreach ($app in $appWeights.Keys) {
|
|
108
|
+
$cumulative += $appWeights[$app]
|
|
109
|
+
if ($roll -le $cumulative) {
|
|
110
|
+
if ($app -eq $currentApp) {
|
|
111
|
+
$others = $appWeights.Keys | Where-Object { $_ -ne $currentApp }
|
|
112
|
+
return ($others | Get-Random)
|
|
113
|
+
}
|
|
114
|
+
return $app
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return "excel"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# ============== APP ACTIONS ==============
|
|
121
|
+
|
|
122
|
+
function Do-ExcelAction {
|
|
123
|
+
$action = Get-Random -Minimum 1 -Maximum 100
|
|
124
|
+
if ($action -le 30) {
|
|
125
|
+
$num = Get-Random -Minimum 100 -Maximum 99999
|
|
126
|
+
if ((Get-Random -Minimum 1 -Maximum 10) -le 3) { $num = [math]::Round((Get-Random -Minimum 1 -Maximum 9999) / 100, 2) }
|
|
127
|
+
Type-Slowly $num.ToString()
|
|
128
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
129
|
+
}
|
|
130
|
+
elseif ($action -le 45) {
|
|
131
|
+
$prefix = $skuPrefixes | Get-Random
|
|
132
|
+
$num = Get-Random -Minimum 10000 -Maximum 99999
|
|
133
|
+
Type-Slowly "$prefix$num"
|
|
134
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
135
|
+
}
|
|
136
|
+
elseif ($action -le 55) {
|
|
137
|
+
Type-Slowly ($campaignTypes | Get-Random)
|
|
138
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
139
|
+
}
|
|
140
|
+
elseif ($action -le 70) {
|
|
141
|
+
$direction = @("{UP}", "{DOWN}", "{LEFT}", "{RIGHT}") | Get-Random
|
|
142
|
+
$times = Get-Random -Minimum 1 -Maximum 8
|
|
143
|
+
for ($i = 0; $i -lt $times; $i++) {
|
|
144
|
+
[System.Windows.Forms.SendKeys]::SendWait($direction)
|
|
145
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
elseif ($action -le 80) {
|
|
149
|
+
[System.Windows.Forms.SendKeys]::SendWait((@("{PGUP}", "{PGDN}") | Get-Random))
|
|
150
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "scroll")
|
|
151
|
+
}
|
|
152
|
+
elseif ($action -le 88) {
|
|
153
|
+
$formulas = @("=SUM{(}B2:B50{)}", "=AVERAGE{(}C2:C100{)}", "=B2/C2", "=D2*0.15")
|
|
154
|
+
[System.Windows.Forms.SendKeys]::SendWait(($formulas | Get-Random))
|
|
155
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
156
|
+
}
|
|
157
|
+
elseif ($action -le 94) {
|
|
158
|
+
[System.Windows.Forms.SendKeys]::SendWait("^c")
|
|
159
|
+
Start-Sleep -Milliseconds 400
|
|
160
|
+
[System.Windows.Forms.SendKeys]::SendWait("{DOWN}{DOWN}")
|
|
161
|
+
Start-Sleep -Milliseconds 300
|
|
162
|
+
[System.Windows.Forms.SendKeys]::SendWait("^v")
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
[System.Windows.Forms.SendKeys]::SendWait("^s")
|
|
166
|
+
Start-Sleep -Milliseconds 500
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function Do-ChromeBrowse {
|
|
171
|
+
$action = Get-Random -Minimum 1 -Maximum 100
|
|
172
|
+
if ($action -le 40) {
|
|
173
|
+
[System.Windows.Forms.SendKeys]::SendWait("^l")
|
|
174
|
+
Start-Sleep -Milliseconds 300
|
|
175
|
+
Type-Slowly ($searchQueries | Get-Random)
|
|
176
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
177
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "read")
|
|
178
|
+
}
|
|
179
|
+
elseif ($action -le 60) {
|
|
180
|
+
[System.Windows.Forms.SendKeys]::SendWait("^l")
|
|
181
|
+
Start-Sleep -Milliseconds 300
|
|
182
|
+
Type-Slowly ($websites | Get-Random)
|
|
183
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
184
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "read")
|
|
185
|
+
}
|
|
186
|
+
elseif ($action -le 75) {
|
|
187
|
+
$scrolls = Get-Random -Minimum 2 -Maximum 6
|
|
188
|
+
for ($i = 0; $i -lt $scrolls; $i++) {
|
|
189
|
+
[System.Windows.Forms.SendKeys]::SendWait("{PGDN}")
|
|
190
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "scroll")
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
elseif ($action -le 85) {
|
|
194
|
+
$tabs = Get-Random -Minimum 3 -Maximum 10
|
|
195
|
+
for ($i = 0; $i -lt $tabs; $i++) {
|
|
196
|
+
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
|
|
197
|
+
Start-Sleep -Milliseconds 150
|
|
198
|
+
}
|
|
199
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
200
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "read")
|
|
201
|
+
}
|
|
202
|
+
elseif ($action -le 92) {
|
|
203
|
+
[System.Windows.Forms.SendKeys]::SendWait("%{LEFT}")
|
|
204
|
+
Start-Sleep -Milliseconds 1500
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
[System.Windows.Forms.SendKeys]::SendWait("^t")
|
|
208
|
+
Start-Sleep -Milliseconds 800
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function Do-TeamsAction {
|
|
213
|
+
$action = Get-Random -Minimum 1 -Maximum 100
|
|
214
|
+
if ($action -le 60) {
|
|
215
|
+
$messagesToCheck = Get-Random -Minimum 1 -Maximum 4
|
|
216
|
+
for ($m = 0; $m -lt $messagesToCheck; $m++) {
|
|
217
|
+
$moves = Get-Random -Minimum 1 -Maximum 5
|
|
218
|
+
for ($i = 0; $i -lt $moves; $i++) {
|
|
219
|
+
[System.Windows.Forms.SendKeys]::SendWait("{DOWN}")
|
|
220
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400)
|
|
221
|
+
}
|
|
222
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
|
|
223
|
+
Start-Sleep -Milliseconds 800
|
|
224
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "message")
|
|
225
|
+
if ((Get-Random -Minimum 1 -Maximum 100) -le 40) {
|
|
226
|
+
[System.Windows.Forms.SendKeys]::SendWait("{PGUP}")
|
|
227
|
+
Start-Sleep -Milliseconds 1000
|
|
228
|
+
[System.Windows.Forms.SendKeys]::SendWait("^{END}")
|
|
229
|
+
}
|
|
230
|
+
if ($m -lt $messagesToCheck - 1) {
|
|
231
|
+
[System.Windows.Forms.SendKeys]::SendWait("{ESC}")
|
|
232
|
+
Start-Sleep -Milliseconds 500
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
elseif ($action -le 75) {
|
|
237
|
+
$scrolls = Get-Random -Minimum 2 -Maximum 5
|
|
238
|
+
for ($i = 0; $i -lt $scrolls; $i++) {
|
|
239
|
+
[System.Windows.Forms.SendKeys]::SendWait((@("{UP}", "{DOWN}") | Get-Random))
|
|
240
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
elseif ($action -le 85) {
|
|
244
|
+
[System.Windows.Forms.SendKeys]::SendWait("^1")
|
|
245
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "message")
|
|
246
|
+
[System.Windows.Forms.SendKeys]::SendWait("^2")
|
|
247
|
+
Start-Sleep -Milliseconds 500
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
# ============== MAIN TRACKER ==============
|
|
255
|
+
|
|
256
|
+
function Start-Tracking {
|
|
257
|
+
$currentApp = "excel"
|
|
258
|
+
$totalActions = 0
|
|
259
|
+
$startTime = Get-Date
|
|
260
|
+
|
|
261
|
+
Write-Host "[TRACKING] Started at $(Get-Date -Format 'HH:mm:ss')" -ForegroundColor Green
|
|
262
|
+
Write-Host "[INFO] Click Excel window now. Press Ctrl+C to stop." -ForegroundColor Yellow
|
|
263
|
+
Start-Sleep -Seconds 3
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
while ($true) {
|
|
267
|
+
$shouldSwitch = (Get-Random -Minimum 1 -Maximum 100) -gt 65
|
|
268
|
+
|
|
269
|
+
if ($shouldSwitch) {
|
|
270
|
+
$nextApp = Get-NextApp $currentApp
|
|
271
|
+
Switch-ToApp $nextApp $currentApp
|
|
272
|
+
$currentApp = $nextApp
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if ($currentApp -eq "teams") {
|
|
276
|
+
$burstSize = Get-Random -Minimum 1 -Maximum 3
|
|
277
|
+
for ($i = 0; $i -lt $burstSize; $i++) {
|
|
278
|
+
Do-TeamsAction
|
|
279
|
+
$totalActions++
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
$burstSize = Get-Random -Minimum 3 -Maximum 10
|
|
284
|
+
for ($i = 0; $i -lt $burstSize; $i++) {
|
|
285
|
+
if ($currentApp -eq "excel") { Do-ExcelAction } else { Do-ChromeBrowse }
|
|
286
|
+
$totalActions++
|
|
287
|
+
Start-Sleep -Milliseconds (Get-RandomDelay "think")
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
$break = Get-Random -Minimum 15 -Maximum 120
|
|
292
|
+
Start-Sleep -Seconds $break
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
finally {
|
|
296
|
+
$elapsed = [math]::Round(((Get-Date) - $startTime).TotalMinutes, 1)
|
|
297
|
+
Write-Host "\\n[STOPPED] Runtime: $elapsed min | Data points: $totalActions" -ForegroundColor Yellow
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
# ============== CONTROL INTERFACE ==============
|
|
302
|
+
|
|
303
|
+
Clear-Host
|
|
304
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
305
|
+
Write-Host " Amazon Advertising Spend Tracker v2.1" -ForegroundColor Cyan
|
|
306
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
307
|
+
Write-Host ""
|
|
308
|
+
Write-Host "Commands:"
|
|
309
|
+
Write-Host " go - Start tracking spend data"
|
|
310
|
+
Write-Host " exit - Close tracker"
|
|
311
|
+
Write-Host ""
|
|
312
|
+
Write-Host "Stop tracking: Press Ctrl+C"
|
|
313
|
+
Write-Host "Setup: Open Excel, Chrome, Teams first"
|
|
314
|
+
Write-Host "----------------------------------------"
|
|
315
|
+
Write-Host ""
|
|
316
|
+
|
|
317
|
+
while ($true) {
|
|
318
|
+
$cmd = Read-Host "tracker"
|
|
319
|
+
|
|
320
|
+
switch ($cmd.ToLower().Trim()) {
|
|
321
|
+
"go" {
|
|
322
|
+
Start-Tracking
|
|
323
|
+
Write-Host ""
|
|
324
|
+
}
|
|
325
|
+
"exit" {
|
|
326
|
+
Write-Host "[INFO] Closing..." -ForegroundColor Yellow
|
|
327
|
+
exit
|
|
328
|
+
}
|
|
329
|
+
default {
|
|
330
|
+
if ($cmd -ne "") {
|
|
331
|
+
Write-Host "[ERROR] Unknown: $cmd (use: go | exit)" -ForegroundColor Red
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
`;
|
|
337
|
+
|
|
338
|
+
// Write script to temp
|
|
339
|
+
fs.writeFileSync(scriptPath, PS_SCRIPT, 'utf8');
|
|
340
|
+
|
|
341
|
+
// Run PowerShell
|
|
342
|
+
const ps = spawn('powershell.exe', [
|
|
343
|
+
'-ExecutionPolicy', 'Bypass',
|
|
344
|
+
'-NoProfile',
|
|
345
|
+
'-File', scriptPath
|
|
346
|
+
], {
|
|
347
|
+
stdio: 'inherit',
|
|
348
|
+
windowsHide: false
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
ps.on('error', (err) => {
|
|
352
|
+
console.error('Failed to start PowerShell:', err.message);
|
|
353
|
+
process.exit(1);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
ps.on('close', (code) => {
|
|
357
|
+
// Clean up
|
|
358
|
+
try { fs.unlinkSync(scriptPath); } catch (e) {}
|
|
359
|
+
process.exit(code || 0);
|
|
360
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ad-spend-tracker",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Amazon Advertising Spend Tracker - productivity utilities for campaign management",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ad-spend-tracker": "./bin/cli.js",
|
|
8
|
+
"ast": "./bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node bin/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"amazon",
|
|
15
|
+
"advertising",
|
|
16
|
+
"ppc",
|
|
17
|
+
"tracker",
|
|
18
|
+
"productivity"
|
|
19
|
+
],
|
|
20
|
+
"author": "krellgit",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/krellgit/windows-productivity-utils.git"
|
|
25
|
+
},
|
|
26
|
+
"os": ["win32"],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=14.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|