@sulala/agent 0.1.6 → 0.1.7
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 +3 -2
- package/context/airtable.md +35 -0
- package/context/asana.md +37 -0
- package/context/bluesky.md +26 -91
- package/context/calendar.md +63 -0
- package/context/country-info.md +13 -0
- package/context/create-skill.md +128 -0
- package/context/discord.md +30 -0
- package/context/docs.md +29 -0
- package/context/drive.md +49 -0
- package/context/dropbox.md +39 -0
- package/context/facebook.md +47 -0
- package/context/fetch-form-api.md +16 -0
- package/context/figma.md +30 -0
- package/context/github.md +58 -0
- package/context/gmail.md +52 -0
- package/context/google.md +28 -0
- package/context/hellohub.md +29 -0
- package/context/jira.md +46 -0
- package/context/linear.md +40 -0
- package/context/notion.md +45 -0
- package/context/portal-integrations.md +42 -0
- package/context/post-to-x.md +50 -0
- package/context/sheets.md +47 -0
- package/context/slack.md +48 -0
- package/context/slides.md +35 -0
- package/context/stripe.md +38 -0
- package/context/tes.md +7 -0
- package/context/test.md +7 -0
- package/context/zoom.md +28 -0
- package/dist/agent/google/calendar.d.ts +2 -0
- package/dist/agent/google/calendar.d.ts.map +1 -0
- package/dist/agent/google/calendar.js +119 -0
- package/dist/agent/google/calendar.js.map +1 -0
- package/dist/agent/google/drive.d.ts +2 -0
- package/dist/agent/google/drive.d.ts.map +1 -0
- package/dist/agent/google/drive.js +51 -0
- package/dist/agent/google/drive.js.map +1 -0
- package/dist/agent/google/get-token.d.ts +7 -0
- package/dist/agent/google/get-token.d.ts.map +1 -0
- package/dist/agent/google/get-token.js +37 -0
- package/dist/agent/google/get-token.js.map +1 -0
- package/dist/agent/google/gmail.d.ts +2 -0
- package/dist/agent/google/gmail.d.ts.map +1 -0
- package/dist/agent/google/gmail.js +138 -0
- package/dist/agent/google/gmail.js.map +1 -0
- package/dist/agent/google/index.d.ts +2 -0
- package/dist/agent/google/index.d.ts.map +1 -0
- package/dist/agent/google/index.js +13 -0
- package/dist/agent/google/index.js.map +1 -0
- package/dist/agent/loop.d.ts +8 -0
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +226 -40
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory.d.ts +21 -0
- package/dist/agent/memory.d.ts.map +1 -0
- package/dist/agent/memory.js +33 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/pending-actions.d.ts +21 -0
- package/dist/agent/pending-actions.d.ts.map +1 -0
- package/dist/agent/pending-actions.js +65 -0
- package/dist/agent/pending-actions.js.map +1 -0
- package/dist/agent/pi-runner.d.ts +27 -0
- package/dist/agent/pi-runner.d.ts.map +1 -0
- package/dist/agent/pi-runner.js +300 -0
- package/dist/agent/pi-runner.js.map +1 -0
- package/dist/agent/skill-generate.d.ts +63 -0
- package/dist/agent/skill-generate.d.ts.map +1 -0
- package/dist/agent/skill-generate.js +128 -0
- package/dist/agent/skill-generate.js.map +1 -0
- package/dist/agent/skill-install.d.ts.map +1 -1
- package/dist/agent/skill-install.js +80 -31
- package/dist/agent/skill-install.js.map +1 -1
- package/dist/agent/skill-templates.d.ts +17 -0
- package/dist/agent/skill-templates.d.ts.map +1 -0
- package/dist/agent/skill-templates.js +26 -0
- package/dist/agent/skill-templates.js.map +1 -0
- package/dist/agent/skills-config.d.ts +24 -2
- package/dist/agent/skills-config.d.ts.map +1 -1
- package/dist/agent/skills-config.js +107 -8
- package/dist/agent/skills-config.js.map +1 -1
- package/dist/agent/skills-watcher.js +1 -1
- package/dist/agent/skills.d.ts +9 -3
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +104 -9
- package/dist/agent/skills.js.map +1 -1
- package/dist/agent/tools.d.ts +25 -3
- package/dist/agent/tools.d.ts.map +1 -1
- package/dist/agent/tools.integrations.test.d.ts +2 -0
- package/dist/agent/tools.integrations.test.d.ts.map +1 -0
- package/dist/agent/tools.integrations.test.js +269 -0
- package/dist/agent/tools.integrations.test.js.map +1 -0
- package/dist/agent/tools.js +692 -39
- package/dist/agent/tools.js.map +1 -1
- package/dist/ai/orchestrator.d.ts +4 -1
- package/dist/ai/orchestrator.d.ts.map +1 -1
- package/dist/ai/orchestrator.js +246 -14
- package/dist/ai/orchestrator.js.map +1 -1
- package/dist/ai/pricing.d.ts +6 -0
- package/dist/ai/pricing.d.ts.map +1 -0
- package/dist/ai/pricing.js +39 -0
- package/dist/ai/pricing.js.map +1 -0
- package/dist/channels/discord.d.ts +15 -0
- package/dist/channels/discord.d.ts.map +1 -0
- package/dist/channels/discord.js +55 -0
- package/dist/channels/discord.js.map +1 -0
- package/dist/channels/stripe.d.ts +15 -0
- package/dist/channels/stripe.d.ts.map +1 -0
- package/dist/channels/stripe.js +58 -0
- package/dist/channels/stripe.js.map +1 -0
- package/dist/channels/telegram.d.ts +60 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +562 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/cli.js +66 -8
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +85 -1
- package/dist/config.js.map +1 -1
- package/dist/db/index.d.ts +83 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +174 -2
- package/dist/db/index.js.map +1 -1
- package/dist/db/schema.sql +35 -0
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/gateway/server.js +1219 -27
- package/dist/gateway/server.js.map +1 -1
- package/dist/index.js +149 -6
- package/dist/index.js.map +1 -1
- package/dist/ollama-setup.d.ts +27 -0
- package/dist/ollama-setup.d.ts.map +1 -0
- package/dist/ollama-setup.js +191 -0
- package/dist/ollama-setup.js.map +1 -0
- package/dist/onboard-env.d.ts +1 -1
- package/dist/onboard-env.d.ts.map +1 -1
- package/dist/onboard-env.js +2 -0
- package/dist/onboard-env.js.map +1 -1
- package/dist/onboard.d.ts +3 -1
- package/dist/onboard.d.ts.map +1 -1
- package/dist/onboard.js +7 -2
- package/dist/onboard.js.map +1 -1
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +32 -0
- package/dist/plugins/index.js.map +1 -1
- package/dist/redact.d.ts +15 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +56 -0
- package/dist/redact.js.map +1 -0
- package/dist/scheduler/cron.d.ts +21 -0
- package/dist/scheduler/cron.d.ts.map +1 -1
- package/dist/scheduler/cron.js +60 -0
- package/dist/scheduler/cron.js.map +1 -1
- package/dist/system-capabilities.d.ts +11 -0
- package/dist/system-capabilities.d.ts.map +1 -0
- package/dist/system-capabilities.js +109 -0
- package/dist/system-capabilities.js.map +1 -0
- package/dist/types.d.ts +62 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/watcher/index.d.ts +2 -0
- package/dist/watcher/index.d.ts.map +1 -1
- package/dist/watcher/index.js +31 -1
- package/dist/watcher/index.js.map +1 -1
- package/dist/workspace-automations.d.ts +16 -0
- package/dist/workspace-automations.d.ts.map +1 -0
- package/dist/workspace-automations.js +133 -0
- package/dist/workspace-automations.js.map +1 -0
- package/package.json +19 -3
- package/registry/bluesky.md +12 -89
- package/registry/skills-registry.json +6 -0
- package/src/db/schema.sql +35 -0
- package/src/index.ts +159 -6
package/dist/scheduler/cron.js
CHANGED
|
@@ -4,6 +4,7 @@ import { enqueue } from './queue.js';
|
|
|
4
4
|
const jobs = new Map();
|
|
5
5
|
/**
|
|
6
6
|
* Schedule a cron expression to enqueue a task type (with optional payload).
|
|
7
|
+
* Each run inserts a row into the DB and enqueues the task.
|
|
7
8
|
*/
|
|
8
9
|
export function scheduleCron(expression, type, payload = null) {
|
|
9
10
|
if (!cron.validate(expression)) {
|
|
@@ -18,6 +19,65 @@ export function scheduleCron(expression, type, payload = null) {
|
|
|
18
19
|
jobs.set(`${expression}:${type}`, task);
|
|
19
20
|
return task;
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Schedule a cron job by id (for DB/config-driven jobs). Can be unscheduled with unscheduleJob(id).
|
|
24
|
+
*/
|
|
25
|
+
export function scheduleCronById(id, expression, type, payload = null) {
|
|
26
|
+
if (!cron.validate(expression)) {
|
|
27
|
+
throw new Error(`Invalid cron expression: ${expression}`);
|
|
28
|
+
}
|
|
29
|
+
const key = `job:${id}`;
|
|
30
|
+
const existing = jobs.get(key);
|
|
31
|
+
if (existing) {
|
|
32
|
+
existing.stop();
|
|
33
|
+
jobs.delete(key);
|
|
34
|
+
}
|
|
35
|
+
const task = cron.schedule(expression, () => {
|
|
36
|
+
const taskId = `cron_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
37
|
+
insertTask({ id: taskId, type, payload, scheduled_at: Date.now() });
|
|
38
|
+
enqueue(taskId);
|
|
39
|
+
log('scheduler', 'info', `Scheduled job enqueued: ${id} -> ${type}`, { taskId });
|
|
40
|
+
});
|
|
41
|
+
jobs.set(key, task);
|
|
42
|
+
return task;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Remove a scheduled job by id (from scheduleCronById).
|
|
46
|
+
*/
|
|
47
|
+
export function unscheduleJob(id) {
|
|
48
|
+
const key = `job:${id}`;
|
|
49
|
+
const task = jobs.get(key);
|
|
50
|
+
if (task) {
|
|
51
|
+
task.stop();
|
|
52
|
+
jobs.delete(key);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Schedule a cron that runs the task handler directly without persisting to the DB.
|
|
57
|
+
* Use for high-frequency types (e.g. heartbeat) to avoid filling the tasks table.
|
|
58
|
+
*/
|
|
59
|
+
export function scheduleCronEphemeral(expression, type, payload = null, handler) {
|
|
60
|
+
if (!cron.validate(expression)) {
|
|
61
|
+
throw new Error(`Invalid cron expression: ${expression}`);
|
|
62
|
+
}
|
|
63
|
+
const key = `ephemeral:${expression}:${type}`;
|
|
64
|
+
const task = cron.schedule(expression, () => {
|
|
65
|
+
const id = `heartbeat_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
66
|
+
const payloadValue = typeof payload === 'function' ? payload() : payload;
|
|
67
|
+
const synthetic = {
|
|
68
|
+
id,
|
|
69
|
+
type,
|
|
70
|
+
payload: payloadValue,
|
|
71
|
+
retry_count: 0,
|
|
72
|
+
max_retries: 3,
|
|
73
|
+
};
|
|
74
|
+
handler(synthetic).catch((err) => {
|
|
75
|
+
log('scheduler', 'error', `Ephemeral cron failed: ${type}`, { error: String(err) });
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
jobs.set(key, task);
|
|
79
|
+
return task;
|
|
80
|
+
}
|
|
21
81
|
export async function loadAndRunPending() {
|
|
22
82
|
const { loadPendingFromDb } = await import('./queue.js');
|
|
23
83
|
const n = loadPendingFromDb();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/scheduler/cron.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,IAAI,GAAG,IAAI,GAAG,EAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/scheduler/cron.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type SystemCapabilities = {
|
|
2
|
+
storageFreeBytes: number | null;
|
|
3
|
+
isCloudOrContainer: boolean;
|
|
4
|
+
cloudReason: string;
|
|
5
|
+
ollamaSuitable: boolean;
|
|
6
|
+
ollamaSuitableReason: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function getSystemCapabilities(): SystemCapabilities;
|
|
9
|
+
/** Parse model size string like "~4.2GB" or "~1.6GB" to bytes. Returns null if unparseable. */
|
|
10
|
+
export declare function parseModelSizeToBytes(sizeStr: string): number | null;
|
|
11
|
+
//# sourceMappingURL=system-capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-capabilities.d.ts","sourceRoot":"","sources":["../src/system-capabilities.ts"],"names":[],"mappings":"AAyDA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,wBAAgB,qBAAqB,IAAI,kBAAkB,CA+B1D;AAED,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASpE"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System capabilities for Ollama suitability: storage, cloud detection.
|
|
3
|
+
* Used by onboarding to warn or disable Ollama on cloud/weak devices.
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
import { readFileSync } from 'fs';
|
|
7
|
+
import { platform } from 'os';
|
|
8
|
+
const MIN_STORAGE_BYTES = 5 * 1024 * 1024 * 1024; // 5GB for Ollama + models
|
|
9
|
+
function getFreeDiskBytes() {
|
|
10
|
+
try {
|
|
11
|
+
if (platform() === 'win32') {
|
|
12
|
+
const out = execSync('wmic logicaldisk get FreeSpace,DeviceID', { encoding: 'utf8', timeout: 3000 });
|
|
13
|
+
const lines = out.trim().split(/\r?\n/).slice(1);
|
|
14
|
+
let total = 0;
|
|
15
|
+
for (const line of lines) {
|
|
16
|
+
const parts = line.trim().split(/\s+/);
|
|
17
|
+
if (parts.length >= 2) {
|
|
18
|
+
const free = parseInt(parts[0], 10);
|
|
19
|
+
if (!Number.isNaN(free))
|
|
20
|
+
total += free;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return total > 0 ? total : null;
|
|
24
|
+
}
|
|
25
|
+
const out = execSync('df -k . 2>/dev/null | tail -1', { encoding: 'utf8', timeout: 3000 });
|
|
26
|
+
const parts = out.trim().split(/\s+/);
|
|
27
|
+
const avail = parseInt(parts[3], 10); // 4th column is available 1K blocks
|
|
28
|
+
if (!Number.isNaN(avail) && avail >= 0)
|
|
29
|
+
return avail * 1024;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// ignore
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
function isCloudOrContainer() {
|
|
37
|
+
const env = process.env;
|
|
38
|
+
if (env.AWS_EXECUTION_ENV || env.AWS_LAMBDA_FUNCTION_NAME)
|
|
39
|
+
return { cloud: true, reason: 'AWS Lambda' };
|
|
40
|
+
if (env.GCP_PROJECT || env.GOOGLE_CLOUD_PROJECT)
|
|
41
|
+
return { cloud: true, reason: 'Google Cloud' };
|
|
42
|
+
if (Object.keys(env).some((k) => k.startsWith('AZURE_')))
|
|
43
|
+
return { cloud: true, reason: 'Azure' };
|
|
44
|
+
if (env.KUBERNETES_SERVICE_HOST)
|
|
45
|
+
return { cloud: true, reason: 'Kubernetes' };
|
|
46
|
+
if (env.DOCKER === 'true' || env.CONTAINER === 'true')
|
|
47
|
+
return { cloud: true, reason: 'Container' };
|
|
48
|
+
if (env.CI === 'true' || env.GITHUB_ACTIONS === 'true')
|
|
49
|
+
return { cloud: true, reason: 'CI/CD' };
|
|
50
|
+
if (env.CODESPACES === 'true')
|
|
51
|
+
return { cloud: true, reason: 'GitHub Codespaces' };
|
|
52
|
+
try {
|
|
53
|
+
if (platform() === 'linux') {
|
|
54
|
+
const cgroup = readFileSync('/proc/1/cgroup', 'utf8');
|
|
55
|
+
if (cgroup.includes('docker') || cgroup.includes('kubepods')) {
|
|
56
|
+
return { cloud: true, reason: 'Container (cgroup)' };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// ignore
|
|
62
|
+
}
|
|
63
|
+
return { cloud: false, reason: '' };
|
|
64
|
+
}
|
|
65
|
+
export function getSystemCapabilities() {
|
|
66
|
+
const free = getFreeDiskBytes();
|
|
67
|
+
const { cloud, reason } = isCloudOrContainer();
|
|
68
|
+
if (cloud) {
|
|
69
|
+
return {
|
|
70
|
+
storageFreeBytes: free,
|
|
71
|
+
isCloudOrContainer: true,
|
|
72
|
+
cloudReason: reason,
|
|
73
|
+
ollamaSuitable: false,
|
|
74
|
+
ollamaSuitableReason: `Not recommended: Running in ${reason}. Ollama requires a local machine with sufficient storage and compute.`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (free != null && free < MIN_STORAGE_BYTES) {
|
|
78
|
+
return {
|
|
79
|
+
storageFreeBytes: free,
|
|
80
|
+
isCloudOrContainer: false,
|
|
81
|
+
cloudReason: '',
|
|
82
|
+
ollamaSuitable: false,
|
|
83
|
+
ollamaSuitableReason: `Insufficient storage: ${(free / 1024 / 1024 / 1024).toFixed(1)}GB free. Ollama needs at least 5GB.`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
storageFreeBytes: free,
|
|
88
|
+
isCloudOrContainer: false,
|
|
89
|
+
cloudReason: '',
|
|
90
|
+
ollamaSuitable: true,
|
|
91
|
+
ollamaSuitableReason: free != null ? `${(free / 1024 / 1024 / 1024).toFixed(1)}GB free` : 'Storage check unavailable',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** Parse model size string like "~4.2GB" or "~1.6GB" to bytes. Returns null if unparseable. */
|
|
95
|
+
export function parseModelSizeToBytes(sizeStr) {
|
|
96
|
+
if (!sizeStr || typeof sizeStr !== 'string')
|
|
97
|
+
return null;
|
|
98
|
+
const m = sizeStr.match(/~?(\d+(?:\.\d+)?)\s*(GB|MB|gb|mb)/);
|
|
99
|
+
if (!m)
|
|
100
|
+
return null;
|
|
101
|
+
const val = parseFloat(m[1]);
|
|
102
|
+
const unit = m[2].toUpperCase();
|
|
103
|
+
if (unit === 'GB')
|
|
104
|
+
return Math.round(val * 1024 * 1024 * 1024);
|
|
105
|
+
if (unit === 'MB')
|
|
106
|
+
return Math.round(val * 1024 * 1024);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=system-capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-capabilities.js","sourceRoot":"","sources":["../src/system-capabilities.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -28,9 +28,29 @@ export interface Config {
|
|
|
28
28
|
agentToolProfile: 'full' | 'messaging' | 'coding' | 'minimal';
|
|
29
29
|
/** Retry failed tool calls up to this many times with backoff (env AGENT_TOOL_RETRY_COUNT). Default 2. */
|
|
30
30
|
agentToolRetryCount: number;
|
|
31
|
+
/** When true, high-risk tools (write_file, run_command, register_automation) require user approval before running (env AGENT_EXECUTION_PREVIEW=1). */
|
|
32
|
+
agentExecutionPreview: boolean;
|
|
33
|
+
/** Use Pi coding-agent runtime when true (env AGENT_USE_PI). Requires optional deps. Default false. */
|
|
34
|
+
agentUsePi: boolean;
|
|
35
|
+
/** Optional key for shared (cross-session) memory. When set, all sessions use this key for shared scope; when unset, session_key is used per identity (env AGENT_SHARED_MEMORY_KEY). */
|
|
36
|
+
agentSharedMemoryKey: string | null;
|
|
37
|
+
/** Integrations service URL (e.g. http://localhost:1717) for OAuth connections. When set, github_repos and other connection-backed tools are available. Ignored when portal gateway is set. */
|
|
38
|
+
integrationsUrl: string | null;
|
|
39
|
+
/** Portal gateway base URL (e.g. http://localhost:3000). When set with portalApiKey, agent uses Portal → API Keys for connections instead of INTEGRATIONS_URL. */
|
|
40
|
+
portalGatewayUrl: string | null;
|
|
41
|
+
/** Portal API key (from Portal → API Keys). Use with portalGatewayUrl. Sent as Authorization: Bearer <key>. */
|
|
42
|
+
portalApiKey: string | null;
|
|
43
|
+
/** Optional Discord bot token (env DISCORD_BOT_TOKEN). When set, discord_list_guilds, discord_list_channels, discord_send_message are available. */
|
|
44
|
+
discordBotToken: string | null;
|
|
45
|
+
/** Optional Stripe secret key (env STRIPE_SECRET_KEY). When set, stripe_* tools are available. Can override via Settings → Channels (Stripe). */
|
|
46
|
+
stripeSecretKey: string | null;
|
|
31
47
|
/** Bundled skills dir, e.g. <project>/context. */
|
|
32
48
|
skillsBundledDir: string;
|
|
33
|
-
/**
|
|
49
|
+
/** Workspace root: ~/.sulala/workspace (env SULALA_WORKSPACE_DIR). Contains skills/, scripts/, .env, automations.json. Agent can write scripts and credentials here. */
|
|
50
|
+
workspaceDir: string;
|
|
51
|
+
/** Workspace skills dir: ~/.sulala/workspace/skills/<skill-name>/SKILL.md (env SULALA_WORKSPACE_SKILLS_DIR). User-created skills here are not overwritten by project updates. */
|
|
52
|
+
skillsWorkspaceDir: string;
|
|
53
|
+
/** Managed skills dir, e.g. ~/.sulala/skills (env SULALA_SKILLS_DIR). Flat .md files for registry installs. */
|
|
34
54
|
skillsManagedDir: string;
|
|
35
55
|
/** Extra skill dirs (env SKILLS_EXTRA_DIRS). */
|
|
36
56
|
skillsExtraDirs: string[];
|
|
@@ -38,6 +58,19 @@ export interface Config {
|
|
|
38
58
|
skillsPluginDirs: string[];
|
|
39
59
|
/** Watch skill dirs (env SKILLS_WATCH). */
|
|
40
60
|
skillsWatch: boolean;
|
|
61
|
+
/** Telegram channel (OpenClaw-style): enable bot, token, DM policy. */
|
|
62
|
+
telegram: {
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
botToken: string | null;
|
|
65
|
+
/** Who can DM the bot: "open" (anyone), "allowlist" (only allowFrom), "disabled". */
|
|
66
|
+
dmPolicy: 'open' | 'allowlist' | 'disabled';
|
|
67
|
+
/** Numeric Telegram user IDs allowed when dmPolicy is "allowlist". Comma-separated in env. */
|
|
68
|
+
allowFrom: number[];
|
|
69
|
+
/** Optional: AI provider for Telegram (e.g. "ollama"). Env: TELEGRAM_DEFAULT_PROVIDER. */
|
|
70
|
+
defaultProvider?: string | null;
|
|
71
|
+
/** Optional: AI model for Telegram (e.g. "llama3.2:1b"). Env: TELEGRAM_DEFAULT_MODEL. */
|
|
72
|
+
defaultModel?: string | null;
|
|
73
|
+
};
|
|
41
74
|
}
|
|
42
75
|
/** Task row from DB */
|
|
43
76
|
export interface TaskRow {
|
|
@@ -87,6 +120,7 @@ export interface AIAdapter {
|
|
|
87
120
|
parameters?: Record<string, unknown>;
|
|
88
121
|
}>;
|
|
89
122
|
signal?: AbortSignal;
|
|
123
|
+
think?: boolean;
|
|
90
124
|
}): Promise<{
|
|
91
125
|
content: string;
|
|
92
126
|
usage?: Record<string, number>;
|
|
@@ -112,11 +146,21 @@ export interface CompleteOptions {
|
|
|
112
146
|
parameters?: Record<string, unknown>;
|
|
113
147
|
}>;
|
|
114
148
|
signal?: AbortSignal;
|
|
149
|
+
/** Enable reasoning trace for thinking-capable models (e.g. Ollama deepseek-r1, qwen3). */
|
|
150
|
+
think?: boolean;
|
|
151
|
+
}
|
|
152
|
+
/** Ollama pull progress for UI */
|
|
153
|
+
export interface OllamaPullState {
|
|
154
|
+
inProgress: boolean;
|
|
155
|
+
model: string;
|
|
156
|
+
lastLine: string;
|
|
157
|
+
percent: number;
|
|
115
158
|
}
|
|
116
159
|
/** Express app with optional locals */
|
|
117
160
|
export interface AppLocals {
|
|
118
161
|
wsBroadcast?: (data: unknown) => void;
|
|
119
162
|
enqueueTaskId?: (id: string) => void;
|
|
163
|
+
ollamaPullState?: OllamaPullState;
|
|
120
164
|
}
|
|
121
165
|
/** Agent session (DB row) */
|
|
122
166
|
export interface AgentSessionRow {
|
|
@@ -136,6 +180,8 @@ export interface AgentMessageRow {
|
|
|
136
180
|
tool_call_id: string | null;
|
|
137
181
|
name: string | null;
|
|
138
182
|
created_at: number;
|
|
183
|
+
usage?: string | null;
|
|
184
|
+
cost_usd?: number | null;
|
|
139
185
|
}
|
|
140
186
|
/** Message format for AI / agent loop */
|
|
141
187
|
export interface AgentTurnMessage {
|
|
@@ -149,13 +195,26 @@ export interface AgentTurnMessage {
|
|
|
149
195
|
tool_call_id?: string;
|
|
150
196
|
name?: string;
|
|
151
197
|
}
|
|
152
|
-
/**
|
|
198
|
+
/** Context passed when executing a tool (OpenClaw-style: abort signal, tool call id, session for memory). */
|
|
199
|
+
export interface ToolExecuteContext {
|
|
200
|
+
/** Tool call id from the model (e.g. for logging or idempotency). */
|
|
201
|
+
toolCallId?: string;
|
|
202
|
+
/** Abort signal so long-running tools can respect cancellation. */
|
|
203
|
+
signal?: AbortSignal;
|
|
204
|
+
/** Optional callback for streaming partial results (future use). */
|
|
205
|
+
onUpdate?: (chunk: unknown) => void;
|
|
206
|
+
/** Session id (for memory tools: session-scoped and shared scope_key resolution). */
|
|
207
|
+
sessionId?: string;
|
|
208
|
+
}
|
|
209
|
+
/** Tool definition for registry. execute may accept optional context (signal, toolCallId). */
|
|
153
210
|
export interface ToolDef {
|
|
154
211
|
name: string;
|
|
155
212
|
description: string;
|
|
156
213
|
parameters?: Record<string, unknown>;
|
|
157
|
-
execute: (args: Record<string, unknown
|
|
214
|
+
execute: (args: Record<string, unknown>, context?: ToolExecuteContext) => Promise<unknown> | unknown;
|
|
158
215
|
/** Optional profile hint: which profile includes this tool (default 'full'). */
|
|
159
216
|
profile?: 'full' | 'messaging' | 'coding' | 'minimal';
|
|
217
|
+
/** If true, only available when explicitly allowed (e.g. plugin allowlist). */
|
|
218
|
+
ownerOnly?: boolean;
|
|
160
219
|
}
|
|
161
220
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,8EAA8E;IAC9E,cAAc,EAAE,MAAM,CAAC;IACvB,qHAAqH;IACrH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kGAAkG;IAClG,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,2HAA2H;IAC3H,uBAAuB,EAAE,MAAM,CAAC;IAChC,wHAAwH;IACxH,qBAAqB,EAAE,MAAM,CAAC;IAC9B,4HAA4H;IAC5H,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC9D,0GAA0G;IAC1G,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,gBAAgB,EAAE,MAAM,CAAC;IACzB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/watcher/index.d.ts
CHANGED
|
@@ -11,5 +11,7 @@ export declare function startWatcher(folders?: string[] | null, options?: {
|
|
|
11
11
|
ignoreInitial?: boolean;
|
|
12
12
|
}): FSWatcher | null;
|
|
13
13
|
export declare function enqueueTaskOnEvent(payload: FileEventPayload): void;
|
|
14
|
+
/** Add paths to the running watcher (e.g. after register_automation). If watcher was never started, starts it with all automation folders + config so new images trigger automations without restart. */
|
|
15
|
+
export declare function addWatchPaths(paths: string[]): void;
|
|
14
16
|
export declare function stopWatcher(): void;
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAQpD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAE9E;AA2BD,wBAAgB,YAAY,CAC1B,OAAO,GAAE,MAAM,EAAE,GAAG,IAAW,EAC/B,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACxC,SAAS,GAAG,IAAI,CA0ClB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CASlE;AAED,yMAAyM;AACzM,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAmBnD;AAED,wBAAgB,WAAW,IAAI,IAAI,CAKlC"}
|
package/dist/watcher/index.js
CHANGED
|
@@ -2,6 +2,8 @@ import chokidar from 'chokidar';
|
|
|
2
2
|
import { statSync } from 'fs';
|
|
3
3
|
import { config } from '../config.js';
|
|
4
4
|
import { initDb, getDb, log, upsertFileState, insertTask } from '../db/index.js';
|
|
5
|
+
import { getWatchFoldersFromAutomations } from '../workspace-automations.js';
|
|
6
|
+
import { enqueue } from '../scheduler/queue.js';
|
|
5
7
|
let watcher = null;
|
|
6
8
|
let eventCallback = null;
|
|
7
9
|
export function setEventCallback(fn) {
|
|
@@ -22,6 +24,7 @@ function emit(event, path, stats) {
|
|
|
22
24
|
if (event !== 'unlink' && payload.mtimeMs != null) {
|
|
23
25
|
upsertFileState(path, payload.mtimeMs, payload.size ?? null);
|
|
24
26
|
}
|
|
27
|
+
console.log('[watcher] File', event + ':', path);
|
|
25
28
|
log('watcher', 'info', `${event}: ${path}`, payload);
|
|
26
29
|
if (eventCallback)
|
|
27
30
|
eventCallback(payload);
|
|
@@ -37,6 +40,7 @@ export function startWatcher(folders = null, options = {}) {
|
|
|
37
40
|
initDb(config.dbPath);
|
|
38
41
|
const paths = folders?.length ? folders : config.watchFolders;
|
|
39
42
|
if (!paths.length) {
|
|
43
|
+
console.log('[watcher] Not started — no watch folders configured');
|
|
40
44
|
log('watcher', 'info', 'No watch folders configured; skipping file watcher');
|
|
41
45
|
return null;
|
|
42
46
|
}
|
|
@@ -67,16 +71,42 @@ export function startWatcher(folders = null, options = {}) {
|
|
|
67
71
|
})
|
|
68
72
|
.on('unlink', (path) => emit('unlink', path, null))
|
|
69
73
|
.on('error', (err) => log('watcher', 'error', err instanceof Error ? err.message : String(err), err instanceof Error ? { stack: err.stack } : null));
|
|
74
|
+
console.log('[watcher] Started watching', paths.length, 'folder(s):', paths.join(', '));
|
|
70
75
|
log('watcher', 'info', 'Watching folders', { paths });
|
|
71
76
|
return watcher;
|
|
72
77
|
}
|
|
73
78
|
export function enqueueTaskOnEvent(payload) {
|
|
79
|
+
const taskId = `ev_${payload.ts}_${Math.random().toString(36).slice(2, 9)}`;
|
|
74
80
|
insertTask({
|
|
75
|
-
id:
|
|
81
|
+
id: taskId,
|
|
76
82
|
type: 'file_event',
|
|
77
83
|
payload,
|
|
78
84
|
max_retries: 2,
|
|
79
85
|
});
|
|
86
|
+
enqueue(taskId);
|
|
87
|
+
}
|
|
88
|
+
/** Add paths to the running watcher (e.g. after register_automation). If watcher was never started, starts it with all automation folders + config so new images trigger automations without restart. */
|
|
89
|
+
export function addWatchPaths(paths) {
|
|
90
|
+
if (!paths.length)
|
|
91
|
+
return;
|
|
92
|
+
if (!watcher) {
|
|
93
|
+
const automationFolders = getWatchFoldersFromAutomations();
|
|
94
|
+
const allPaths = [...new Set([...config.watchFolders, ...automationFolders])];
|
|
95
|
+
if (!allPaths.length) {
|
|
96
|
+
console.log('[watcher] register_automation: no paths to watch, watcher not started');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
startWatcher(allPaths);
|
|
100
|
+
console.log('[watcher] Started from register_automation — now watching', allPaths.length, 'folder(s):', allPaths.join(', '));
|
|
101
|
+
log('watcher', 'info', 'Started watcher from register_automation', { paths: allPaths });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
for (const p of paths) {
|
|
105
|
+
if (p?.trim())
|
|
106
|
+
watcher.add(p.trim());
|
|
107
|
+
}
|
|
108
|
+
console.log('[watcher] Added', paths.length, 'path(s) to watcher:', paths.join(', '));
|
|
109
|
+
log('watcher', 'info', 'Added watch paths', { paths });
|
|
80
110
|
}
|
|
81
111
|
export function stopWatcher() {
|
|
82
112
|
if (watcher) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAA4B,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface AutomationEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
script: string;
|
|
4
|
+
watch_folders: string[];
|
|
5
|
+
filter?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AutomationsFile {
|
|
8
|
+
automations?: AutomationEntry[];
|
|
9
|
+
}
|
|
10
|
+
export declare function getAutomationsPath(): string;
|
|
11
|
+
export declare function loadAutomations(): AutomationEntry[];
|
|
12
|
+
/** All unique watch_folders from automations.json (for merging with config.watchFolders at startup). */
|
|
13
|
+
export declare function getWatchFoldersFromAutomations(): string[];
|
|
14
|
+
/** Run scripts for automations that match this file event. */
|
|
15
|
+
export declare function runMatchingAutomations(event: string, filePath: string): void;
|
|
16
|
+
//# sourceMappingURL=workspace-automations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-automations.d.ts","sourceRoot":"","sources":["../src/workspace-automations.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC;AAaD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAgB,eAAe,IAAI,eAAe,EAAE,CASnD;AAED,wGAAwG;AACxG,wBAAgB,8BAA8B,IAAI,MAAM,EAAE,CASzD;AAED,8DAA8D;AAC9D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAgF5E"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace automations: load from ~/.sulala/workspace/automations.json and run scripts
|
|
3
|
+
* when file events match (watch_folders + optional filter). Script is run with env from
|
|
4
|
+
* workspace/.env and the file path as first argument.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, existsSync, chmodSync } from 'fs';
|
|
7
|
+
import { join, resolve } from 'path';
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import { config } from './config.js';
|
|
10
|
+
import { log } from './db/index.js';
|
|
11
|
+
const IMAGE_EXT = /\.(jpg|jpeg|png|gif|webp)$/i;
|
|
12
|
+
function isImage(path) {
|
|
13
|
+
return IMAGE_EXT.test(path);
|
|
14
|
+
}
|
|
15
|
+
function matchesFilter(path, filter) {
|
|
16
|
+
if (!filter || filter.toLowerCase() === 'image')
|
|
17
|
+
return isImage(path);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
export function getAutomationsPath() {
|
|
21
|
+
return join(resolve(config.workspaceDir), 'automations.json');
|
|
22
|
+
}
|
|
23
|
+
export function loadAutomations() {
|
|
24
|
+
const path = getAutomationsPath();
|
|
25
|
+
if (!existsSync(path))
|
|
26
|
+
return [];
|
|
27
|
+
try {
|
|
28
|
+
const data = JSON.parse(readFileSync(path, 'utf8'));
|
|
29
|
+
return Array.isArray(data.automations) ? data.automations : [];
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** All unique watch_folders from automations.json (for merging with config.watchFolders at startup). */
|
|
36
|
+
export function getWatchFoldersFromAutomations() {
|
|
37
|
+
const list = loadAutomations();
|
|
38
|
+
const set = new Set();
|
|
39
|
+
for (const a of list) {
|
|
40
|
+
for (const f of a.watch_folders || []) {
|
|
41
|
+
if (f?.trim())
|
|
42
|
+
set.add(resolve(f.trim()));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return [...set];
|
|
46
|
+
}
|
|
47
|
+
/** Run scripts for automations that match this file event. */
|
|
48
|
+
export function runMatchingAutomations(event, filePath) {
|
|
49
|
+
if (event !== 'add')
|
|
50
|
+
return;
|
|
51
|
+
const pathResolved = resolve(filePath);
|
|
52
|
+
const automations = loadAutomations();
|
|
53
|
+
const workspaceDir = resolve(config.workspaceDir);
|
|
54
|
+
for (const a of automations) {
|
|
55
|
+
const inFolder = (a.watch_folders || []).some((dir) => {
|
|
56
|
+
const d = resolve(dir);
|
|
57
|
+
return pathResolved === d || pathResolved.startsWith(d + '/');
|
|
58
|
+
});
|
|
59
|
+
if (!inFolder)
|
|
60
|
+
continue;
|
|
61
|
+
if (!matchesFilter(pathResolved, a.filter))
|
|
62
|
+
continue;
|
|
63
|
+
const scriptPath = a.script.startsWith('/') ? a.script : join(workspaceDir, a.script);
|
|
64
|
+
if (!existsSync(scriptPath)) {
|
|
65
|
+
log('automations', 'warn', `Script not found: ${scriptPath}`, { automationId: a.id });
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const scriptExt = scriptPath.toLowerCase().slice(scriptPath.lastIndexOf('.'));
|
|
69
|
+
if (['.sh', '.bash', '.py'].includes(scriptExt)) {
|
|
70
|
+
try {
|
|
71
|
+
chmodSync(scriptPath, 0o755);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// ignore chmod errors (e.g. read-only fs)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const envPath = join(workspaceDir, '.env');
|
|
78
|
+
const env = {};
|
|
79
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
80
|
+
if (v !== undefined)
|
|
81
|
+
env[k] = v;
|
|
82
|
+
}
|
|
83
|
+
if (existsSync(envPath)) {
|
|
84
|
+
try {
|
|
85
|
+
const content = readFileSync(envPath, 'utf8');
|
|
86
|
+
for (const line of content.split('\n')) {
|
|
87
|
+
const trimmed = line.trim();
|
|
88
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
89
|
+
continue;
|
|
90
|
+
const eq = trimmed.indexOf('=');
|
|
91
|
+
if (eq > 0) {
|
|
92
|
+
const key = trimmed.slice(0, eq).trim();
|
|
93
|
+
const value = trimmed.slice(eq + 1).trim();
|
|
94
|
+
if (key)
|
|
95
|
+
env[key] = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
log('automations', 'warn', `Could not load workspace .env: ${e.message}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
console.log('[automations] Running', a.id, '→', scriptPath, pathResolved);
|
|
104
|
+
const lower = scriptPath.toLowerCase();
|
|
105
|
+
const isSh = lower.endsWith('.sh');
|
|
106
|
+
const isJs = lower.endsWith('.js') || lower.endsWith('.mjs');
|
|
107
|
+
const cmd = isSh ? 'bash' : isJs ? 'node' : scriptPath;
|
|
108
|
+
const argv = isSh ? [scriptPath, pathResolved] : isJs ? [scriptPath, pathResolved] : [pathResolved];
|
|
109
|
+
const child = spawn(cmd, argv, {
|
|
110
|
+
env,
|
|
111
|
+
cwd: workspaceDir,
|
|
112
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
113
|
+
});
|
|
114
|
+
let out = '';
|
|
115
|
+
let err = '';
|
|
116
|
+
child.stdout?.on('data', (chunk) => { out += chunk; });
|
|
117
|
+
child.stderr?.on('data', (chunk) => { err += chunk; });
|
|
118
|
+
child.on('close', (code) => {
|
|
119
|
+
if (code !== 0) {
|
|
120
|
+
console.log('[automations]', a.id, 'failed exit code', code, err.slice(0, 200));
|
|
121
|
+
log('automations', 'error', `Automation ${a.id} script failed`, { scriptPath, code, stderr: err.slice(0, 500) });
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
console.log('[automations]', a.id, 'completed');
|
|
125
|
+
log('automations', 'info', `Automation ${a.id} completed`, { path: pathResolved });
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
child.on('error', (e) => {
|
|
129
|
+
log('automations', 'error', `Automation ${a.id} spawn error`, { scriptPath, error: e.message });
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=workspace-automations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-automations.js","sourceRoot":"","sources":["../src/workspace-automations.ts"],"names":[],"mappings":"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"}
|