run-and-notify 0.1.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/.env.example +3 -0
- package/LICENSE +619 -0
- package/README.md +132 -0
- package/config.example.json +54 -0
- package/dist/bundle/run-and-notify.mjs +516 -0
- package/dist/bundle/run-and-notify.mjs.map +7 -0
- package/examples/apps/daily-digest-failure.mjs +17 -0
- package/examples/apps/daily-digest-html-success.mjs +14 -0
- package/examples/apps/daily-digest-success.mjs +16 -0
- package/examples/apps/full-html.mjs +14 -0
- package/examples/apps/full-markdown.mjs +19 -0
- package/examples/apps/full-raw.mjs +4 -0
- package/examples/apps/structured-jsonl-success.mjs +23 -0
- package/examples/config-html.json +8 -0
- package/examples/config-jsonl.json +8 -0
- package/examples/config-markdown.json +8 -0
- package/examples/config-raw.json +8 -0
- package/examples/daily-digest-html/config.json +46 -0
- package/examples/daily-digest-html/templates/error.email.html.hbs +9 -0
- package/examples/daily-digest-html/templates/error.slack.blocks.json.hbs +9 -0
- package/examples/daily-digest-html/templates/error.subject.hbs +1 -0
- package/examples/daily-digest-html/templates/error.text.hbs +7 -0
- package/examples/daily-digest-html/templates/success.email.html.hbs +1 -0
- package/examples/daily-digest-html/templates/success.slack.blocks.json.hbs +9 -0
- package/examples/daily-digest-html/templates/success.subject.hbs +1 -0
- package/examples/daily-digest-html/templates/success.text.hbs +1 -0
- package/examples/daily-digest-markdown/config.json +46 -0
- package/examples/daily-digest-markdown/templates/error.email.html.hbs +9 -0
- package/examples/daily-digest-markdown/templates/error.slack.blocks.json.hbs +16 -0
- package/examples/daily-digest-markdown/templates/error.subject.hbs +1 -0
- package/examples/daily-digest-markdown/templates/error.text.hbs +9 -0
- package/examples/daily-digest-markdown/templates/success.email.html.hbs +1 -0
- package/examples/daily-digest-markdown/templates/success.slack.blocks.json.hbs +9 -0
- package/examples/daily-digest-markdown/templates/success.subject.hbs +1 -0
- package/examples/daily-digest-markdown/templates/success.text.hbs +1 -0
- package/examples/full-html/config.json +46 -0
- package/examples/full-html/templates/email.html.hbs +22 -0
- package/examples/full-html/templates/slack.blocks.json.hbs +9 -0
- package/examples/full-html/templates/slack.text.hbs +1 -0
- package/examples/full-html/templates/subject.hbs +1 -0
- package/examples/full-html/templates/text.hbs +12 -0
- package/examples/full-markdown/config.json +46 -0
- package/examples/full-markdown/templates/email.html.hbs +1 -0
- package/examples/full-markdown/templates/slack.blocks.json.hbs +9 -0
- package/examples/full-markdown/templates/slack.text.hbs +1 -0
- package/examples/full-markdown/templates/subject.hbs +1 -0
- package/examples/full-markdown/templates/text.hbs +18 -0
- package/examples/full-raw/config.json +46 -0
- package/examples/full-raw/templates/email.html.hbs +22 -0
- package/examples/full-raw/templates/slack.blocks.json.hbs +16 -0
- package/examples/full-raw/templates/slack.text.hbs +1 -0
- package/examples/full-raw/templates/subject.hbs +1 -0
- package/examples/full-raw/templates/text.hbs +12 -0
- package/examples/minimal/config.json +20 -0
- package/examples/structured-jsonl-html/config.json +46 -0
- package/examples/structured-jsonl-html/templates/error.email.html.hbs +6 -0
- package/examples/structured-jsonl-html/templates/error.slack.blocks.json.hbs +9 -0
- package/examples/structured-jsonl-html/templates/error.subject.hbs +1 -0
- package/examples/structured-jsonl-html/templates/error.text.hbs +4 -0
- package/examples/structured-jsonl-html/templates/success.email.html.hbs +16 -0
- package/examples/structured-jsonl-html/templates/success.slack.blocks.json.hbs +9 -0
- package/examples/structured-jsonl-html/templates/success.subject.hbs +1 -0
- package/examples/structured-jsonl-html/templates/success.text.hbs +6 -0
- package/examples/structured-jsonl-markdown/config.json +46 -0
- package/examples/structured-jsonl-markdown/templates/error.email.html.hbs +9 -0
- package/examples/structured-jsonl-markdown/templates/error.slack.blocks.json.hbs +9 -0
- package/examples/structured-jsonl-markdown/templates/error.subject.hbs +1 -0
- package/examples/structured-jsonl-markdown/templates/error.text.hbs +9 -0
- package/examples/structured-jsonl-markdown/templates/success.email.html.hbs +1 -0
- package/examples/structured-jsonl-markdown/templates/success.slack.blocks.json.hbs +9 -0
- package/examples/structured-jsonl-markdown/templates/success.subject.hbs +1 -0
- package/examples/structured-jsonl-markdown/templates/success.text.hbs +19 -0
- package/package.json +79 -0
- package/schemas/config.schema.json +259 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
console.log('# Daily digest');
|
|
2
|
+
console.error(
|
|
3
|
+
JSON.stringify({
|
|
4
|
+
level: 50,
|
|
5
|
+
timestamp: '2026-01-02T12:34:56Z',
|
|
6
|
+
msg: 'report failed because *input* contained <tags>',
|
|
7
|
+
}),
|
|
8
|
+
);
|
|
9
|
+
console.error(
|
|
10
|
+
JSON.stringify({
|
|
11
|
+
level: 40,
|
|
12
|
+
timestamp: '2026-01-02T12:35:20Z',
|
|
13
|
+
code: 'DIGEST_RETRY',
|
|
14
|
+
}),
|
|
15
|
+
);
|
|
16
|
+
console.error('not-json stderr fallback');
|
|
17
|
+
process.exit(2);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
console.log('<h1>Daily digest</h1>');
|
|
2
|
+
console.log('<ul><li>agenda generated</li><li>report mailed</li></ul>');
|
|
3
|
+
console.log('<table><thead><tr><th>Job</th><th>Status</th></tr></thead>');
|
|
4
|
+
console.log(
|
|
5
|
+
'<tbody><tr><td>Agenda</td><td>Ready</td></tr><tr><td>Report</td><td>Sent</td></tr></tbody></table>',
|
|
6
|
+
);
|
|
7
|
+
console.log('<pre><code>daily-report --send</code></pre>');
|
|
8
|
+
console.error(
|
|
9
|
+
JSON.stringify({
|
|
10
|
+
level: 30,
|
|
11
|
+
timestamp: '2026-01-02T12:34:56Z',
|
|
12
|
+
msg: 'success stderr should be omitted',
|
|
13
|
+
}),
|
|
14
|
+
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
console.log('# Daily digest');
|
|
2
|
+
console.log('');
|
|
3
|
+
console.log('- agenda generated');
|
|
4
|
+
console.log('- report mailed');
|
|
5
|
+
console.log('');
|
|
6
|
+
console.log('| Job | Status |');
|
|
7
|
+
console.log('| --- | --- |');
|
|
8
|
+
console.log('| Agenda | Ready |');
|
|
9
|
+
console.log('| Report | Sent |');
|
|
10
|
+
console.error(
|
|
11
|
+
JSON.stringify({
|
|
12
|
+
level: 30,
|
|
13
|
+
timestamp: '2026-01-02T12:34:56Z',
|
|
14
|
+
msg: 'success stderr should be omitted',
|
|
15
|
+
}),
|
|
16
|
+
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
console.log('<h1>Backup report</h1>');
|
|
2
|
+
console.log('<ul>');
|
|
3
|
+
console.log('<li>copied <code>/var/data</code></li>');
|
|
4
|
+
console.log('<li>verified checksum</li>');
|
|
5
|
+
console.log('</ul>');
|
|
6
|
+
console.log('<table><thead><tr><th>Step</th><th>Result</th></tr></thead>');
|
|
7
|
+
console.log(
|
|
8
|
+
'<tbody><tr><td>Copy</td><td>OK</td></tr><tr><td>Verify</td><td>OK</td></tr></tbody></table>',
|
|
9
|
+
);
|
|
10
|
+
console.log(
|
|
11
|
+
'<pre><code>rsync -a /var/data /backup/data\nsha256sum /backup/data/archive.tar</code></pre>',
|
|
12
|
+
);
|
|
13
|
+
console.error('<p><strong>warning:</strong> slow disk</p>');
|
|
14
|
+
console.error('<pre><code>iostat: await > 50ms</code></pre>');
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
console.log('# Backup report');
|
|
2
|
+
console.log('');
|
|
3
|
+
console.log('- copied `/var/data`');
|
|
4
|
+
console.log('- verified checksum');
|
|
5
|
+
console.log('');
|
|
6
|
+
console.log('| Step | Result |');
|
|
7
|
+
console.log('| --- | --- |');
|
|
8
|
+
console.log('| Copy | OK |');
|
|
9
|
+
console.log('| Verify | OK |');
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log('```sh');
|
|
12
|
+
console.log('rsync -a /var/data /backup/data');
|
|
13
|
+
console.log('sha256sum /backup/data/archive.tar');
|
|
14
|
+
console.log('```');
|
|
15
|
+
console.error('**warning:** slow disk');
|
|
16
|
+
console.error('');
|
|
17
|
+
console.error('```text');
|
|
18
|
+
console.error('iostat: await > 50ms');
|
|
19
|
+
console.error('```');
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
console.log(
|
|
2
|
+
JSON.stringify({
|
|
3
|
+
title: 'Structured report',
|
|
4
|
+
items: ['item 1', 'item 2'],
|
|
5
|
+
table: [
|
|
6
|
+
['col-1-row-1', 'col-2-row-1'],
|
|
7
|
+
['col-1-row-2', 'col-2-row-2'],
|
|
8
|
+
],
|
|
9
|
+
date: '2026-01-02T12:34:56Z',
|
|
10
|
+
time: '2026-01-02T12:34:56Z',
|
|
11
|
+
datetime: '2026-01-02T12:34:56Z',
|
|
12
|
+
childHtml: '<p>some html</p>',
|
|
13
|
+
childMarkdown: '**some markdown**',
|
|
14
|
+
childRaw: 'raw text escapes <tags>',
|
|
15
|
+
}),
|
|
16
|
+
);
|
|
17
|
+
console.error(
|
|
18
|
+
JSON.stringify({
|
|
19
|
+
level: 30,
|
|
20
|
+
timestamp: '2026-01-02T12:34:56Z',
|
|
21
|
+
msg: 'structured report completed',
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"locale": "en-US",
|
|
3
|
+
"timeoutSeconds": 0,
|
|
4
|
+
"showStderrIfSuccess": false,
|
|
5
|
+
"templatesDir": "examples/daily-digest-html/templates",
|
|
6
|
+
"stdout": {
|
|
7
|
+
"format": "html"
|
|
8
|
+
},
|
|
9
|
+
"stderr": {
|
|
10
|
+
"format": "jsonl"
|
|
11
|
+
},
|
|
12
|
+
"transports": {
|
|
13
|
+
"smtp": {
|
|
14
|
+
"enabled": true,
|
|
15
|
+
"host": "smtp.example.com",
|
|
16
|
+
"port": 587,
|
|
17
|
+
"from": "run-and-notify@example.com",
|
|
18
|
+
"to": ["digest@example.com"]
|
|
19
|
+
},
|
|
20
|
+
"slack": {
|
|
21
|
+
"enabled": true,
|
|
22
|
+
"tokenEnvVar": "SLACK_BOT_TOKEN",
|
|
23
|
+
"defaultChannel": "#daily-digest"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"success": {
|
|
27
|
+
"email": {
|
|
28
|
+
"subject": "success.subject.hbs",
|
|
29
|
+
"html": "success.email.html.hbs",
|
|
30
|
+
"text": "success.text.hbs"
|
|
31
|
+
},
|
|
32
|
+
"slack": {
|
|
33
|
+
"blocks": "success.slack.blocks.json.hbs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"error": {
|
|
37
|
+
"email": {
|
|
38
|
+
"subject": "error.subject.hbs",
|
|
39
|
+
"html": "error.email.html.hbs",
|
|
40
|
+
"text": "error.text.hbs"
|
|
41
|
+
},
|
|
42
|
+
"slack": {
|
|
43
|
+
"blocks": "error.slack.blocks.json.hbs"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<h1>Daily digest failed</h1>
|
|
2
|
+
<p><strong>CWD:</strong> {{shellToken cwd}}</p>
|
|
3
|
+
<p><strong>Command:</strong> {{shellCommand command}}</p>
|
|
4
|
+
<p><strong>Status:</strong> {{status}}</p>
|
|
5
|
+
<ul>
|
|
6
|
+
{{#each stderr.lines}}
|
|
7
|
+
<li>{{#if timestamp}}{{datetimeFromISO8601 timestamp}} {{{escapeHtml msg}}}{{else}}{{{escapeHtml raw}}}{{/if}}</li>
|
|
8
|
+
{{/each}}
|
|
9
|
+
</ul>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Daily digest failed with status {{status}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{{stdout.html}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Daily digest
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{htmlToMarkdown stdout.html}}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"locale": "en-US",
|
|
3
|
+
"timeoutSeconds": 0,
|
|
4
|
+
"showStderrIfSuccess": false,
|
|
5
|
+
"templatesDir": "examples/daily-digest-markdown/templates",
|
|
6
|
+
"stdout": {
|
|
7
|
+
"format": "markdown"
|
|
8
|
+
},
|
|
9
|
+
"stderr": {
|
|
10
|
+
"format": "jsonl"
|
|
11
|
+
},
|
|
12
|
+
"transports": {
|
|
13
|
+
"smtp": {
|
|
14
|
+
"enabled": true,
|
|
15
|
+
"host": "smtp.example.com",
|
|
16
|
+
"port": 587,
|
|
17
|
+
"from": "run-and-notify@example.com",
|
|
18
|
+
"to": ["digest@example.com"]
|
|
19
|
+
},
|
|
20
|
+
"slack": {
|
|
21
|
+
"enabled": true,
|
|
22
|
+
"tokenEnvVar": "SLACK_BOT_TOKEN",
|
|
23
|
+
"defaultChannel": "#daily-digest"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"success": {
|
|
27
|
+
"email": {
|
|
28
|
+
"subject": "success.subject.hbs",
|
|
29
|
+
"html": "success.email.html.hbs",
|
|
30
|
+
"text": "success.text.hbs"
|
|
31
|
+
},
|
|
32
|
+
"slack": {
|
|
33
|
+
"blocks": "success.slack.blocks.json.hbs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"error": {
|
|
37
|
+
"email": {
|
|
38
|
+
"subject": "error.subject.hbs",
|
|
39
|
+
"html": "error.email.html.hbs",
|
|
40
|
+
"text": "error.text.hbs"
|
|
41
|
+
},
|
|
42
|
+
"slack": {
|
|
43
|
+
"blocks": "error.slack.blocks.json.hbs"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<h1>Daily digest failed</h1>
|
|
2
|
+
<p><strong>CWD:</strong> {{shellToken cwd}}</p>
|
|
3
|
+
<p><strong>Command:</strong> {{shellCommand command}}</p>
|
|
4
|
+
<p><strong>Status:</strong> {{status}}</p>
|
|
5
|
+
<ul>
|
|
6
|
+
{{#each stderr.lines}}
|
|
7
|
+
<li>{{#if timestamp}}{{datetimeFromISO8601 timestamp}} {{{escapeHtml msg}}}{{else}}{{{escapeHtml raw}}}{{/if}}</li>
|
|
8
|
+
{{/each}}
|
|
9
|
+
</ul>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"type": "section",
|
|
4
|
+
"text": {
|
|
5
|
+
"type": "mrkdwn",
|
|
6
|
+
"text": {{{jsonString (concat "*Daily digest failed*" (nl) "*CWD:* `" (shellToken cwd) "`" (nl) "*Command:* `" (shellCommand command) "`" (nl) "*Status:* " status)}}}
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"type": "section",
|
|
11
|
+
"text": {
|
|
12
|
+
"type": "mrkdwn",
|
|
13
|
+
"text": {{{jsonString (slackCodeBlock (concat (datetimeFromISO8601 stderr.lines.[0].timestamp) " " (escapeMarkdown stderr.lines.[0].msg)))}}}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Daily digest failed with status {{status}}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Daily digest failed
|
|
2
|
+
|
|
3
|
+
- CWD: `{{shellToken cwd}}`
|
|
4
|
+
- Command: `{{shellCommand command}}`
|
|
5
|
+
- Status: `{{status}}`
|
|
6
|
+
|
|
7
|
+
{{#each stderr.lines}}
|
|
8
|
+
- {{#if timestamp}}{{datetimeFromISO8601 timestamp}} {{{escapeMarkdown msg}}}{{else}}{{{escapeMarkdown raw}}}{{/if}}
|
|
9
|
+
{{/each}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{{markdownToHtml stdout.markdown}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Daily digest
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{stdout.markdown}}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"locale": "en-US",
|
|
3
|
+
"timeoutSeconds": 0,
|
|
4
|
+
"showStderrIfSuccess": true,
|
|
5
|
+
"templatesDir": "examples/full-html/templates",
|
|
6
|
+
"stdout": {
|
|
7
|
+
"format": "html"
|
|
8
|
+
},
|
|
9
|
+
"stderr": {
|
|
10
|
+
"format": "html"
|
|
11
|
+
},
|
|
12
|
+
"transports": {
|
|
13
|
+
"smtp": {
|
|
14
|
+
"enabled": true,
|
|
15
|
+
"host": "smtp.example.com",
|
|
16
|
+
"port": 587,
|
|
17
|
+
"from": "run-and-notify@example.com",
|
|
18
|
+
"to": ["ops@example.com"]
|
|
19
|
+
},
|
|
20
|
+
"slack": {
|
|
21
|
+
"enabled": true,
|
|
22
|
+
"tokenEnvVar": "SLACK_BOT_TOKEN",
|
|
23
|
+
"defaultChannel": "#critical-ops"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"success": {
|
|
27
|
+
"email": {
|
|
28
|
+
"subject": "subject.hbs",
|
|
29
|
+
"html": "email.html.hbs",
|
|
30
|
+
"text": "text.hbs"
|
|
31
|
+
},
|
|
32
|
+
"slack": {
|
|
33
|
+
"blocks": "slack.blocks.json.hbs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"error": {
|
|
37
|
+
"email": {
|
|
38
|
+
"subject": "subject.hbs",
|
|
39
|
+
"html": "email.html.hbs",
|
|
40
|
+
"text": "text.hbs"
|
|
41
|
+
},
|
|
42
|
+
"slack": {
|
|
43
|
+
"blocks": "slack.blocks.json.hbs"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<main style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #18212f; line-height: 1.5;">
|
|
2
|
+
<section style="border: 1px solid #d9e2ec; border-radius: 16px; overflow: hidden;">
|
|
3
|
+
<header style="background: {{#if status}}#7f1d1d{{else}}#0f766e{{/if}}; color: #f0fdfa; padding: 20px 24px;">
|
|
4
|
+
<p style="margin: 0 0 6px; text-transform: uppercase; letter-spacing: .08em; font-size: 12px;">HTML output</p>
|
|
5
|
+
<h1 style="margin: 0; font-size: 22px;">Command result</h1>
|
|
6
|
+
</header>
|
|
7
|
+
<section style="padding: 18px 24px; background: #f8fafc;">
|
|
8
|
+
<p><strong>Executed:</strong> {{datetimeFromISO8601 executedAt}}</p>
|
|
9
|
+
<p><strong>Command:</strong> <code>{{shellCommand command}}</code></p>
|
|
10
|
+
<p><strong>CWD:</strong> <code>{{shellToken cwd}}</code></p>
|
|
11
|
+
<p><strong>Status:</strong> <code>{{status}}</code></p>
|
|
12
|
+
</section>
|
|
13
|
+
<section style="padding: 20px 24px;">
|
|
14
|
+
<h2>Output</h2>
|
|
15
|
+
{{{stdout.html}}}
|
|
16
|
+
</section>
|
|
17
|
+
<section style="padding: 20px 24px; border-top: 1px solid #e5e7eb;">
|
|
18
|
+
<h2>Errors</h2>
|
|
19
|
+
{{{stderr.html}}}
|
|
20
|
+
</section>
|
|
21
|
+
</section>
|
|
22
|
+
</main>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"type": "section",
|
|
4
|
+
"text": {
|
|
5
|
+
"type": "mrkdwn",
|
|
6
|
+
"text": {{{jsonString (concat "*HTML command result*" (nl) "*Command:* `" (shellCommand command) "`" (nl) "*Status:* " status (nl) "*Executed:* " (datetimeFromISO8601 executedAt) (nl) "*CWD:* `" (shellToken cwd) "`" (nl) (nl) "*Output*" (nl) (slackCodeBlock (htmlToMarkdown stdout.html)) (nl) (nl) "*Errors*" (nl) (slackCodeBlock (htmlToMarkdown stderr.html)))}}}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
html {{shellCommand command}} exited {{status}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[html] {{shellToken command.[0]}} exited {{status}}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# HTML Command Result
|
|
2
|
+
|
|
3
|
+
- Executed: {{datetimeFromISO8601 executedAt}}
|
|
4
|
+
- Command: `{{shellCommand command}}`
|
|
5
|
+
- CWD: `{{shellToken cwd}}`
|
|
6
|
+
- Status: `{{status}}`
|
|
7
|
+
|
|
8
|
+
## Output
|
|
9
|
+
{{htmlToMarkdown stdout.html}}
|
|
10
|
+
|
|
11
|
+
## Errors
|
|
12
|
+
{{htmlToMarkdown stderr.html}}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"locale": "en-US",
|
|
3
|
+
"timeoutSeconds": 0,
|
|
4
|
+
"showStderrIfSuccess": true,
|
|
5
|
+
"templatesDir": "examples/full-markdown/templates",
|
|
6
|
+
"stdout": {
|
|
7
|
+
"format": "markdown"
|
|
8
|
+
},
|
|
9
|
+
"stderr": {
|
|
10
|
+
"format": "markdown"
|
|
11
|
+
},
|
|
12
|
+
"transports": {
|
|
13
|
+
"smtp": {
|
|
14
|
+
"enabled": true,
|
|
15
|
+
"host": "smtp.example.com",
|
|
16
|
+
"port": 587,
|
|
17
|
+
"from": "run-and-notify@example.com",
|
|
18
|
+
"to": ["ops@example.com"]
|
|
19
|
+
},
|
|
20
|
+
"slack": {
|
|
21
|
+
"enabled": true,
|
|
22
|
+
"tokenEnvVar": "SLACK_BOT_TOKEN",
|
|
23
|
+
"defaultChannel": "#critical-ops"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"success": {
|
|
27
|
+
"email": {
|
|
28
|
+
"subject": "subject.hbs",
|
|
29
|
+
"html": "email.html.hbs",
|
|
30
|
+
"text": "text.hbs"
|
|
31
|
+
},
|
|
32
|
+
"slack": {
|
|
33
|
+
"blocks": "slack.blocks.json.hbs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"error": {
|
|
37
|
+
"email": {
|
|
38
|
+
"subject": "subject.hbs",
|
|
39
|
+
"html": "email.html.hbs",
|
|
40
|
+
"text": "text.hbs"
|
|
41
|
+
},
|
|
42
|
+
"slack": {
|
|
43
|
+
"blocks": "slack.blocks.json.hbs"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{{markdownToHtml (concat "# Markdown Command Result" (nl) (nl) "- Executed: " (datetimeFromISO8601 executedAt) (nl) "- Command: `" (shellCommand command) "`" (nl) "- CWD: `" (shellToken cwd) "`" (nl) "- Status: `" status "`" (nl) (nl) "## Output" (nl) (nl) "```markdown" (nl) stdout.markdown (nl) "```" (nl) (nl) "## Errors" (nl) (nl) "```markdown" (nl) stderr.markdown (nl) "```")}}}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"type": "section",
|
|
4
|
+
"text": {
|
|
5
|
+
"type": "mrkdwn",
|
|
6
|
+
"text": {{{jsonString (concat "*Markdown command result*" (nl) "*Command:* `" (shellCommand command) "`" (nl) "*Status:* " status (nl) "*Executed:* " (datetimeFromISO8601 executedAt) (nl) "*CWD:* `" (shellToken cwd) "`" (nl) (nl) "*Output*" (nl) (slackCodeBlock stdout) (nl) (nl) "*Errors*" (nl) (slackCodeBlock stderr))}}}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
markdown {{shellCommand command}} exited {{status}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[markdown] {{shellToken command.[0]}} exited {{status}}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Markdown Command Result
|
|
2
|
+
|
|
3
|
+
- Executed: {{datetimeFromISO8601 executedAt}}
|
|
4
|
+
- Command: `{{shellCommand command}}`
|
|
5
|
+
- CWD: `{{shellToken cwd}}`
|
|
6
|
+
- Status: `{{status}}`
|
|
7
|
+
|
|
8
|
+
## Output
|
|
9
|
+
|
|
10
|
+
```markdown
|
|
11
|
+
{{stdout.markdown}}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Errors
|
|
15
|
+
|
|
16
|
+
```markdown
|
|
17
|
+
{{stderr.markdown}}
|
|
18
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"locale": "en-US",
|
|
3
|
+
"timeoutSeconds": 0,
|
|
4
|
+
"showStderrIfSuccess": true,
|
|
5
|
+
"templatesDir": "examples/full-raw/templates",
|
|
6
|
+
"stdout": {
|
|
7
|
+
"format": "raw"
|
|
8
|
+
},
|
|
9
|
+
"stderr": {
|
|
10
|
+
"format": "raw"
|
|
11
|
+
},
|
|
12
|
+
"transports": {
|
|
13
|
+
"smtp": {
|
|
14
|
+
"enabled": true,
|
|
15
|
+
"host": "smtp.example.com",
|
|
16
|
+
"port": 587,
|
|
17
|
+
"from": "run-and-notify@example.com",
|
|
18
|
+
"to": ["ops@example.com"]
|
|
19
|
+
},
|
|
20
|
+
"slack": {
|
|
21
|
+
"enabled": true,
|
|
22
|
+
"tokenEnvVar": "SLACK_BOT_TOKEN",
|
|
23
|
+
"defaultChannel": "#critical-ops"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"success": {
|
|
27
|
+
"email": {
|
|
28
|
+
"subject": "subject.hbs",
|
|
29
|
+
"html": "email.html.hbs",
|
|
30
|
+
"text": "text.hbs"
|
|
31
|
+
},
|
|
32
|
+
"slack": {
|
|
33
|
+
"blocks": "slack.blocks.json.hbs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"error": {
|
|
37
|
+
"email": {
|
|
38
|
+
"subject": "subject.hbs",
|
|
39
|
+
"html": "email.html.hbs",
|
|
40
|
+
"text": "text.hbs"
|
|
41
|
+
},
|
|
42
|
+
"slack": {
|
|
43
|
+
"blocks": "slack.blocks.json.hbs"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<main style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #18212f; line-height: 1.5;">
|
|
2
|
+
<section style="border: 1px solid #d9e2ec; border-radius: 16px; overflow: hidden;">
|
|
3
|
+
<header style="background: {{#if status}}#7f1d1d{{else}}#111827{{/if}}; color: #f9fafb; padding: 20px 24px;">
|
|
4
|
+
<p style="margin: 0 0 6px; text-transform: uppercase; letter-spacing: .08em; font-size: 12px;">Critical automation</p>
|
|
5
|
+
<h1 style="margin: 0; font-size: 22px;">Raw command result</h1>
|
|
6
|
+
</header>
|
|
7
|
+
<section style="padding: 18px 24px; background: #f8fafc;">
|
|
8
|
+
<p><strong>Executed:</strong> {{datetimeFromISO8601 executedAt}}</p>
|
|
9
|
+
<p><strong>Command:</strong> <code>{{shellCommand command}}</code></p>
|
|
10
|
+
<p><strong>CWD:</strong> <code>{{shellToken cwd}}</code></p>
|
|
11
|
+
<p><strong>Status:</strong> <code>{{status}}</code></p>
|
|
12
|
+
</section>
|
|
13
|
+
<section style="padding: 20px 24px;">
|
|
14
|
+
<h2>Output</h2>
|
|
15
|
+
<pre style="white-space: pre-wrap;">{{{rawToHtml stdout.raw}}}</pre>
|
|
16
|
+
</section>
|
|
17
|
+
<section style="padding: 20px 24px; border-top: 1px solid #e5e7eb;">
|
|
18
|
+
<h2>Errors</h2>
|
|
19
|
+
<pre style="white-space: pre-wrap;">{{{rawToHtml stderr.raw}}}</pre>
|
|
20
|
+
</section>
|
|
21
|
+
</section>
|
|
22
|
+
</main>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"type": "section",
|
|
4
|
+
"text": {
|
|
5
|
+
"type": "mrkdwn",
|
|
6
|
+
"text": {{{jsonString (concat "*Raw command result*" (nl) "*Command:* `" (shellCommand command) "`" (nl) "*Status:* " status (nl) "*Executed:* " (datetimeFromISO8601 executedAt) (nl) "*CWD:* `" (shellToken cwd) "`")}}}
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"type": "section",
|
|
11
|
+
"text": {
|
|
12
|
+
"type": "mrkdwn",
|
|
13
|
+
"text": {{{jsonString (concat "*Output*" (nl) (slackCodeBlock stdout) (nl) (nl) "*Errors*" (nl) (slackCodeBlock stderr))}}}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
raw {{shellCommand command}} exited {{status}} at {{datetimeFromISO8601 executedAt}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[raw] {{shellToken command.[0]}} exited {{status}}
|