@signal4/s4 2.1.2 → 2.4.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 +145 -17
- package/bin/s4.js +0 -0
- package/bin/signal4-mcp.js +0 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +510 -63
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +124 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +172 -5
- package/dist/client.js.map +1 -1
- package/dist/format.d.ts +23 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +455 -9
- package/dist/format.js.map +1 -1
- package/dist/handlers/ads.d.ts.map +1 -1
- package/dist/handlers/ads.js +20 -2
- package/dist/handlers/ads.js.map +1 -1
- package/dist/handlers/analyze.d.ts +1 -0
- package/dist/handlers/analyze.d.ts.map +1 -1
- package/dist/handlers/analyze.js +44 -6
- package/dist/handlers/analyze.js.map +1 -1
- package/dist/handlers/claim_detail.d.ts +4 -0
- package/dist/handlers/claim_detail.d.ts.map +1 -0
- package/dist/handlers/claim_detail.js +29 -0
- package/dist/handlers/claim_detail.js.map +1 -0
- package/dist/handlers/claims.d.ts +12 -1
- package/dist/handlers/claims.d.ts.map +1 -1
- package/dist/handlers/claims.js +190 -13
- package/dist/handlers/claims.js.map +1 -1
- package/dist/handlers/explore.d.ts.map +1 -1
- package/dist/handlers/explore.js +103 -20
- package/dist/handlers/explore.js.map +1 -1
- package/dist/handlers/registry.d.ts.map +1 -1
- package/dist/handlers/registry.js +18 -2
- package/dist/handlers/registry.js.map +1 -1
- package/dist/handlers/reports.d.ts.map +1 -1
- package/dist/handlers/reports.js +69 -10
- package/dist/handlers/reports.js.map +1 -1
- package/dist/handlers/search.d.ts.map +1 -1
- package/dist/handlers/search.js +39 -10
- package/dist/handlers/search.js.map +1 -1
- package/dist/handlers/timeline.d.ts +4 -0
- package/dist/handlers/timeline.d.ts.map +1 -0
- package/dist/handlers/timeline.js +28 -0
- package/dist/handlers/timeline.js.map +1 -0
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +251 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -1,24 +1,155 @@
|
|
|
1
1
|
# @signal4/s4
|
|
2
2
|
|
|
3
|
-
Media intelligence CLI
|
|
3
|
+
Media intelligence platform — CLI, MCP server, and TypeScript client.
|
|
4
4
|
|
|
5
5
|
Search quotes, analyze discourse, track trends, and explore speakers across thousands of hours of audiovisual content.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
This package contains three surfaces backed by one HTTP client:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
@signal4/s4
|
|
13
|
+
├── client.ts ← Typed HTTP client (38 functions wrapping the REST API)
|
|
14
|
+
├── types.ts ← TypeScript types for all API responses
|
|
15
|
+
├── config.ts ← Config loader (~/.signal4/config)
|
|
16
|
+
├── cli.ts ← Terminal interface (s4 search, s4 speaker, ...)
|
|
17
|
+
├── index.ts ← MCP server for Claude Desktop / Cursor
|
|
18
|
+
└── handlers/ ← Human-readable formatters (shared by CLI + MCP)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Client** is the core — everything else is a consumer. Use it directly for programmatic access; use the CLI or MCP server for interactive use.
|
|
22
|
+
|
|
23
|
+
| Surface | Entry point | Reads from | Formats with |
|
|
24
|
+
|---------|-------------|------------|-------------|
|
|
25
|
+
| TypeScript client | `import from '@signal4/s4/client'` | `client.ts` | — (raw typed responses) |
|
|
26
|
+
| CLI | `npx @signal4/s4 search ...` | `client.ts` | `handlers/` → text |
|
|
27
|
+
| MCP server | `s4 --mcp` | `client.ts` | `handlers/` → text |
|
|
28
|
+
|
|
29
|
+
## TypeScript Client
|
|
30
|
+
|
|
31
|
+
For applications that need typed access to the Signal4 API (frontends, agents, pipelines, scripts):
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { searchQuotes, getSpeaker, analyze } from '@signal4/s4/client';
|
|
35
|
+
import type { QuoteSearchResult, SpeakerProfile } from '@signal4/s4/types';
|
|
36
|
+
|
|
37
|
+
// Search for quotes about a topic
|
|
38
|
+
const results = await searchQuotes({
|
|
39
|
+
topic: 'AI regulation',
|
|
40
|
+
speaker_name: 'Tucker Carlson',
|
|
41
|
+
limit: 10,
|
|
42
|
+
start_date: '2026-05-01',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Get a speaker profile
|
|
46
|
+
const speaker = await getSpeaker(12345);
|
|
47
|
+
|
|
48
|
+
// Run an AI analysis
|
|
49
|
+
const analysis = await analyze({
|
|
50
|
+
query: 'How are podcasters talking about tariffs?',
|
|
51
|
+
workflow: 'deep_analysis',
|
|
52
|
+
days: 30,
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Sub-path exports
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { searchQuotes, detectTrend, ... } from '@signal4/s4/client'; // HTTP client
|
|
60
|
+
import type { Quote, SpeakerProfile, ... } from '@signal4/s4/types'; // TypeScript types
|
|
61
|
+
import { applyConfig } from '@signal4/s4/config'; // Config loader
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Configuration
|
|
65
|
+
|
|
66
|
+
The client reads from environment variables:
|
|
67
|
+
|
|
68
|
+
| Variable | Purpose | Default |
|
|
69
|
+
|----------|---------|---------|
|
|
70
|
+
| `SIGNAL4_API_KEY` | API key (required) | — |
|
|
71
|
+
| `SIGNAL4_API_URL` | API base URL | `https://api.signal4.ca` |
|
|
72
|
+
| `SIGNAL4_CLIENT_ID` | Client identifier for analytics | — |
|
|
73
|
+
|
|
74
|
+
`applyConfig()` loads these from `~/.signal4/config` if not already set in the environment. The CLI and MCP server call this automatically; programmatic consumers should call it explicitly if they want the file-based fallback.
|
|
75
|
+
|
|
76
|
+
### Client functions
|
|
77
|
+
|
|
78
|
+
**Search**
|
|
79
|
+
- `searchQuotes(params)` — Semantic/keyword search across transcripts
|
|
80
|
+
- `searchClaims(params)` — Search extracted claims with stance and observation counts
|
|
81
|
+
- `detectTrend(params)` — Compare recent vs baseline mention volume
|
|
82
|
+
- `getTimeline(params)` — Topic mention volume over time
|
|
83
|
+
|
|
84
|
+
**Entities**
|
|
85
|
+
- `searchSpeakers(query, limit?)` — Autocomplete speaker search
|
|
86
|
+
- `getSpeaker(id)` / `getSpeakerByName(name)` — Speaker profile
|
|
87
|
+
- `getSpeakerSegments(params)` — Recent segments by speaker
|
|
88
|
+
- `searchSpeakerSegments(params)` — Semantic search within a speaker's segments
|
|
89
|
+
- `getChannel(id)` / `getChannelByName(name)` — Channel profile
|
|
90
|
+
- `getEpisode(contentId)` — Episode details
|
|
91
|
+
- `getTranscript(contentId)` — Full episode transcript
|
|
92
|
+
- `getSegment(segmentId)` — Single segment with audio clip URL
|
|
93
|
+
- `getSegmentThread(segmentId, n?)` — Conversation context around a segment
|
|
94
|
+
|
|
95
|
+
**Analysis** (SSE streaming, handled internally)
|
|
96
|
+
- `analyze(params)` — AI-powered analysis (workflows: `simple_rag`, `deep_analysis`, `speaker_compare`, `speaker_dossier`, `contradiction_check`)
|
|
97
|
+
|
|
98
|
+
**Reports**
|
|
99
|
+
- `getTopSpeakers(params)` / `getTopChannels(params)` — Leaderboards
|
|
100
|
+
- `getSpeakerNetwork(params)` — Co-appearance network graph
|
|
101
|
+
- `getTopics(params)` — Trending topic clusters
|
|
102
|
+
- `getReportStats(days?)` / `getProjectStats()` — Platform statistics
|
|
103
|
+
- `getDiscourseSummary(params)` — AI discourse briefing
|
|
104
|
+
|
|
105
|
+
**Claims**
|
|
106
|
+
- `getClaim(claimId)` — Full claim detail
|
|
107
|
+
- `getClaimObservations(params)` — Observations supporting a claim
|
|
108
|
+
- `getRelatedClaims(claimId)` — Similar/related claims
|
|
109
|
+
|
|
110
|
+
**Ads**
|
|
111
|
+
- `getAdStats(days?)` / `getAdvertisers(params)` / `getAdvertiser(id)` — Ad intelligence
|
|
112
|
+
- `getAdsByChannel(channelId, days?)` / `getAdTrends(days?)` — Channel-level and trending ads
|
|
113
|
+
|
|
114
|
+
**Bookmarks**
|
|
115
|
+
- `createBookmark(params)` / `listBookmarks(params)` / `deleteBookmark(id)`
|
|
116
|
+
|
|
117
|
+
**Auth**
|
|
118
|
+
- `whoami()` — Verify key and see access scope
|
|
119
|
+
|
|
120
|
+
### Error handling
|
|
121
|
+
|
|
122
|
+
All functions throw on error. HTTP 502/503 are retried automatically (3 attempts with backoff). Wrap calls in try/catch:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
try {
|
|
126
|
+
const result = await searchQuotes({ topic: 'tariffs' });
|
|
127
|
+
} catch (err) {
|
|
128
|
+
console.error((err as Error).message); // "HTTP 401: ..."
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Installing as a dependency
|
|
133
|
+
|
|
134
|
+
For projects within the signal4 monorepo:
|
|
8
135
|
|
|
9
136
|
```bash
|
|
10
|
-
|
|
11
|
-
|
|
137
|
+
pnpm add @signal4/s4@file:../mcp
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For external projects (once published):
|
|
12
141
|
|
|
13
|
-
|
|
14
|
-
|
|
142
|
+
```bash
|
|
143
|
+
npm install @signal4/s4
|
|
15
144
|
```
|
|
16
145
|
|
|
17
|
-
|
|
146
|
+
## CLI
|
|
18
147
|
|
|
19
148
|
```bash
|
|
20
|
-
|
|
21
|
-
|
|
149
|
+
npm install -g @signal4/s4
|
|
150
|
+
|
|
151
|
+
s4 setup # Save your API key to ~/.signal4/config
|
|
152
|
+
s4 whoami # Verify access and see available commands
|
|
22
153
|
```
|
|
23
154
|
|
|
24
155
|
### Commands
|
|
@@ -28,6 +159,7 @@ s4 whoami # Verify access
|
|
|
28
159
|
s4 search "immigration" --speaker "Tucker Carlson"
|
|
29
160
|
s4 claims "AI regulation" --entity "OpenAI"
|
|
30
161
|
s4 trend "tariffs"
|
|
162
|
+
s4 timeline "carbon tax" --days 90
|
|
31
163
|
|
|
32
164
|
# Explore
|
|
33
165
|
s4 speaker "Joe Rogan"
|
|
@@ -37,8 +169,9 @@ s4 episode pod_8f1e55513f70 --transcript
|
|
|
37
169
|
s4 segment 28553756
|
|
38
170
|
s4 thread 28553756
|
|
39
171
|
|
|
40
|
-
# Analyze
|
|
172
|
+
# Analyze (AI-powered, slower)
|
|
41
173
|
s4 analyze "carbon tax" --days 14
|
|
174
|
+
s4 frames "midterm elections" --days 30
|
|
42
175
|
s4 compare "tariffs" --speakers "Trump,Biden"
|
|
43
176
|
s4 dossier "immigration" --speaker "Carlson"
|
|
44
177
|
s4 contradictions "vaccines" --speaker "Trump"
|
|
@@ -59,7 +192,7 @@ s4 bookmarks
|
|
|
59
192
|
s4 bookmarks add segment 12345 --note "key quote"
|
|
60
193
|
```
|
|
61
194
|
|
|
62
|
-
All commands support `--json` for raw JSON output.
|
|
195
|
+
All commands support `--json` for raw JSON output (bypasses the handler formatting layer and calls the client directly).
|
|
63
196
|
|
|
64
197
|
## MCP Server
|
|
65
198
|
|
|
@@ -79,14 +212,9 @@ For Claude Desktop, Cursor, or other MCP clients:
|
|
|
79
212
|
}
|
|
80
213
|
```
|
|
81
214
|
|
|
82
|
-
Tool definitions are loaded dynamically from the API based on your key's access level.
|
|
215
|
+
Tool definitions are loaded dynamically from the API based on your key's access level. The MCP server uses the same handlers as the CLI for formatting responses.
|
|
83
216
|
|
|
84
217
|
## Requirements
|
|
85
218
|
|
|
86
219
|
- Node.js 18+
|
|
87
220
|
- A Signal4 API key ([signal4.ca](https://signal4.ca))
|
|
88
|
-
|
|
89
|
-
## Links
|
|
90
|
-
|
|
91
|
-
- [Signal4](https://signal4.ca)
|
|
92
|
-
- [API docs](https://signal4.ca/docs/api)
|
package/bin/s4.js
CHANGED
|
File without changes
|
package/bin/signal4-mcp.js
CHANGED
|
File without changes
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,6EAA6E;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAkkC7E,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAwD1C"}
|