create-ironclaws 1.0.0 → 1.0.1
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/package.json
CHANGED
|
@@ -11,7 +11,7 @@ USER root
|
|
|
11
11
|
|
|
12
12
|
# Python 3 + pip (requests needed by elastic_query.py)
|
|
13
13
|
RUN apt-get update && apt-get install -y python3 python3-pip && rm -rf /var/lib/apt/lists/*
|
|
14
|
-
RUN pip3 install requests youtube-transcript-api markdownify --break-system-packages
|
|
14
|
+
RUN pip3 install requests tenacity youtube-transcript-api markdownify --break-system-packages
|
|
15
15
|
|
|
16
16
|
# Poetry
|
|
17
17
|
RUN pip3 install poetry --break-system-packages
|
|
@@ -1,92 +1,219 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: slack-formatting
|
|
3
|
-
description: Format messages for Slack using mrkdwn
|
|
3
|
+
description: Format messages for Slack using mrkdwn. All agents in this deployment communicate via Slack — these rules always apply.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Slack
|
|
6
|
+
# Slack Formatting — World-Class Messages
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Every message you send goes to Slack. Slack does not render standard Markdown. Follow these rules exactly.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## The Golden Rules
|
|
13
|
+
|
|
14
|
+
1. `*bold*` — never `**bold**`
|
|
15
|
+
2. `_italic_` — never `*italic*`
|
|
16
|
+
3. No markdown tables — never `| col | col |`
|
|
17
|
+
4. No `##` headings — use `*Bold text*` instead
|
|
18
|
+
5. No `---` horizontal rules
|
|
19
|
+
6. No `[text](url)` — use `<url|text>` instead
|
|
20
|
+
7. Email drafts and code always go in ` ```triple backtick blocks``` `
|
|
21
|
+
8. Emoji add clarity — use them intentionally, not decoratively
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Data without tables
|
|
26
|
+
|
|
27
|
+
Tables don't render. Use these patterns instead:
|
|
28
|
+
|
|
29
|
+
**Field list (best for structured data):**
|
|
30
|
+
```
|
|
31
|
+
*Voucher:* AP-818
|
|
32
|
+
*Vendor:* Metosin Oy
|
|
33
|
+
*Amount:* 325,994.74 NOK
|
|
34
|
+
*Posted:* 2025-08-31
|
|
35
|
+
```
|
|
11
36
|
|
|
12
|
-
|
|
37
|
+
**Compact inline (best for short summaries):**
|
|
38
|
+
```
|
|
39
|
+
AP-818 • Metosin Oy • 325,994.74 NOK • 2025-08-31
|
|
40
|
+
```
|
|
13
41
|
|
|
14
|
-
|
|
42
|
+
**Key-value in code block (best for exact copy-paste, e.g. email drafts):**
|
|
43
|
+
````
|
|
44
|
+
```
|
|
45
|
+
Voucher: AP-818
|
|
46
|
+
Vendor: Metosin Oy
|
|
47
|
+
Amount: 325,994.74 NOK
|
|
48
|
+
Move from: 6784 – Konsulentkostnader Utvikling
|
|
49
|
+
Move to: [INSERT ACCOUNT]
|
|
50
|
+
```
|
|
51
|
+
````
|
|
15
52
|
|
|
16
|
-
|
|
53
|
+
---
|
|
17
54
|
|
|
18
|
-
|
|
19
|
-
|-------|--------|---------|
|
|
20
|
-
| Bold | `*text*` | *bold text* |
|
|
21
|
-
| Italic | `_text_` | _italic text_ |
|
|
22
|
-
| Strikethrough | `~text~` | ~strikethrough~ |
|
|
23
|
-
| Code (inline) | `` `code` `` | `inline code` |
|
|
24
|
-
| Code block | ` ```code``` ` | Multi-line code |
|
|
55
|
+
## Message structure
|
|
25
56
|
|
|
26
|
-
|
|
57
|
+
**Use blank lines to breathe.** Dense walls of text are hard to scan on mobile.
|
|
27
58
|
|
|
59
|
+
**Sections flow like this:**
|
|
28
60
|
```
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
61
|
+
*Title or status line*
|
|
62
|
+
|
|
63
|
+
Short one-line context sentence.
|
|
64
|
+
|
|
65
|
+
:emoji: *Section header*
|
|
66
|
+
Content here
|
|
67
|
+
|
|
68
|
+
:emoji: *Another section*
|
|
69
|
+
Content here
|
|
70
|
+
|
|
71
|
+
> Callout or note for important info
|
|
72
|
+
|
|
73
|
+
_Footer — instructions or next steps_
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Violations and alerts
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
:red_circle: *1 violation found — action required*
|
|
82
|
+
|
|
83
|
+
*Voucher:* AP-818
|
|
84
|
+
*Vendor:* Metosin Oy (Finland)
|
|
85
|
+
*Amount:* 325,994.74 NOK
|
|
86
|
+
*Posted:* 2025-08-31
|
|
87
|
+
*Issue:* Vendor invoice posted to 6784 — must be reclassified by Amesto
|
|
88
|
+
|
|
89
|
+
> Christian — fill in `[INSERT ACCOUNT]` and send the correction email below.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Status summaries
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
:white_check_mark: *Expense check complete — May 2026*
|
|
98
|
+
|
|
99
|
+
• Reports checked: 14 | Expenses: 67
|
|
100
|
+
• :red_circle: 2 red violations | :large_yellow_circle: 7 yellow flags
|
|
101
|
+
• Notifications: 0 (DM sending not yet enabled)
|
|
35
102
|
```
|
|
36
103
|
|
|
37
|
-
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Email and document drafts
|
|
107
|
+
|
|
108
|
+
Always use a triple-backtick code block. This makes it copy-paste ready and visually distinct:
|
|
38
109
|
|
|
39
|
-
|
|
110
|
+
````
|
|
111
|
+
Here's the correction email for Christian to review and send:
|
|
40
112
|
|
|
41
113
|
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
114
|
+
To: [Amesto contact]
|
|
115
|
+
Cc: finance@ardoq.com, Christian Dotterweich <christian.dotterweich@ardoq.com>
|
|
116
|
+
Subject: Correction request — voucher AP-818 — move from 6784 to [INSERT ACCOUNT]
|
|
117
|
+
|
|
118
|
+
Hi [Amesto contact],
|
|
119
|
+
|
|
120
|
+
Please reclassify the following vendor invoice ...
|
|
121
|
+
|
|
122
|
+
Voucher: AP-818
|
|
123
|
+
Vendor: Metosin Oy
|
|
124
|
+
Amount: 325,994.74 NOK
|
|
125
|
+
Move from: 6784 – Konsulentkostnader Utvikling
|
|
126
|
+
Move to: [INSERT ACCOUNT]
|
|
127
|
+
|
|
128
|
+
Thanks,
|
|
129
|
+
Christian Dotterweich
|
|
45
130
|
```
|
|
131
|
+
````
|
|
132
|
+
|
|
133
|
+
---
|
|
46
134
|
|
|
47
|
-
|
|
135
|
+
## Progress updates (mid-run)
|
|
48
136
|
|
|
49
|
-
|
|
137
|
+
Use `send_message` for long-running tasks so people know you're working:
|
|
50
138
|
|
|
51
139
|
```
|
|
52
|
-
|
|
53
|
-
|
|
140
|
+
:hourglass_flowing_sand: Fetching transactions from Xledger...
|
|
141
|
+
```
|
|
142
|
+
```
|
|
143
|
+
:mag: Found 3 entries on account 6784 — running classification...
|
|
54
144
|
```
|
|
55
145
|
|
|
56
|
-
|
|
146
|
+
---
|
|
57
147
|
|
|
58
|
-
|
|
148
|
+
## Escalations and warnings
|
|
59
149
|
|
|
60
|
-
|
|
150
|
+
```
|
|
151
|
+
:rotating_light: *Annual true-up required — December close*
|
|
61
152
|
|
|
62
|
-
|
|
63
|
-
- **NO** `**double asterisks**` for bold (use `*single asterisks*`)
|
|
64
|
-
- **NO** `[text](url)` links (use `<url|text>` instead)
|
|
65
|
-
- **NO** `1.` numbered lists (use bullets with numbers: `• 1. First`)
|
|
66
|
-
- **NO** tables (use code blocks or plain text alignment)
|
|
67
|
-
- **NO** `---` horizontal rules
|
|
153
|
+
The December close report cannot be marked complete until the annual true-up is logged.
|
|
68
154
|
|
|
69
|
-
|
|
155
|
+
Reply with:
|
|
156
|
+
`annual true-up done 2025: <summary including adjustment amount>`
|
|
157
|
+
```
|
|
70
158
|
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Confirmations and success
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
:white_check_mark: *Done* — session flagged as resolved in state/flagged_6784.json
|
|
71
165
|
```
|
|
72
|
-
*Daily Standup Summary*
|
|
73
166
|
|
|
74
|
-
|
|
167
|
+
```
|
|
168
|
+
:white_check_mark: *Reconciliation complete — 6784 — 2025-08*
|
|
169
|
+
|
|
170
|
+
:red_circle: 1 violation | :large_green_circle: 1 compliant | no volume flag
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
75
174
|
|
|
76
|
-
|
|
77
|
-
• *In Progress:* Building new dashboard widgets
|
|
78
|
-
• *Blocked:* Waiting on API access from DevOps
|
|
175
|
+
## Lists
|
|
79
176
|
|
|
80
|
-
|
|
177
|
+
Use `•` for bullets. Never `1.` numbered lists (they don't render as lists in Slack):
|
|
81
178
|
|
|
82
|
-
:white_check_mark: All tests passing | <https://ci.example.com/builds/123|View Build>
|
|
83
179
|
```
|
|
180
|
+
What was checked:
|
|
181
|
+
• Account 6784 — Konsulentkostnader Utvikling
|
|
182
|
+
• Period: 2025-08 (August)
|
|
183
|
+
• Source: Xledger GraphQL API
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Mentions and links
|
|
84
189
|
|
|
85
|
-
|
|
190
|
+
```
|
|
191
|
+
<@U04S2VA1CU8> # Mention a specific user
|
|
192
|
+
<#C0B36KNFDHV|finance-close-ops> # Link a channel
|
|
193
|
+
<https://expensify.com/report?id=123|View report> # Named link
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Dividers and spacing
|
|
199
|
+
|
|
200
|
+
Never use `---`. Use blank lines between sections. For a hard visual break, use a line of spaces or just let the sections breathe naturally.
|
|
201
|
+
|
|
202
|
+
---
|
|
86
203
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
204
|
+
## Quick cheat sheet
|
|
205
|
+
|
|
206
|
+
| Goal | Use |
|
|
207
|
+
|------|-----|
|
|
208
|
+
| Bold | `*text*` |
|
|
209
|
+
| Italic | `_text_` |
|
|
210
|
+
| Code inline | `` `code` `` |
|
|
211
|
+
| Code block | ` ```block``` ` |
|
|
212
|
+
| Bullet | `•` |
|
|
213
|
+
| Blockquote | `> text` |
|
|
214
|
+
| Link | `<url\|text>` |
|
|
215
|
+
| Mention user | `<@USERID>` |
|
|
216
|
+
| Emoji | `:white_check_mark:` |
|
|
217
|
+
| "Heading" | `*Bold line*` then blank line |
|
|
218
|
+
| Table | Field list or code block |
|
|
219
|
+
| Divider | Blank line |
|
package/template/src/index.ts
CHANGED
|
@@ -87,23 +87,21 @@ const queue = new GroupQueue();
|
|
|
87
87
|
|
|
88
88
|
const onecli = new OneCLI({ url: ONECLI_URL });
|
|
89
89
|
|
|
90
|
-
function ensureOneCLIAgent(jid: string, group: RegisteredGroup): void {
|
|
90
|
+
async function ensureOneCLIAgent(jid: string, group: RegisteredGroup): Promise<void> {
|
|
91
91
|
if (group.isMain) return;
|
|
92
92
|
const identifier = group.folder.toLowerCase().replace(/_/g, '-');
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
(err) => {
|
|
93
|
+
try {
|
|
94
|
+
const res = await onecli.ensureAgent({ name: group.name, identifier });
|
|
95
|
+
logger.info(
|
|
96
|
+
{ jid, identifier, created: res.created },
|
|
97
|
+
'OneCLI agent ensured',
|
|
98
|
+
);
|
|
99
|
+
} catch (err) {
|
|
101
100
|
logger.debug(
|
|
102
101
|
{ jid, identifier, err: String(err) },
|
|
103
102
|
'OneCLI agent ensure skipped',
|
|
104
103
|
);
|
|
105
|
-
|
|
106
|
-
);
|
|
104
|
+
}
|
|
107
105
|
}
|
|
108
106
|
|
|
109
107
|
function loadState(): void {
|
|
@@ -757,15 +755,19 @@ async function main(): Promise<void> {
|
|
|
757
755
|
// Auto-register any agents from agents.yaml whose channel env vars are set.
|
|
758
756
|
autoRegisterAgentsFromYaml();
|
|
759
757
|
|
|
758
|
+
// Ensure all registered agents exist in OneCLI's PostgreSQL FIRST — must complete
|
|
759
|
+
// before ensureOneCLISecrets() runs, otherwise the secrets script cannot link
|
|
760
|
+
// secrets to agents that don't exist in OneCLI yet (race condition for new agents).
|
|
761
|
+
await Promise.all(
|
|
762
|
+
Object.entries(registeredGroups).map(([jid, group]) =>
|
|
763
|
+
ensureOneCLIAgent(jid, group),
|
|
764
|
+
),
|
|
765
|
+
);
|
|
766
|
+
|
|
760
767
|
// Ensure OneCLI secrets are up to date (re-runs only when credentials change).
|
|
768
|
+
// Runs after ensureOneCLIAgent so agents are guaranteed to exist in OneCLI.
|
|
761
769
|
ensureOneCLISecrets();
|
|
762
770
|
|
|
763
|
-
// Ensure OneCLI agents exist for all registered groups.
|
|
764
|
-
// Recovers from missed creates (e.g. OneCLI was down at registration time).
|
|
765
|
-
for (const [jid, group] of Object.entries(registeredGroups)) {
|
|
766
|
-
ensureOneCLIAgent(jid, group);
|
|
767
|
-
}
|
|
768
|
-
|
|
769
771
|
restoreRemoteControl();
|
|
770
772
|
|
|
771
773
|
// Graceful shutdown handlers
|