figranium 0.12.1 → 0.12.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/LICENSE +674 -674
- package/README.md +336 -336
- package/agent.js +1 -1
- package/bin/cli.js +149 -149
- package/common-utils.js +211 -211
- package/dist/assets/{favicon-DmUMR1rm.svg → favicon-DXDXzv5K.svg} +290 -290
- package/dist/assets/index-BaVlGc48.js +18 -0
- package/dist/assets/index-T2xxnq_A.css +1 -0
- package/dist/favicon.svg +290 -290
- package/dist/figranium_icon.svg +290 -290
- package/dist/figranium_logo.svg +60 -60
- package/dist/index.html +26 -26
- package/dist/novnc.html +108 -108
- package/dist/styles.css +86 -86
- package/extraction-worker.js +211 -207
- package/headful.js +584 -569
- package/html-utils.js +24 -24
- package/package.json +82 -82
- package/proxy-rotation.js +261 -261
- package/proxy-utils.js +84 -84
- package/public/favicon.svg +290 -290
- package/public/figranium_icon.svg +290 -290
- package/public/figranium_logo.svg +60 -60
- package/public/novnc.html +108 -108
- package/public/styles.css +86 -86
- package/scrape.js +389 -389
- package/scripts/postinstall.js +21 -21
- package/server.js +626 -626
- package/src/server/cron-parser.js +325 -316
- package/src/server/routes/schedules.js +171 -171
- package/src/server/scheduler.js +379 -379
- package/url-utils.js +339 -323
- package/user-agent-settings.js +76 -76
- package/dist/assets/index-C2rVEs3q.css +0 -1
- package/dist/assets/index-CvaIUcTv.js +0 -18
package/agent.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('./src/agent/index');
|
|
1
|
+
module.exports = require('./src/agent/index');
|
package/bin/cli.js
CHANGED
|
@@ -1,149 +1,149 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
if (!process.env.NODE_ENV) {
|
|
7
|
-
process.env.NODE_ENV = 'production';
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const rootDir = path.resolve(__dirname, '..');
|
|
11
|
-
process.chdir(rootDir);
|
|
12
|
-
|
|
13
|
-
const args = process.argv.slice(2);
|
|
14
|
-
const flags = {};
|
|
15
|
-
const params = [];
|
|
16
|
-
|
|
17
|
-
for (let i = 0; i < args.length; i++) {
|
|
18
|
-
if (args[i].startsWith('--')) {
|
|
19
|
-
let key = args[i].slice(2);
|
|
20
|
-
let value = true;
|
|
21
|
-
if (key.includes('=')) {
|
|
22
|
-
const parts = key.split('=');
|
|
23
|
-
key = parts[0];
|
|
24
|
-
value = parts.slice(1).join('=');
|
|
25
|
-
} else if (args[i + 1] && !args[i + 1].startsWith('--')) {
|
|
26
|
-
value = args[i + 1];
|
|
27
|
-
i++;
|
|
28
|
-
}
|
|
29
|
-
flags[key] = value;
|
|
30
|
-
} else {
|
|
31
|
-
params.push(args[i]);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (flags.help || flags.h || (params.length === 0 && Object.keys(flags).length === 1 && flags.help)) {
|
|
36
|
-
console.log(`
|
|
37
|
-
Figranium CLI - Deterministic Control for an Agentic World
|
|
38
|
-
|
|
39
|
-
Usage:
|
|
40
|
-
figranium [options]
|
|
41
|
-
figranium --scrape --url <url> [--selector <css>]
|
|
42
|
-
figranium --agent --task <id>
|
|
43
|
-
figranium --headful --url <url>
|
|
44
|
-
|
|
45
|
-
Options:
|
|
46
|
-
--scrape Run a one-off scrape task
|
|
47
|
-
--agent Run a one-off agent task
|
|
48
|
-
--headful Open a headful browser session for manual interaction
|
|
49
|
-
--url <url> Target URL for the task
|
|
50
|
-
--task <id> Run a saved task by its ID
|
|
51
|
-
--selector <css> CSS selector for scraping mode
|
|
52
|
-
--wait <seconds> Seconds to wait after page load
|
|
53
|
-
--port <number> Port for the web dashboard (default: 11345)
|
|
54
|
-
--help, -h Show this help message
|
|
55
|
-
|
|
56
|
-
Environment Variables:
|
|
57
|
-
PORT Port for the server
|
|
58
|
-
SESSION_SECRET Secret for session encryption
|
|
59
|
-
ALLOWED_IPS Comma-separated list of allowed IPs
|
|
60
|
-
|
|
61
|
-
Examples:
|
|
62
|
-
figranium # Starts web dashboard
|
|
63
|
-
figranium --scrape --url google.com # Scrapes Google homepage
|
|
64
|
-
figranium --agent --task my-task-123 # Runs saved agent task
|
|
65
|
-
`);
|
|
66
|
-
process.exit(0);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function start() {
|
|
70
|
-
const isStandalone = flags.scrape || flags.agent || flags.headful || flags.task;
|
|
71
|
-
|
|
72
|
-
if (isStandalone) {
|
|
73
|
-
console.log('Figranium: Initializing standalone execution...');
|
|
74
|
-
const { loadTasks, getTaskById } = require('../src/server/storage');
|
|
75
|
-
|
|
76
|
-
let data = { ...flags };
|
|
77
|
-
const url = flags.url || params[0];
|
|
78
|
-
if (url) data.url = url;
|
|
79
|
-
|
|
80
|
-
if (flags.task) {
|
|
81
|
-
try {
|
|
82
|
-
await loadTasks();
|
|
83
|
-
const task = getTaskById(flags.task);
|
|
84
|
-
if (!task) {
|
|
85
|
-
console.error(`Error: Task "${flags.task}" not found.`);
|
|
86
|
-
process.exit(1);
|
|
87
|
-
}
|
|
88
|
-
console.log(`Loaded task: ${task.name} (${task.mode})`);
|
|
89
|
-
// Merge task data with flags (flags take precedence)
|
|
90
|
-
data = { ...task, ...flags, actions: task.actions };
|
|
91
|
-
if (task.mode === 'scrape' && !flags.agent) flags.scrape = true;
|
|
92
|
-
if (task.mode === 'agent' && !flags.scrape) flags.agent = true;
|
|
93
|
-
} catch (err) {
|
|
94
|
-
console.error('Failed to load tasks:', err.message);
|
|
95
|
-
process.exit(1);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (flags.scrape) {
|
|
100
|
-
const { runScrape } = require('../scrape');
|
|
101
|
-
console.log(`Mode: Scrape | URL: ${data.url}`);
|
|
102
|
-
try {
|
|
103
|
-
const result = await runScrape(data);
|
|
104
|
-
console.log('\n--- Extraction Result ---');
|
|
105
|
-
console.log(JSON.stringify(result.data || result, null, 2));
|
|
106
|
-
process.exit(0);
|
|
107
|
-
} catch (err) {
|
|
108
|
-
console.error('Scrape failed:', err.message);
|
|
109
|
-
process.exit(1);
|
|
110
|
-
}
|
|
111
|
-
} else if (flags.agent) {
|
|
112
|
-
const { runAgent } = require('../src/agent/index');
|
|
113
|
-
console.log(`Mode: Agent | URL: ${data.url || 'None'}`);
|
|
114
|
-
try {
|
|
115
|
-
const result = await runAgent(data);
|
|
116
|
-
console.log('\n--- Agent Execution Finished ---');
|
|
117
|
-
if (result.logs && result.logs.length > 0) {
|
|
118
|
-
console.log('Logs:');
|
|
119
|
-
result.logs.forEach(l => console.log(` ${l}`));
|
|
120
|
-
}
|
|
121
|
-
console.log('\nData Output:');
|
|
122
|
-
console.log(JSON.stringify(result.data || result, null, 2));
|
|
123
|
-
process.exit(0);
|
|
124
|
-
} catch (err) {
|
|
125
|
-
console.error('Agent failed:', err.message);
|
|
126
|
-
process.exit(1);
|
|
127
|
-
}
|
|
128
|
-
} else if (flags.headful) {
|
|
129
|
-
const { runHeadful } = require('../headful');
|
|
130
|
-
console.log(`Mode: Headful | URL: ${data.url}`);
|
|
131
|
-
try {
|
|
132
|
-
await runHeadful(data);
|
|
133
|
-
process.exit(0);
|
|
134
|
-
} catch (err) {
|
|
135
|
-
console.error('Headful failed:', err.message);
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
} else {
|
|
140
|
-
// Default: Start the server
|
|
141
|
-
if (flags.port) process.env.PORT = flags.port;
|
|
142
|
-
require(path.join(rootDir, 'server.js'));
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
start().catch(err => {
|
|
147
|
-
console.error('CLI Fatal Error:', err);
|
|
148
|
-
process.exit(1);
|
|
149
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
if (!process.env.NODE_ENV) {
|
|
7
|
+
process.env.NODE_ENV = 'production';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
11
|
+
process.chdir(rootDir);
|
|
12
|
+
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
const flags = {};
|
|
15
|
+
const params = [];
|
|
16
|
+
|
|
17
|
+
for (let i = 0; i < args.length; i++) {
|
|
18
|
+
if (args[i].startsWith('--')) {
|
|
19
|
+
let key = args[i].slice(2);
|
|
20
|
+
let value = true;
|
|
21
|
+
if (key.includes('=')) {
|
|
22
|
+
const parts = key.split('=');
|
|
23
|
+
key = parts[0];
|
|
24
|
+
value = parts.slice(1).join('=');
|
|
25
|
+
} else if (args[i + 1] && !args[i + 1].startsWith('--')) {
|
|
26
|
+
value = args[i + 1];
|
|
27
|
+
i++;
|
|
28
|
+
}
|
|
29
|
+
flags[key] = value;
|
|
30
|
+
} else {
|
|
31
|
+
params.push(args[i]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (flags.help || flags.h || (params.length === 0 && Object.keys(flags).length === 1 && flags.help)) {
|
|
36
|
+
console.log(`
|
|
37
|
+
Figranium CLI - Deterministic Control for an Agentic World
|
|
38
|
+
|
|
39
|
+
Usage:
|
|
40
|
+
figranium [options]
|
|
41
|
+
figranium --scrape --url <url> [--selector <css>]
|
|
42
|
+
figranium --agent --task <id>
|
|
43
|
+
figranium --headful --url <url>
|
|
44
|
+
|
|
45
|
+
Options:
|
|
46
|
+
--scrape Run a one-off scrape task
|
|
47
|
+
--agent Run a one-off agent task
|
|
48
|
+
--headful Open a headful browser session for manual interaction
|
|
49
|
+
--url <url> Target URL for the task
|
|
50
|
+
--task <id> Run a saved task by its ID
|
|
51
|
+
--selector <css> CSS selector for scraping mode
|
|
52
|
+
--wait <seconds> Seconds to wait after page load
|
|
53
|
+
--port <number> Port for the web dashboard (default: 11345)
|
|
54
|
+
--help, -h Show this help message
|
|
55
|
+
|
|
56
|
+
Environment Variables:
|
|
57
|
+
PORT Port for the server
|
|
58
|
+
SESSION_SECRET Secret for session encryption
|
|
59
|
+
ALLOWED_IPS Comma-separated list of allowed IPs
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
figranium # Starts web dashboard
|
|
63
|
+
figranium --scrape --url google.com # Scrapes Google homepage
|
|
64
|
+
figranium --agent --task my-task-123 # Runs saved agent task
|
|
65
|
+
`);
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function start() {
|
|
70
|
+
const isStandalone = flags.scrape || flags.agent || flags.headful || flags.task;
|
|
71
|
+
|
|
72
|
+
if (isStandalone) {
|
|
73
|
+
console.log('Figranium: Initializing standalone execution...');
|
|
74
|
+
const { loadTasks, getTaskById } = require('../src/server/storage');
|
|
75
|
+
|
|
76
|
+
let data = { ...flags };
|
|
77
|
+
const url = flags.url || params[0];
|
|
78
|
+
if (url) data.url = url;
|
|
79
|
+
|
|
80
|
+
if (flags.task) {
|
|
81
|
+
try {
|
|
82
|
+
await loadTasks();
|
|
83
|
+
const task = getTaskById(flags.task);
|
|
84
|
+
if (!task) {
|
|
85
|
+
console.error(`Error: Task "${flags.task}" not found.`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
console.log(`Loaded task: ${task.name} (${task.mode})`);
|
|
89
|
+
// Merge task data with flags (flags take precedence)
|
|
90
|
+
data = { ...task, ...flags, actions: task.actions };
|
|
91
|
+
if (task.mode === 'scrape' && !flags.agent) flags.scrape = true;
|
|
92
|
+
if (task.mode === 'agent' && !flags.scrape) flags.agent = true;
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.error('Failed to load tasks:', err.message);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (flags.scrape) {
|
|
100
|
+
const { runScrape } = require('../scrape');
|
|
101
|
+
console.log(`Mode: Scrape | URL: ${data.url}`);
|
|
102
|
+
try {
|
|
103
|
+
const result = await runScrape(data);
|
|
104
|
+
console.log('\n--- Extraction Result ---');
|
|
105
|
+
console.log(JSON.stringify(result.data || result, null, 2));
|
|
106
|
+
process.exit(0);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
console.error('Scrape failed:', err.message);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
} else if (flags.agent) {
|
|
112
|
+
const { runAgent } = require('../src/agent/index');
|
|
113
|
+
console.log(`Mode: Agent | URL: ${data.url || 'None'}`);
|
|
114
|
+
try {
|
|
115
|
+
const result = await runAgent(data);
|
|
116
|
+
console.log('\n--- Agent Execution Finished ---');
|
|
117
|
+
if (result.logs && result.logs.length > 0) {
|
|
118
|
+
console.log('Logs:');
|
|
119
|
+
result.logs.forEach(l => console.log(` ${l}`));
|
|
120
|
+
}
|
|
121
|
+
console.log('\nData Output:');
|
|
122
|
+
console.log(JSON.stringify(result.data || result, null, 2));
|
|
123
|
+
process.exit(0);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
console.error('Agent failed:', err.message);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
} else if (flags.headful) {
|
|
129
|
+
const { runHeadful } = require('../headful');
|
|
130
|
+
console.log(`Mode: Headful | URL: ${data.url}`);
|
|
131
|
+
try {
|
|
132
|
+
await runHeadful(data);
|
|
133
|
+
process.exit(0);
|
|
134
|
+
} catch (err) {
|
|
135
|
+
console.error('Headful failed:', err.message);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} else {
|
|
140
|
+
// Default: Start the server
|
|
141
|
+
if (flags.port) process.env.PORT = flags.port;
|
|
142
|
+
require(path.join(rootDir, 'server.js'));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
start().catch(err => {
|
|
147
|
+
console.error('CLI Fatal Error:', err);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
});
|