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 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[];