deaf-intelligence 1.0.1
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/LICENSE.md +77 -0
- package/README.md +75 -0
- package/dist/constrained-disagg.d.ts +76 -0
- package/dist/constrained-disagg.js +499 -0
- package/dist/db.d.ts +34 -0
- package/dist/db.js +65 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +450 -0
- package/dist/scraper.d.ts +111 -0
- package/dist/scraper.js +2072 -0
- package/dist/validation.d.ts +43 -0
- package/dist/validation.js +138 -0
- package/package.json +52 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, Apache 2.0 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-Apache-2.0
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Karel "KAYO" Dittrich / DEAF (deaf.audio)
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
Karel "KAYO" Dittrich / DEAF (deaf.audio)
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
Artist-OS MCP Server — Spotify artist intelligence and archival tool.
|
|
20
|
+
|
|
21
|
+
### Use Grant
|
|
22
|
+
|
|
23
|
+
Subject to the conditions below, we hereby grant you a non-exclusive,
|
|
24
|
+
royalty-free, worldwide, non-sublicensable, non-transferable license to
|
|
25
|
+
use, copy, modify, and distribute the Software, in each case subject to
|
|
26
|
+
the limitations and conditions below.
|
|
27
|
+
|
|
28
|
+
### Limitations
|
|
29
|
+
|
|
30
|
+
You may NOT use the Software:
|
|
31
|
+
|
|
32
|
+
1. **As a Competing Product.** You may not provide the Software to third
|
|
33
|
+
parties as a hosted or managed service that allows such third parties
|
|
34
|
+
to use the Software's substantial functionality. This limitation does
|
|
35
|
+
not apply if you are using the Software for internal, non-commercial
|
|
36
|
+
purposes or for personal use.
|
|
37
|
+
|
|
38
|
+
2. **To Circumvent Licensing.** You may not remove or alter any licensing,
|
|
39
|
+
copyright, or other notices of the Licensor in the Software.
|
|
40
|
+
|
|
41
|
+
### Change Date
|
|
42
|
+
|
|
43
|
+
Two (2) years from the date of each release of the Software.
|
|
44
|
+
|
|
45
|
+
### Change License
|
|
46
|
+
|
|
47
|
+
Apache License, Version 2.0
|
|
48
|
+
|
|
49
|
+
### Future License
|
|
50
|
+
|
|
51
|
+
On the Change Date, this license converts to the Change License, and
|
|
52
|
+
all Limitations cease to apply. This is automatic — no action is required
|
|
53
|
+
by you or us.
|
|
54
|
+
|
|
55
|
+
### No Warranty
|
|
56
|
+
|
|
57
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
58
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
59
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
60
|
+
|
|
61
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
62
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
63
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
64
|
+
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## About FSL
|
|
69
|
+
|
|
70
|
+
The Functional Source License (FSL) was created by Sentry. It is designed
|
|
71
|
+
to give developers freedom to use, modify, and learn from source code,
|
|
72
|
+
while protecting the licensor from competitors who would take their work
|
|
73
|
+
and offer it as a competing hosted service.
|
|
74
|
+
|
|
75
|
+
After 2 years, the code becomes fully open source under Apache 2.0.
|
|
76
|
+
|
|
77
|
+
Learn more: https://fsl.software
|
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# DEAF Intelligence
|
|
2
|
+
|
|
3
|
+
> Your Spotify career intelligence layer. Track any artist, build history, get insights.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
MCP server that turns Spotify data into career intelligence. No API keys, no login, no setup.
|
|
8
|
+
|
|
9
|
+
Give it a Spotify URL — it archives the full public profile, computes intelligence metrics, and builds a history that Spotify deletes after 2 years.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
### Claude Desktop
|
|
14
|
+
|
|
15
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"mcpServers": {
|
|
20
|
+
"deaf-intelligence": {
|
|
21
|
+
"command": "npx",
|
|
22
|
+
"args": ["-y", "deaf-intelligence"]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Claude Code
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
claude mcp add deaf-intelligence -- npx -y deaf-intelligence
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Tools
|
|
35
|
+
|
|
36
|
+
| Tool | What |
|
|
37
|
+
|------|------|
|
|
38
|
+
| `track_artist` | Start tracking — scrapes full profile, all tracks, images |
|
|
39
|
+
| `show_stats` | Current metrics, history, trends |
|
|
40
|
+
| `show_tracks` | All tracks sorted by streams, velocity, date |
|
|
41
|
+
| `show_insights` | Intelligence report — velocity ranking, catalog health, release cadence, milestones, recommendations |
|
|
42
|
+
| `show_cities` | Top listener cities |
|
|
43
|
+
| `show_related` | Related artists |
|
|
44
|
+
| `list_artists` | All tracked artists |
|
|
45
|
+
| `run_scrape` | Add new daily snapshot |
|
|
46
|
+
|
|
47
|
+
## Data
|
|
48
|
+
|
|
49
|
+
Everything stored locally on your machine:
|
|
50
|
+
- Full discography with play counts
|
|
51
|
+
- Popularity score (0-100) per track
|
|
52
|
+
- Monthly listeners, followers, world rank
|
|
53
|
+
- Top cities, related artists, playlists
|
|
54
|
+
- Profile and cover art images (archived)
|
|
55
|
+
|
|
56
|
+
Run daily to build history. The longer you use it, the more patterns emerge.
|
|
57
|
+
|
|
58
|
+
## Why
|
|
59
|
+
|
|
60
|
+
- **Spotify deletes data after 2 years.** We keep it forever.
|
|
61
|
+
- **MCP-native.** Ask questions in natural language.
|
|
62
|
+
- **Intelligence, not just numbers.** Velocity ranking, catalog health, milestone projections, actionable recommendations.
|
|
63
|
+
|
|
64
|
+
## Requirements
|
|
65
|
+
|
|
66
|
+
- Node.js 20+
|
|
67
|
+
- System Chrome or Edge (for scraping)
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
FSL-1.1-Apache-2.0 (Functional Source License)
|
|
72
|
+
|
|
73
|
+
## Links
|
|
74
|
+
|
|
75
|
+
- Website: [deaf.audio](https://deaf.audio)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constrained Temporal Disaggregation with Continuity
|
|
3
|
+
*
|
|
4
|
+
* Solves: given N days split into EST [0..B-1] and S4A_PREV [B..N-1],
|
|
5
|
+
* produce daily values where:
|
|
6
|
+
* - sum(EST) = estTotal
|
|
7
|
+
* - sum(S4A_PREV) = prevAgg
|
|
8
|
+
* - v[B-1] ≈ v[B] (no jump at boundary)
|
|
9
|
+
* - v[N-1] ≈ firstS4aVal (anchor at end)
|
|
10
|
+
* - release spike preserved (Denton proportional)
|
|
11
|
+
* - all values >= 0
|
|
12
|
+
*
|
|
13
|
+
* Method: Proportional Denton scaling + boundary blending + deficit absorption.
|
|
14
|
+
*
|
|
15
|
+
* Classical Denton/Chow-Lin handle EITHER sum OR endpoint constraints, not both.
|
|
16
|
+
* (Denton 1971, Dagum & Cholette 2006, Chow-Lin 1971 — all use a single
|
|
17
|
+
* aggregation matrix encoding one constraint type.)
|
|
18
|
+
*
|
|
19
|
+
* We solve the custom QP with dual constraints:
|
|
20
|
+
* min (y - s)' W (y - s) [shape preservation]
|
|
21
|
+
* s.t. sum(y) = T [sum constraint]
|
|
22
|
+
* y[n] = E [endpoint constraint]
|
|
23
|
+
* y >= 0 [non-negativity]
|
|
24
|
+
*
|
|
25
|
+
* Practical implementation:
|
|
26
|
+
* 1. Build indicator shape s (spike + decay + ramp)
|
|
27
|
+
* 2. Proportional scale: y = s × (T / sum(s)) → preserves spike ratios
|
|
28
|
+
* 3. Blend last K days toward endpoint E → smooth boundary
|
|
29
|
+
* 4. Absorb sum deficit into interior → exact sum
|
|
30
|
+
*
|
|
31
|
+
* References:
|
|
32
|
+
* - Denton (1971), "Adjustment of Monthly or Quarterly Series to Annual Totals"
|
|
33
|
+
* - Dagum & Cholette (2006), "Benchmarking, Temporal Distribution, and Reconciliation"
|
|
34
|
+
* - Dergachev et al. (2019), "Analyzing the Spotify Top 200 Through a Point Process Lens"
|
|
35
|
+
* - tempdisagg R package (Sax & Steiner, 2013)
|
|
36
|
+
*/
|
|
37
|
+
export interface DisaggInput {
|
|
38
|
+
/** Total days in both periods combined */
|
|
39
|
+
totalDays: number;
|
|
40
|
+
/** Index where S4A_PREV starts (= number of EST days) */
|
|
41
|
+
boundaryIdx: number;
|
|
42
|
+
/** Required sum of EST period */
|
|
43
|
+
estTotal: number;
|
|
44
|
+
/** Required sum of S4A_PREV period */
|
|
45
|
+
prevAgg: number;
|
|
46
|
+
/** Known daily value at day N (first real S4A day — the anchor) */
|
|
47
|
+
firstS4aVal: number;
|
|
48
|
+
/** Release date as day index (0-based from start). -1 if before range. */
|
|
49
|
+
releaseDayIdx: number;
|
|
50
|
+
/** Spike amplitude (0 = no spike) */
|
|
51
|
+
spikeA: number;
|
|
52
|
+
/** Spike decay rate (e.g. 0.05 for ~14d half-life) */
|
|
53
|
+
spikeLambda: number;
|
|
54
|
+
/** Baseline daily rate (catalog floor) */
|
|
55
|
+
baseline: number;
|
|
56
|
+
}
|
|
57
|
+
export interface DisaggOutput {
|
|
58
|
+
daily: number[];
|
|
59
|
+
boundaryValue: number;
|
|
60
|
+
estSum: number;
|
|
61
|
+
prevSum: number;
|
|
62
|
+
maxError: number;
|
|
63
|
+
}
|
|
64
|
+
export declare function constrainedDisaggregate(input: DisaggInput): DisaggOutput;
|
|
65
|
+
export declare function roundWithDiffusion(values: number[]): number[];
|
|
66
|
+
/**
|
|
67
|
+
* Largest Remainder rounding with pinned anchor.
|
|
68
|
+
* Pins values[anchorIdx] = anchorVal, then distributes (target - anchorVal)
|
|
69
|
+
* across remaining positions using Hamilton's method.
|
|
70
|
+
*
|
|
71
|
+
* Guarantees:
|
|
72
|
+
* - result[anchorIdx] = anchorVal (exact)
|
|
73
|
+
* - sum(result) = target (exact)
|
|
74
|
+
* - each result[i] = floor(x[i]) or ceil(x[i])
|
|
75
|
+
*/
|
|
76
|
+
export declare function roundWithAnchor(values: number[], anchorIdx: number, anchorVal: number, explicitTarget?: number): number[];
|