@ouro.bot/cli 0.1.0-alpha.823 → 0.1.0-alpha.825
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/changelog.json +12 -0
- package/deploy/unraid/sanctuary.ouro/bundle-meta.json +1 -1
- package/deploy/unraid/sanctuary.xml +1 -1
- package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +12 -0
- package/dist/senses/telegram-effect-adapter.js +38 -9
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.825",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Sanctuary: a single nested emphasis no longer makes a whole Butler reply render as literal asterisks."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"version": "0.1.0-alpha.824",
|
|
12
|
+
"changes": [
|
|
13
|
+
"Sanctuary: vault removal is reachable only from the authority install transaction, so the destructive verb can no longer be run bare against a host with no root authority installed."
|
|
14
|
+
]
|
|
15
|
+
},
|
|
4
16
|
{
|
|
5
17
|
"version": "0.1.0-alpha.823",
|
|
6
18
|
"changes": [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0"?>
|
|
2
2
|
<Container version="2">
|
|
3
3
|
<Name>ouro-butler</Name>
|
|
4
|
-
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.
|
|
4
|
+
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.825</Repository>
|
|
5
5
|
<Registry>https://github.com/ourostack/ouroboros/pkgs/container/ouroboros-butler</Registry>
|
|
6
6
|
<Network>host</Network>
|
|
7
7
|
<Shell>sh</Shell>
|
|
@@ -739,6 +739,7 @@ class SanctuaryAuthorityRootLifecycle {
|
|
|
739
739
|
"--mount", `type=bind,src=${BUNDLE},dst=/home/ouro/AgentBundles/sanctuary.ouro,readonly`,
|
|
740
740
|
"--tmpfs", "/home/ouro/.ouro-cli/bitwarden:rw,nosuid,nodev,noexec,mode=0700",
|
|
741
741
|
"--tmpfs", "/tmp:rw,nosuid,nodev,noexec,mode=0700",
|
|
742
|
+
"--env", `OURO_AUTHORITY_REMOVE_INTERLOCK=${this.#request.epochId}`,
|
|
742
743
|
this.#transaction.targetImageId, "/opt/ouro/dist/heart/daemon/sanctuary-authority-root-lifecycle.js", "vault", operation,
|
|
743
744
|
], input === undefined ? undefined : JSON.stringify(input)));
|
|
744
745
|
}
|
|
@@ -748,6 +749,17 @@ async function runSanctuaryAuthorityRootCli(argv, write = (text) => process.stdo
|
|
|
748
749
|
if (process.getuid() !== 0 || process.getgid() !== 0)
|
|
749
750
|
throw new Error("Sanctuary root lifecycle requires root");
|
|
750
751
|
if (argv.length === 2 && argv[0] === "vault") {
|
|
752
|
+
// `remove` is the one vault verb that can strand the household. It is safe
|
|
753
|
+
// only inside the install transaction, which has already proven the same
|
|
754
|
+
// token into root custody at `verify-token-rotation`. Run bare against a
|
|
755
|
+
// host with no installed root authority it leaves the Butler with no route
|
|
756
|
+
// to Telegram at all, which is how Sanctuary lost its front door on
|
|
757
|
+
// 2026-09-21. This is a safety interlock against invoking it outside its
|
|
758
|
+
// transaction, not a privilege boundary: root can always set the variable,
|
|
759
|
+
// but it can no longer do this by reaching for a documented verb.
|
|
760
|
+
if (argv[1] === "remove" && !process.env.OURO_AUTHORITY_REMOVE_INTERLOCK) {
|
|
761
|
+
throw new Error("Sanctuary vault removal runs only inside the authority install transaction; use docker-man-template-transaction.mjs authority-install");
|
|
762
|
+
}
|
|
751
763
|
const input = argv[1] === "restore" ? JSON.parse(fs.readFileSync(0, "utf8")) : undefined;
|
|
752
764
|
write(`${JSON.stringify(await (0, sanctuary_authority_vault_migration_1.migrateSanctuaryAuthorityVault)(argv[1], input))}\n`);
|
|
753
765
|
return;
|
|
@@ -76,25 +76,54 @@ function preparedTexts(effect) {
|
|
|
76
76
|
return [requireText(effect.text, "Telegram text")];
|
|
77
77
|
return [effect.text?.trim() || null];
|
|
78
78
|
}
|
|
79
|
+
// Bold spans may carry one level of emphasis inside them, because `**bold with
|
|
80
|
+
// *italic* inside**` is ordinary model prose. The inner span is rendered by the
|
|
81
|
+
// same conservative scan, so a bold run that does not resolve cleanly still
|
|
82
|
+
// degrades the whole message to literal text rather than emitting partial
|
|
83
|
+
// markup. Everything else stays as strict as before: a span must open on a
|
|
84
|
+
// letter or digit and close on a non-space, which is what keeps `**/src/**`,
|
|
85
|
+
// `2 ** 3` and `a_b_c` literal.
|
|
86
|
+
const TELEGRAM_BOLD_WITH_NESTING = /`([^`\n]+)`|\*\*([\p{L}\p{N}](?:[^*_`\n]|\*(?!\*)|_)*\S|[\p{L}\p{N}])\*\*|\*([\p{L}\p{N}](?:[^*_`\n]*\S)?)\*|_([\p{L}\p{N}](?:[^*_`\n]*\S)?)_/gu;
|
|
87
|
+
const TELEGRAM_EMPHASIS_ONLY = /`([^`\n]+)`|\*([\p{L}\p{N}](?:[^*_`\n]*\S)?)\*|_([\p{L}\p{N}](?:[^*_`\n]*\S)?)_/gu;
|
|
79
88
|
function renderTelegramButlerHtml(text) {
|
|
89
|
+
return renderTelegramStyledSpan(text, true) ?? (0, telegram_client_1.escapeTelegramHtml)(text);
|
|
90
|
+
}
|
|
91
|
+
// Returns null when the span cannot be rendered cleanly, so every caller falls
|
|
92
|
+
// back to escaping rather than emitting half-applied markup.
|
|
93
|
+
function renderTelegramStyledSpan(text, allowBold) {
|
|
80
94
|
let html = "";
|
|
81
95
|
let cursor = 0;
|
|
82
|
-
const
|
|
83
|
-
|
|
96
|
+
const pattern = allowBold ? TELEGRAM_BOLD_WITH_NESTING : TELEGRAM_EMPHASIS_ONLY;
|
|
97
|
+
pattern.lastIndex = 0;
|
|
98
|
+
for (const match of text.matchAll(pattern)) {
|
|
84
99
|
const gap = text.slice(cursor, match.index);
|
|
85
100
|
if (/[*_`]/u.test(gap))
|
|
86
|
-
return
|
|
101
|
+
return null;
|
|
87
102
|
html += (0, telegram_client_1.escapeTelegramHtml)(gap);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
103
|
+
const code = match[1];
|
|
104
|
+
const bold = allowBold ? match[2] : undefined;
|
|
105
|
+
const italic = allowBold ? match[3] : match[2];
|
|
106
|
+
const underscored = allowBold ? match[4] : match[3];
|
|
107
|
+
if (code !== undefined)
|
|
108
|
+
html += `<code>${(0, telegram_client_1.escapeTelegramHtml)(code)}</code>`;
|
|
109
|
+
else if (bold !== undefined) {
|
|
110
|
+
const inner = renderTelegramStyledSpan(bold, false);
|
|
111
|
+
if (inner === null)
|
|
112
|
+
return null;
|
|
113
|
+
html += `<b>${inner}</b>`;
|
|
114
|
+
// A single-marker span is bold at the top level, which is the long-standing
|
|
115
|
+
// convention here, but inside a bold run it is the nested emphasis the
|
|
116
|
+
// author meant - and nesting <b> in <b> would be markup Telegram has no
|
|
117
|
+
// reason to accept.
|
|
118
|
+
}
|
|
119
|
+
else if (italic !== undefined)
|
|
120
|
+
html += allowBold ? `<b>${(0, telegram_client_1.escapeTelegramHtml)(italic)}</b>` : `<i>${(0, telegram_client_1.escapeTelegramHtml)(italic)}</i>`;
|
|
92
121
|
else
|
|
93
|
-
html += `<i>${(0, telegram_client_1.escapeTelegramHtml)(
|
|
122
|
+
html += `<i>${(0, telegram_client_1.escapeTelegramHtml)(underscored)}</i>`;
|
|
94
123
|
cursor = match.index + match[0].length;
|
|
95
124
|
}
|
|
96
125
|
const tail = text.slice(cursor);
|
|
97
|
-
return /[*_`]/u.test(tail) ?
|
|
126
|
+
return /[*_`]/u.test(tail) ? null : html + (0, telegram_client_1.escapeTelegramHtml)(tail);
|
|
98
127
|
}
|
|
99
128
|
function assertEffectTarget(target, effect, idempotencyKey) {
|
|
100
129
|
if (target.kind === "admission_gate") {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.825",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@ouro.bot/cli",
|
|
9
|
-
"version": "0.1.0-alpha.
|
|
9
|
+
"version": "0.1.0-alpha.825",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
12
12
|
"@azure/identity": "^4.13.0",
|