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.
Files changed (3) hide show
  1. package/README.md +23 -0
  2. package/bin/cli.js +360 -0
  3. 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
+ }