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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-ironclaws",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Create an IronClaws AI agent platform in seconds",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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 syntax. Use when responding to Slack channels (folder starts with "slack_" or JID contains slack identifiers).
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 Message Formatting (mrkdwn)
6
+ # Slack Formatting — World-Class Messages
7
7
 
8
- When responding to Slack channels, use Slack's mrkdwn syntax instead of standard Markdown.
8
+ Every message you send goes to Slack. Slack does not render standard Markdown. Follow these rules exactly.
9
9
 
10
- ## Slack context
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
- All agents in this deployment communicate via Slack. These formatting rules always apply.
37
+ **Compact inline (best for short summaries):**
38
+ ```
39
+ AP-818 • Metosin Oy • 325,994.74 NOK • 2025-08-31
40
+ ```
13
41
 
14
- ## Formatting reference
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
- ### Text styles
53
+ ---
17
54
 
18
- | Style | Syntax | Example |
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
- ### Links and mentions
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
- <https://example.com|Link text> # Named link
30
- <https://example.com> # Auto-linked URL
31
- <@U1234567890> # Mention user by ID
32
- <#C1234567890> # Mention channel by ID
33
- <!here> # @here
34
- <!channel> # @channel
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
- ### Lists
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
- Slack supports simple bullet lists but NOT numbered lists:
110
+ ````
111
+ Here's the correction email for Christian to review and send:
40
112
 
41
113
  ```
42
- First item
43
- Second item
44
- Third item
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
- Use `•` (bullet character) or `- ` or `* ` for bullets.
135
+ ## Progress updates (mid-run)
48
136
 
49
- ### Block quotes
137
+ Use `send_message` for long-running tasks so people know you're working:
50
138
 
51
139
  ```
52
- > This is a block quote
53
- > It can span multiple lines
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
- ### Emoji
146
+ ---
57
147
 
58
- Use standard emoji shortcodes: `:white_check_mark:`, `:x:`, `:rocket:`, `:tada:`
148
+ ## Escalations and warnings
59
149
 
60
- ## What NOT to use
150
+ ```
151
+ :rotating_light: *Annual true-up required — December close*
61
152
 
62
- - **NO** `##` headings (use `*Bold text*` for headers instead)
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
- ## Example message
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
- _March 21, 2026_
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
- *Completed:* Fixed authentication bug in login flow
77
- • *In Progress:* Building new dashboard widgets
78
- • *Blocked:* Waiting on API access from DevOps
175
+ ## Lists
79
176
 
80
- > Next sync: Monday 10am
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
- ## Quick rules
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
- 1. Use `*bold*` not `**bold**`
88
- 2. Use `<url|text>` not `[text](url)`
89
- 3. Use `•` bullets, avoid numbered lists
90
- 4. Use `:emoji:` shortcodes
91
- 5. Quote blocks with `>`
92
- 6. Skip headings use bold text instead
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 |
@@ -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
- onecli.ensureAgent({ name: group.name, identifier }).then(
94
- (res) => {
95
- logger.info(
96
- { jid, identifier, created: res.created },
97
- 'OneCLI agent ensured',
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