alif-digest 1.1.0 → 1.1.2
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/.github/workflows/alif-scheduled-run.yml +68 -0
- package/README.md +23 -1
- package/ROADMAP.md +1 -7
- package/dist/cli/commands/init.d.ts +3 -1
- package/dist/cli/commands/init.js +158 -94
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.js +4 -0
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +1 -0
- package/dist/cli/commands/validate.js +35 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.js +10 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/core/config-manager.js +3 -1
- package/dist/core/config-manager.js.map +1 -1
- package/dist/core/validator.d.ts +12 -0
- package/dist/core/validator.js +106 -0
- package/dist/core/validator.js.map +1 -0
- package/package.json +1 -1
- package/src/cli/commands/init.ts +165 -95
- package/src/cli/commands/run.ts +5 -0
- package/src/cli/commands/validate.ts +36 -0
- package/src/cli/index.ts +11 -2
- package/src/core/config-manager.ts +3 -1
- package/src/core/validator.ts +111 -0
- package/tests/config-manager.test.ts +14 -0
- package/tests/validator.test.ts +132 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Scheduled Run
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: '0 8 * * *' # Example: 8:00 AM UTC daily
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
run-alif:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout Code
|
|
13
|
+
uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Setup Node.js
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: 22
|
|
19
|
+
|
|
20
|
+
- name: Cache Alif Data Directory
|
|
21
|
+
uses: actions/cache@v4
|
|
22
|
+
with:
|
|
23
|
+
path: .alif-data
|
|
24
|
+
key: ${{ runner.os }}-alif-data-${{ github.run_id }}
|
|
25
|
+
restore-keys: |
|
|
26
|
+
${{ runner.os }}-alif-data-
|
|
27
|
+
|
|
28
|
+
- name: Install Alif Digest
|
|
29
|
+
run: npm install -g alif-digest
|
|
30
|
+
|
|
31
|
+
- name: Initialize Alif Configuration
|
|
32
|
+
env:
|
|
33
|
+
ALIF_CONFIG_DIR: ${{ github.workspace }}/.alif-data
|
|
34
|
+
ALIF_LLM_PROVIDER: ${{ vars.ALIF_LLM_PROVIDER || 'anthropic' }}
|
|
35
|
+
ALIF_LLM_MODEL: ${{ vars.ALIF_LLM_MODEL || '' }}
|
|
36
|
+
ALIF_LLM_BASE_URL: ${{ vars.ALIF_LLM_BASE_URL || '' }}
|
|
37
|
+
ALIF_SIGNAL_THRESHOLD: ${{ vars.ALIF_SIGNAL_THRESHOLD || '60' }}
|
|
38
|
+
ALIF_MAX_ITEMS_PER_RUN: ${{ vars.ALIF_MAX_ITEMS_PER_RUN || '10' }}
|
|
39
|
+
ALIF_SOURCE_COOLDOWN_MINUTES: ${{ vars.ALIF_SOURCE_COOLDOWN_MINUTES || '5' }}
|
|
40
|
+
ALIF_SEQUENTIAL_ANALYSIS: ${{ vars.ALIF_SEQUENTIAL_ANALYSIS || 'false' }}
|
|
41
|
+
ALIF_ENABLE_AI_SCORING: ${{ vars.ALIF_ENABLE_AI_SCORING || 'true' }}
|
|
42
|
+
ALIF_LOG_LEVEL: ${{ vars.ALIF_LOG_LEVEL || 'verbose' }}
|
|
43
|
+
ALIF_CUSTOM_KEYWORDS: ${{ vars.ALIF_CUSTOM_KEYWORDS || '{}' }}
|
|
44
|
+
ALIF_NEGATIVE_KEYWORDS: ${{ vars.ALIF_NEGATIVE_KEYWORDS || '{}' }}
|
|
45
|
+
ALIF_NO_COLOR: ${{ vars.ALIF_NO_COLOR || 'false' }}
|
|
46
|
+
|
|
47
|
+
ALIF_LLM_API_KEY: ${{ secrets.ALIF_LLM_API_KEY || '' }}
|
|
48
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY || '' }}
|
|
49
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || '' }}
|
|
50
|
+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL || '' }}
|
|
51
|
+
GENERIC_WEBHOOK_URL: ${{ secrets.GENERIC_WEBHOOK_URL || '' }}
|
|
52
|
+
run: alif init --non-interactive
|
|
53
|
+
|
|
54
|
+
- name: Run Alif
|
|
55
|
+
env:
|
|
56
|
+
ALIF_CONFIG_DIR: ${{ github.workspace }}/.alif-data
|
|
57
|
+
ALIF_LLM_API_KEY: ${{ secrets.ALIF_LLM_API_KEY }}
|
|
58
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
59
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
60
|
+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
61
|
+
run: alif run
|
|
62
|
+
|
|
63
|
+
- name: Update Cache
|
|
64
|
+
if: always()
|
|
65
|
+
uses: actions/cache/save@v4
|
|
66
|
+
with:
|
|
67
|
+
path: .alif-data
|
|
68
|
+
key: ${{ runner.os }}-alif-data-${{ github.run_id }}
|
package/README.md
CHANGED
|
@@ -80,6 +80,10 @@ Use **standard instruction-tuned models** that support structured output. Avoid
|
|
|
80
80
|
|
|
81
81
|
Interactive wizard to configure your LLM provider, model, delivery channel, and preferences.
|
|
82
82
|
|
|
83
|
+
### `alif validate`
|
|
84
|
+
|
|
85
|
+
Runs a strict pre-flight check on your `config.json` and `feeds.json` files. It verifies that your Cloud LLM API keys are present (if selected), that Delivery Webhook URLs are valid HTTP destinations, and that the `feeds.json` array exists and contains the correct format schema.
|
|
86
|
+
|
|
83
87
|
### `alif run [--force] [--verbose] [--quiet]`
|
|
84
88
|
|
|
85
89
|
Run the full pipeline.
|
|
@@ -152,13 +156,31 @@ Config is stored at `~/.config/alif/config.json`. Most values can be changed wit
|
|
|
152
156
|
}
|
|
153
157
|
```
|
|
154
158
|
|
|
159
|
+
## ☁️ Running on GitHub Actions (Free)
|
|
160
|
+
|
|
161
|
+
You can run Alif entirely in the cloud for free using GitHub Actions, without ever installing it locally.
|
|
162
|
+
|
|
163
|
+
1. **Fork this repository.**
|
|
164
|
+
2. Navigate to your fork's **Settings > Secrets and variables > Actions**.
|
|
165
|
+
3. Add your sensitive API keys as **Repository Secrets**:
|
|
166
|
+
- `ALIF_LLM_API_KEY` (or `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`)
|
|
167
|
+
- `SLACK_WEBHOOK_URL` (or `GENERIC_WEBHOOK_URL`)
|
|
168
|
+
4. Configure your preferences as **Repository Variables** (optional):
|
|
169
|
+
- `ALIF_LLM_PROVIDER` (default: anthropic)
|
|
170
|
+
- `ALIF_LLM_MODEL`
|
|
171
|
+
- `ALIF_SIGNAL_THRESHOLD` (default: 60)
|
|
172
|
+
- `ALIF_MAX_ITEMS_PER_RUN` (default: 10)
|
|
173
|
+
- `ALIF_SOURCE_COOLDOWN_MINUTES` (default: 5)
|
|
174
|
+
|
|
175
|
+
The included workflow (`.github/workflows/alif-scheduled-run.yml`) automatically runs every day at 8:00 AM UTC (feel free to change the schedule in your forked version), caches your database/state, and delivers your customized digest!
|
|
176
|
+
|
|
155
177
|
---
|
|
156
178
|
|
|
157
179
|
## 🤝 Architecture & Contributing
|
|
158
180
|
|
|
159
181
|
Interested in how Alif works under the hood or want to run it locally?
|
|
160
182
|
|
|
161
|
-
Check out our [**Contributing Guidelines**](CONTRIBUTING.md) for information on the architecture, local development setup, and how to submit pull requests!
|
|
183
|
+
Check out our [**Contributing Guidelines**](https://github.com/qaribhaider/alif/blob/main/CONTRIBUTING.md) for information on the architecture, local development setup, and how to submit pull requests!
|
|
162
184
|
|
|
163
185
|
---
|
|
164
186
|
|
package/ROADMAP.md
CHANGED
|
@@ -6,13 +6,7 @@ Items planned for future development, roughly in priority order.
|
|
|
6
6
|
|
|
7
7
|
## 🔴 High Priority
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`alif validate` or an automatic pre-flight check at the start of `alif run` that catches misconfigured/missing API keys, malformed URLs, etc. — before scraping has already happened.
|
|
12
|
-
|
|
13
|
-
### Expand default keywords
|
|
14
|
-
|
|
15
|
-
The default keyword list in `default-keywords.ts` is thin. A richer, categorized list (models, research, tools, policy) would meaningfully improve signal quality out of the box.
|
|
9
|
+
_Currently empty - all planned high-priority features have shipped!_
|
|
16
10
|
|
|
17
11
|
---
|
|
18
12
|
|
|
@@ -2,106 +2,170 @@ import prompts from 'prompts';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { ConfigManager } from '../../core/config-manager.js';
|
|
4
4
|
import { logger } from '../../core/logger.js';
|
|
5
|
-
export async function initCommand() {
|
|
5
|
+
export async function initCommand(options) {
|
|
6
6
|
const configManager = ConfigManager.getInstance();
|
|
7
7
|
const configDir = configManager.getConfigDir();
|
|
8
8
|
logger.log('\n--- Alif Initialization ---');
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
9
|
+
let config;
|
|
10
|
+
if (options?.nonInteractive) {
|
|
11
|
+
logger.info('Running in non-interactive mode. Reading from environment variables...');
|
|
12
|
+
const provider = (process.env.ALIF_LLM_PROVIDER || 'anthropic');
|
|
13
|
+
let apiKey = process.env.ALIF_LLM_API_KEY;
|
|
14
|
+
if (!apiKey) {
|
|
15
|
+
if (provider === 'anthropic')
|
|
16
|
+
apiKey = process.env.ANTHROPIC_API_KEY;
|
|
17
|
+
else if (provider === 'openrouter')
|
|
18
|
+
apiKey = process.env.OPENROUTER_API_KEY || process.env.OPENAI_API_KEY;
|
|
19
|
+
}
|
|
20
|
+
const model = process.env.ALIF_LLM_MODEL ||
|
|
21
|
+
(provider === 'ollama'
|
|
22
|
+
? 'llama3'
|
|
23
|
+
: provider === 'anthropic'
|
|
24
|
+
? 'claude-3-5-sonnet-20240620'
|
|
25
|
+
: 'meta-llama/llama-3-70b-instruct');
|
|
26
|
+
const baseUrl = process.env.ALIF_LLM_BASE_URL ||
|
|
27
|
+
(provider === 'ollama' ? 'http://localhost:11434' : undefined);
|
|
28
|
+
const deliveryConfigs = [];
|
|
29
|
+
if (process.env.SLACK_WEBHOOK_URL) {
|
|
30
|
+
deliveryConfigs.push({ type: 'slack', webhookUrl: process.env.SLACK_WEBHOOK_URL });
|
|
31
|
+
}
|
|
32
|
+
if (process.env.GENERIC_WEBHOOK_URL) {
|
|
33
|
+
deliveryConfigs.push({
|
|
34
|
+
type: 'webhook',
|
|
35
|
+
webhookUrl: process.env.GENERIC_WEBHOOK_URL,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
config = {
|
|
39
|
+
llm: {
|
|
40
|
+
provider,
|
|
41
|
+
apiKey,
|
|
42
|
+
model,
|
|
43
|
+
baseUrl,
|
|
35
44
|
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
name: 'deliveryProviders',
|
|
62
|
-
message: 'Where should we deliver the digest?',
|
|
63
|
-
choices: [
|
|
64
|
-
{ title: 'Slack', value: 'slack' },
|
|
65
|
-
{ title: 'Generic Webhook', value: 'webhook' },
|
|
66
|
-
],
|
|
67
|
-
min: 1,
|
|
68
|
-
},
|
|
69
|
-
]);
|
|
70
|
-
if (!response.llmProvider || !response.deliveryProviders) {
|
|
71
|
-
logger.warn('Initialization cancelled.');
|
|
72
|
-
return;
|
|
45
|
+
delivery: deliveryConfigs,
|
|
46
|
+
preferences: {
|
|
47
|
+
signalThreshold: process.env.ALIF_SIGNAL_THRESHOLD
|
|
48
|
+
? parseInt(process.env.ALIF_SIGNAL_THRESHOLD, 10)
|
|
49
|
+
: 60,
|
|
50
|
+
maxItemsPerRun: process.env.ALIF_MAX_ITEMS_PER_RUN
|
|
51
|
+
? parseInt(process.env.ALIF_MAX_ITEMS_PER_RUN, 10)
|
|
52
|
+
: 10,
|
|
53
|
+
sourceCooldownMinutes: process.env.ALIF_SOURCE_COOLDOWN_MINUTES
|
|
54
|
+
? parseInt(process.env.ALIF_SOURCE_COOLDOWN_MINUTES, 10)
|
|
55
|
+
: 5,
|
|
56
|
+
sequentialAnalysis: process.env.ALIF_SEQUENTIAL_ANALYSIS === 'true' || provider === 'ollama',
|
|
57
|
+
enableAIArticlesScoring: process.env.ALIF_ENABLE_AI_SCORING !== 'false',
|
|
58
|
+
customKeywords: process.env.ALIF_CUSTOM_KEYWORDS
|
|
59
|
+
? JSON.parse(process.env.ALIF_CUSTOM_KEYWORDS)
|
|
60
|
+
: {},
|
|
61
|
+
negativeKeywords: process.env.ALIF_NEGATIVE_KEYWORDS
|
|
62
|
+
? JSON.parse(process.env.ALIF_NEGATIVE_KEYWORDS)
|
|
63
|
+
: {},
|
|
64
|
+
logLevel: process.env.ALIF_LOG_LEVEL || 'normal',
|
|
65
|
+
noColor: process.env.ALIF_NO_COLOR === 'true',
|
|
66
|
+
},
|
|
67
|
+
dbPath: path.join(configDir, 'alif.db'),
|
|
68
|
+
feedsPath: path.join(configDir, 'feeds.json'),
|
|
69
|
+
};
|
|
73
70
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
else {
|
|
72
|
+
const response = await prompts([
|
|
73
|
+
{
|
|
74
|
+
type: 'select',
|
|
75
|
+
name: 'llmProvider',
|
|
76
|
+
message: 'Which LLM provider would you like to use?',
|
|
77
|
+
choices: [
|
|
78
|
+
{ title: 'Ollama (Local)', value: 'ollama' },
|
|
79
|
+
{ title: 'Anthropic', value: 'anthropic' },
|
|
80
|
+
{ title: 'OpenRouter', value: 'openrouter' },
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: (prev) => (prev !== 'ollama' ? 'text' : null),
|
|
85
|
+
name: 'apiKey',
|
|
86
|
+
message: 'Enter your API Key:',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
type: 'text',
|
|
90
|
+
name: 'model',
|
|
91
|
+
message: 'Enter the model name (e.g., llama3, claude-3-opus-20240229):',
|
|
92
|
+
initial: (prev, values) => {
|
|
93
|
+
if (values.llmProvider === 'ollama')
|
|
94
|
+
return 'llama3';
|
|
95
|
+
if (values.llmProvider === 'anthropic')
|
|
96
|
+
return 'claude-3-5-sonnet-20240620';
|
|
97
|
+
return 'meta-llama/llama-3-70b-instruct';
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: (prev, values) => (values.llmProvider === 'ollama' ? 'text' : null),
|
|
102
|
+
name: 'baseUrl',
|
|
103
|
+
message: 'Enter Ollama base URL:',
|
|
104
|
+
initial: 'http://localhost:11434',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: 'toggle',
|
|
108
|
+
name: 'sequentialAnalysis',
|
|
109
|
+
message: 'Enable sequential (one-by-one) LLM processing? (Recommended for small local models)',
|
|
110
|
+
initial: (prev, values) => values.llmProvider === 'ollama',
|
|
111
|
+
active: 'yes',
|
|
112
|
+
inactive: 'no',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: 'toggle',
|
|
116
|
+
name: 'enableAIArticlesScoring',
|
|
117
|
+
message: 'Enable AI Article Scoring? (Uses your LLM to intelligently score articles)',
|
|
118
|
+
initial: true,
|
|
119
|
+
active: 'yes',
|
|
120
|
+
inactive: 'no',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
type: 'multiselect',
|
|
124
|
+
name: 'deliveryProviders',
|
|
125
|
+
message: 'Where should we deliver the digest?',
|
|
126
|
+
choices: [
|
|
127
|
+
{ title: 'Slack', value: 'slack' },
|
|
128
|
+
{ title: 'Generic Webhook', value: 'webhook' },
|
|
129
|
+
],
|
|
130
|
+
min: 1,
|
|
131
|
+
},
|
|
132
|
+
]);
|
|
133
|
+
if (!response.llmProvider || !response.deliveryProviders) {
|
|
134
|
+
logger.warn('Initialization cancelled.');
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const deliveryConfigs = [];
|
|
138
|
+
for (const provider of response.deliveryProviders) {
|
|
139
|
+
const { webhookUrl } = await prompts({
|
|
140
|
+
type: 'text',
|
|
141
|
+
name: 'webhookUrl',
|
|
142
|
+
message: `Enter ${provider} Webhook URL:`,
|
|
143
|
+
});
|
|
144
|
+
deliveryConfigs.push({ type: provider, webhookUrl });
|
|
145
|
+
}
|
|
146
|
+
config = {
|
|
147
|
+
llm: {
|
|
148
|
+
provider: response.llmProvider,
|
|
149
|
+
apiKey: response.apiKey,
|
|
150
|
+
model: response.model,
|
|
151
|
+
baseUrl: response.baseUrl,
|
|
152
|
+
},
|
|
153
|
+
delivery: deliveryConfigs,
|
|
154
|
+
preferences: {
|
|
155
|
+
signalThreshold: 60,
|
|
156
|
+
maxItemsPerRun: 10,
|
|
157
|
+
sourceCooldownMinutes: 5,
|
|
158
|
+
sequentialAnalysis: response.sequentialAnalysis,
|
|
159
|
+
enableAIArticlesScoring: response.enableAIArticlesScoring,
|
|
160
|
+
customKeywords: {},
|
|
161
|
+
negativeKeywords: {},
|
|
162
|
+
logLevel: 'normal',
|
|
163
|
+
noColor: false,
|
|
164
|
+
},
|
|
165
|
+
dbPath: path.join(configDir, 'alif.db'),
|
|
166
|
+
feedsPath: path.join(configDir, 'feeds.json'),
|
|
167
|
+
};
|
|
82
168
|
}
|
|
83
|
-
const config = {
|
|
84
|
-
llm: {
|
|
85
|
-
provider: response.llmProvider,
|
|
86
|
-
apiKey: response.apiKey,
|
|
87
|
-
model: response.model,
|
|
88
|
-
baseUrl: response.baseUrl,
|
|
89
|
-
},
|
|
90
|
-
delivery: deliveryConfigs,
|
|
91
|
-
preferences: {
|
|
92
|
-
signalThreshold: 60,
|
|
93
|
-
maxItemsPerRun: 10,
|
|
94
|
-
sourceCooldownMinutes: 5,
|
|
95
|
-
sequentialAnalysis: response.sequentialAnalysis,
|
|
96
|
-
enableAIArticlesScoring: response.enableAIArticlesScoring,
|
|
97
|
-
customKeywords: {},
|
|
98
|
-
negativeKeywords: {},
|
|
99
|
-
logLevel: 'normal',
|
|
100
|
-
noColor: false,
|
|
101
|
-
},
|
|
102
|
-
dbPath: path.join(configDir, 'alif.db'),
|
|
103
|
-
feedsPath: path.join(configDir, 'feeds.json'),
|
|
104
|
-
};
|
|
105
169
|
configManager.save(config);
|
|
106
170
|
logger.success(`Configuration saved to ${configManager.getConfigFile()}`);
|
|
107
171
|
logger.info(`Database will be located at ${config.dbPath}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,WAAW;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/commands/run.js
CHANGED
|
@@ -4,6 +4,7 @@ import { createDatabase } from '../../db/connection.js';
|
|
|
4
4
|
import { runMigrations } from '../../db/migrate.js';
|
|
5
5
|
import { Pipeline } from '../../core/pipeline.js';
|
|
6
6
|
import { configureLogger, logger } from '../../core/logger.js';
|
|
7
|
+
import { Validator } from '../../core/validator.js';
|
|
7
8
|
export async function runPipeline(config, db, force = false) {
|
|
8
9
|
const pipeline = new Pipeline(config, db);
|
|
9
10
|
// Load feeds
|
|
@@ -31,6 +32,9 @@ export async function runCommand(options = {}) {
|
|
|
31
32
|
noColor: config.preferences.noColor,
|
|
32
33
|
override: options.verbose ? 'verbose' : options.quiet ? 'quiet' : undefined,
|
|
33
34
|
});
|
|
35
|
+
// Pre-flight validation
|
|
36
|
+
const validator = new Validator(config, config.feedsPath);
|
|
37
|
+
validator.printAndExitIfFailed();
|
|
34
38
|
db = createDatabase(config.dbPath);
|
|
35
39
|
runMigrations(db);
|
|
36
40
|
await runPipeline(config, db, options.force);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function validateCommand(): Promise<void>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ConfigManager } from '../../core/config-manager.js';
|
|
2
|
+
import { Validator } from '../../core/validator.js';
|
|
3
|
+
import { logger } from '../../core/logger.js';
|
|
4
|
+
export async function validateCommand() {
|
|
5
|
+
const configManager = ConfigManager.getInstance();
|
|
6
|
+
if (!configManager.exists()) {
|
|
7
|
+
logger.error('Alif is not initialized. Run "alif init" first.');
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const config = configManager.load();
|
|
12
|
+
const validator = new Validator(config, config.feedsPath);
|
|
13
|
+
logger.info('Running pre-flight validation...');
|
|
14
|
+
const failures = validator.validate();
|
|
15
|
+
if (failures.length > 0) {
|
|
16
|
+
logger.error(`Validation failed with ${failures.length} errors:`);
|
|
17
|
+
failures.forEach((f) => logger.error(` [${f.scope}] ${f.message}`));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
logger.success('All configurations and feeds are valid! 🎉');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error instanceof Error) {
|
|
27
|
+
logger.error(`Validation failed exception: ${error.message}`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
logger.error('An unknown error occurred during validation.');
|
|
31
|
+
}
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,aAAa,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;IAElD,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAE1D,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;QAEtC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,UAAU,CAAC,CAAC;YAClE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,gCAAgC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/cli/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { runCommand } from './commands/run.js';
|
|
|
6
6
|
import { scheduleCommand } from './commands/schedule.js';
|
|
7
7
|
import { debugCommand } from './commands/debug.js';
|
|
8
8
|
import { configCommand } from './commands/config.js';
|
|
9
|
+
import { validateCommand } from './commands/validate.js';
|
|
9
10
|
const require = createRequire(import.meta.url);
|
|
10
11
|
const { version } = require('../../package.json');
|
|
11
12
|
const program = new Command();
|
|
@@ -13,8 +14,9 @@ program.name('alif').description('Alif - Daily AI Signal Digest CLI').version(ve
|
|
|
13
14
|
program
|
|
14
15
|
.command('init')
|
|
15
16
|
.description('Initialize Alif configuration')
|
|
16
|
-
.
|
|
17
|
-
|
|
17
|
+
.option('--non-interactive', 'Run without interactive prompts using environment variables')
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
await initCommand(options);
|
|
18
20
|
});
|
|
19
21
|
program
|
|
20
22
|
.command('run')
|
|
@@ -32,6 +34,12 @@ program
|
|
|
32
34
|
.action(async (action) => {
|
|
33
35
|
await scheduleCommand(action);
|
|
34
36
|
});
|
|
37
|
+
program
|
|
38
|
+
.command('validate')
|
|
39
|
+
.description('Run a pre-flight configuration check')
|
|
40
|
+
.action(async () => {
|
|
41
|
+
await validateCommand();
|
|
42
|
+
});
|
|
35
43
|
program.addCommand(debugCommand);
|
|
36
44
|
program.addCommand(configCommand);
|
|
37
45
|
program.parse(process.argv);
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvF,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,mBAAmB,EAAE,6DAA6D,CAAC;KAC1F,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;KAC/C,MAAM,CAAC,eAAe,EAAE,4BAA4B,CAAC;KACrD,MAAM,CAAC,aAAa,EAAE,mCAAmC,CAAC;KAC1D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,yBAAyB,CAAC;KACtC,WAAW,CAAC,OAAO,EAAE,qCAAqC,CAAC;KAC3D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;IACvB,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,eAAe,EAAE,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -8,7 +8,9 @@ export class ConfigManager {
|
|
|
8
8
|
configDir;
|
|
9
9
|
configFile;
|
|
10
10
|
constructor() {
|
|
11
|
-
this.configDir =
|
|
11
|
+
this.configDir = process.env.ALIF_CONFIG_DIR
|
|
12
|
+
? path.resolve(process.env.ALIF_CONFIG_DIR)
|
|
13
|
+
: path.join(os.homedir(), '.config', 'alif');
|
|
12
14
|
this.configFile = path.join(this.configDir, 'config.json');
|
|
13
15
|
}
|
|
14
16
|
static getInstance() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/core/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAU,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,CAAgB;IAC/B,MAAM,GAAkB,IAAI,CAAC;IAC7B,SAAS,CAAS;IAClB,UAAU,CAAS;IAE3B;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/core/config-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Config } from './config-schema.js';
|
|
2
|
+
export interface ValidationFailure {
|
|
3
|
+
scope: 'LLM' | 'Delivery' | 'Feeds' | 'Config';
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class Validator {
|
|
7
|
+
private config;
|
|
8
|
+
private feedsPath;
|
|
9
|
+
constructor(config: Config, feedsPath: string);
|
|
10
|
+
validate(): ValidationFailure[];
|
|
11
|
+
printAndExitIfFailed(): void;
|
|
12
|
+
}
|