toolroll 0.9.53 → 0.9.55
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.md +17 -0
- package/README.md +5 -4
- package/dist/agent-onboard.js +4 -1
- package/dist/approval-rules-ui.d.ts +3 -2
- package/dist/approval-rules-ui.js +15 -20
- package/dist/assignment-ui.d.ts +3 -2
- package/dist/assignment-ui.js +4 -11
- package/dist/backup-ui.d.ts +2 -1
- package/dist/backup-ui.js +16 -27
- package/dist/brand-mark.d.ts +3 -2
- package/dist/brand-mark.js +4 -4
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +25 -25
- package/dist/browser-shell.d.ts +2 -1
- package/dist/browser-shell.js +9 -9
- package/dist/browser-workspace.d.ts +2 -3
- package/dist/browser-workspace.js +0 -3
- package/dist/chat-ask.js +8 -8
- package/dist/chat-core.d.ts +171 -0
- package/dist/chat-core.js +288 -0
- package/dist/chat-decide.d.ts +10 -8
- package/dist/chat-decide.js +26 -21
- package/dist/chat-delivery-state.d.ts +51 -75
- package/dist/chat-delivery-state.js +140 -170
- package/dist/chat-delivery.d.ts +21 -2
- package/dist/chat-delivery.js +313 -194
- package/dist/chat-flow.d.ts +29 -1
- package/dist/chat-flow.js +24 -50
- package/dist/chat-messages.d.ts +319 -0
- package/dist/chat-messages.js +841 -0
- package/dist/chat-migration.d.ts +30 -0
- package/dist/chat-migration.js +802 -0
- package/dist/chat-polish.d.ts +5 -4
- package/dist/chat-polish.js +9 -10
- package/dist/chat-quiet.d.ts +3 -0
- package/dist/chat-quiet.js +5 -0
- package/dist/check-levels-ui.d.ts +2 -1
- package/dist/check-levels-ui.js +26 -53
- package/dist/cli.d.ts +3 -1
- package/dist/cli.js +9 -3
- package/dist/coding-shipping-ui.d.ts +2 -1
- package/dist/coding-shipping-ui.js +6 -6
- package/dist/coding-ui.d.ts +3 -1
- package/dist/coding-ui.js +30 -29
- package/dist/contracts/chat-content.d.ts +71 -2
- package/dist/contracts/chat-content.js +22 -3
- package/dist/contracts/chat-tables.d.ts +11 -4
- package/dist/contracts/chat-tables.js +165 -87
- package/dist/contracts/cli.d.ts +1 -3
- package/dist/contracts/console-api.d.ts +1 -1
- package/dist/contracts/console-api.js +6 -5
- package/dist/contracts/discord-callback.js +2 -1
- package/dist/contracts/health.d.ts +1 -3
- package/dist/contracts/slack-callback.js +3 -2
- package/dist/contracts/store-json.d.ts +1 -5
- package/dist/contracts/store-json.js +1 -4
- package/dist/contracts/teams-callback.js +2 -1
- package/dist/control-ui.d.ts +5 -4
- package/dist/control-ui.js +9 -34
- package/dist/credentials-ui.d.ts +5 -4
- package/dist/credentials-ui.js +23 -24
- package/dist/demo-chat.d.ts +3 -3
- package/dist/demo-chat.js +29 -76
- package/dist/discord-chat.js +19 -38
- package/dist/discord-settings.d.ts +3 -2
- package/dist/discord-settings.js +21 -55
- package/dist/discord.js +4 -14
- package/dist/envelope.js +10 -0
- package/dist/evidence-pack.d.ts +2 -1
- package/dist/evidence-pack.js +45 -49
- package/dist/export-ui.d.ts +7 -2
- package/dist/export-ui.js +4 -10
- package/dist/export.js +4 -4
- package/dist/flow-gallery-ui.d.ts +4 -3
- package/dist/flow-gallery-ui.js +28 -43
- package/dist/flow-starters-ui.d.ts +2 -1
- package/dist/flow-starters-ui.js +12 -15
- package/dist/flow-triggers.d.ts +1 -0
- package/dist/flow-triggers.js +16 -14
- package/dist/flows-ui.d.ts +4 -3
- package/dist/flows-ui.js +19 -30
- package/dist/flows.js +2 -1
- package/dist/guides.js +108 -3
- package/dist/html.d.ts +76 -0
- package/dist/html.js +173 -0
- package/dist/integrations-ui.d.ts +2 -1
- package/dist/integrations-ui.js +19 -23
- package/dist/kits-ui.d.ts +5 -4
- package/dist/kits-ui.js +18 -20
- package/dist/knowledge-ui.d.ts +6 -5
- package/dist/knowledge-ui.js +26 -25
- package/dist/lead-context.d.ts +11 -1
- package/dist/lead-context.js +6 -8
- package/dist/ledger-view.d.ts +2 -1
- package/dist/ledger-view.js +27 -29
- package/dist/limits-ui.d.ts +2 -1
- package/dist/limits-ui.js +7 -7
- package/dist/live-bus.d.ts +50 -8
- package/dist/live-bus.js +133 -50
- package/dist/mate-tools.js +3 -2
- package/dist/mcp-oauth.js +35 -36
- package/dist/models-ui.d.ts +2 -1
- package/dist/models-ui.js +25 -35
- package/dist/modes.d.ts +13 -1
- package/dist/modes.js +17 -1
- package/dist/monitoring-ui.d.ts +4 -3
- package/dist/monitoring-ui.js +13 -26
- package/dist/notification-rows.d.ts +30 -0
- package/dist/notification-rows.js +102 -0
- package/dist/openrouter-models.d.ts +2 -1
- package/dist/openrouter-models.js +5 -9
- package/dist/operate.js +16 -9
- package/dist/people-audit-ui.d.ts +2 -1
- package/dist/people-audit-ui.js +13 -13
- package/dist/plane-review.js +5 -11
- package/dist/policy-ui.d.ts +3 -2
- package/dist/policy-ui.js +17 -23
- package/dist/project-delete-ui.d.ts +4 -3
- package/dist/project-delete-ui.js +15 -27
- package/dist/project-delete.js +21 -26
- package/dist/pull-request-ui.d.ts +2 -1
- package/dist/pull-request-ui.js +17 -32
- package/dist/recipe-ui.d.ts +8 -7
- package/dist/recipe-ui.js +39 -32
- package/dist/release-adapters.d.ts +60 -0
- package/dist/release-adapters.js +435 -0
- package/dist/release-cli.d.ts +24 -0
- package/dist/release-cli.js +181 -0
- package/dist/release-gate.d.ts +80 -0
- package/dist/release-gate.js +150 -0
- package/dist/release-links.d.ts +29 -0
- package/dist/release-links.js +102 -0
- package/dist/release.d.ts +331 -0
- package/dist/release.js +550 -0
- package/dist/reply-shape.d.ts +2 -1
- package/dist/reply-shape.js +5 -5
- package/dist/repository-context-ui.d.ts +2 -1
- package/dist/repository-context-ui.js +2 -7
- package/dist/request-budget-ui.d.ts +2 -1
- package/dist/request-budget-ui.js +16 -16
- package/dist/result-review.d.ts +2 -3
- package/dist/result-review.js +3 -9
- package/dist/result-shots.js +2 -2
- package/dist/retention-ui.d.ts +7 -1
- package/dist/retention-ui.js +7 -11
- package/dist/retention.js +1 -1
- package/dist/serve.d.ts +11 -2
- package/dist/serve.js +69 -58
- package/dist/server/chat.d.ts +3 -6
- package/dist/server/chat.js +969 -1006
- package/dist/server/chrome.d.ts +291 -0
- package/dist/server/chrome.js +747 -0
- package/dist/server/console.css +2819 -0
- package/dist/server/flows.d.ts +2 -6
- package/dist/server/flows.js +840 -766
- package/dist/server/guards.d.ts +1 -1
- package/dist/server/guards.js +5 -2
- package/dist/server/handler-context.d.ts +1 -1
- package/dist/server/handler-context.js +1 -1
- package/dist/server/handler-registry.d.ts +8 -6
- package/dist/server/handler-registry.js +14 -2
- package/dist/server/http.d.ts +274 -0
- package/dist/server/http.js +239 -0
- package/dist/server/live.d.ts +34 -0
- package/dist/server/live.js +309 -0
- package/dist/server/pages.d.ts +2 -6
- package/dist/server/pages.js +808 -789
- package/dist/server/people-tokens.d.ts +1 -6
- package/dist/server/people-tokens.js +580 -572
- package/dist/server/remote.d.ts +4 -7
- package/dist/server/remote.js +37 -70
- package/dist/server/render-chat.d.ts +402 -0
- package/dist/server/render-chat.js +927 -0
- package/dist/server/render-pages.d.ts +535 -0
- package/dist/server/render-pages.js +1277 -0
- package/dist/server/render-people.d.ts +32 -0
- package/dist/server/render-people.js +121 -0
- package/dist/server/render-results.d.ts +744 -0
- package/dist/server/render-results.js +2237 -0
- package/dist/server/render-settings.d.ts +147 -0
- package/dist/server/render-settings.js +577 -0
- package/dist/server/render-tasks.d.ts +632 -0
- package/dist/server/render-tasks.js +2345 -0
- package/dist/server/request-context.d.ts +46 -0
- package/dist/server/request-context.js +17 -0
- package/dist/server/route-table.d.ts +25 -3
- package/dist/server/route-table.js +163 -75
- package/dist/server/runtime.d.ts +15 -7
- package/dist/server/runtime.js +7 -1
- package/dist/server/session.d.ts +138 -0
- package/dist/server/session.js +94 -0
- package/dist/server/settings.d.ts +1 -5
- package/dist/server/settings.js +2182 -2117
- package/dist/server/task-views.d.ts +11 -4
- package/dist/server/task-views.js +26 -22
- package/dist/server/tasks.d.ts +9 -9
- package/dist/server/tasks.js +1486 -1418
- package/dist/server-telemetry.d.ts +4 -3
- package/dist/server-telemetry.js +4 -8
- package/dist/skills-ui.d.ts +4 -3
- package/dist/skills-ui.js +14 -17
- package/dist/skills.d.ts +1 -1
- package/dist/skills.js +2 -1
- package/dist/slack-api.d.ts +5 -1
- package/dist/slack-api.js +2 -2
- package/dist/slack-chat.d.ts +9 -4
- package/dist/slack-chat.js +29 -52
- package/dist/slack-settings.d.ts +3 -2
- package/dist/slack-settings.js +23 -57
- package/dist/slack.js +6 -16
- package/dist/spend-ui.d.ts +2 -1
- package/dist/spend-ui.js +9 -32
- package/dist/sso-ui.d.ts +3 -2
- package/dist/sso-ui.js +26 -27
- package/dist/storage-ui.d.ts +2 -1
- package/dist/storage-ui.js +14 -33
- package/dist/store.d.ts +97 -364
- package/dist/store.js +207 -1531
- package/dist/surface.js +14 -3
- package/dist/task-composer.d.ts +2 -1
- package/dist/task-composer.js +7 -7
- package/dist/task-status.d.ts +4 -3
- package/dist/task-status.js +15 -16
- package/dist/team-http.d.ts +5 -9
- package/dist/team-http.js +5 -63
- package/dist/team-ui.d.ts +2 -1
- package/dist/team-ui.js +2 -5
- package/dist/teammate-question.js +12 -12
- package/dist/teammates-ui.d.ts +5 -4
- package/dist/teammates-ui.js +61 -90
- package/dist/teams-chat.js +12 -9
- package/dist/teams-settings.d.ts +3 -2
- package/dist/teams-settings.js +22 -33
- package/dist/teams.js +4 -5
- package/dist/telegram-flow.js +5 -5
- package/dist/telegram-settings.d.ts +3 -2
- package/dist/telegram-settings.js +14 -25
- package/dist/telegram.js +4 -4
- package/dist/toolroll-update-ui.d.ts +3 -2
- package/dist/toolroll-update-ui.js +35 -39
- package/dist/toolroll-update.d.ts +10 -0
- package/dist/toolroll-update.js +50 -3
- package/dist/tools-ui.d.ts +5 -2
- package/dist/tools-ui.js +31 -31
- package/dist/when-html.d.ts +11 -3
- package/dist/when-html.js +5 -6
- package/dist/workspace-revision.js +3 -1
- package/dist/workspace-ui.d.ts +4 -2
- package/dist/workspace-ui.js +10 -10
- package/package.json +1 -1
- package/dist/server/shared.d.ts +0 -3151
- package/dist/server/shared.js +0 -12001
- package/dist/slack-state.d.ts +0 -13
- package/dist/slack-state.js +0 -10
|
@@ -1,129 +1,197 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
*
|
|
2
|
+
* The one set of chat tables every chat app shares (v116): Telegram, Slack, Discord and Teams keep their pairings,
|
|
3
|
+
* received events, planned message parts, buttons, rooms and delivery receipts here, each row keyed by `provider`.
|
|
4
|
+
* A row's identity is (provider, id): ids carried over from the per-app tables keep their numbers, and nothing infers
|
|
5
|
+
* the app from an id. A leaf: it imports nothing, so the store creates these tables without loading the chat modules.
|
|
4
6
|
*/
|
|
5
|
-
const
|
|
7
|
+
export const CHAT_PROVIDERS = ["telegram", "slack", "discord", "teams"];
|
|
8
|
+
export const isChatProvider = (value) => CHAT_PROVIDERS.includes(value);
|
|
9
|
+
const PROVIDER = `provider TEXT NOT NULL CHECK (provider IN (${CHAT_PROVIDERS.map(one => `'${one}'`).join(",")}))`;
|
|
10
|
+
export const CHAT_SCHEMA = `
|
|
11
|
+
-- One person's chat in one app, speaking as one approver generation. Revoked, never deleted.
|
|
12
|
+
-- installation: the bot (Telegram) or workspace app; member: the app's user id; channel: their private chat.
|
|
6
13
|
CREATE TABLE IF NOT EXISTS chat_binding (
|
|
7
|
-
id INTEGER
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
11
|
-
|
|
14
|
+
${PROVIDER}, id INTEGER NOT NULL, installation TEXT NOT NULL, team TEXT NOT NULL, app TEXT NOT NULL,
|
|
15
|
+
member TEXT NOT NULL, channel TEXT NOT NULL, approver TEXT NOT NULL, generation INTEGER NOT NULL,
|
|
16
|
+
created TEXT NOT NULL, created_by TEXT, pair_event TEXT, revoked TEXT, revoked_by TEXT,
|
|
17
|
+
PRIMARY KEY (provider, id)
|
|
18
|
+
);
|
|
19
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_binding_live ON chat_binding(provider, installation, member) WHERE revoked IS NULL;
|
|
20
|
+
CREATE INDEX IF NOT EXISTS chat_binding_approver ON chat_binding(provider, approver) WHERE revoked IS NULL;
|
|
21
|
+
-- One-time pairing codes, by hash. installation NULL: any installation of the app (a Telegram code works on its bot).
|
|
12
22
|
CREATE TABLE IF NOT EXISTS chat_pair (
|
|
13
|
-
hash TEXT
|
|
14
|
-
|
|
23
|
+
${PROVIDER}, hash TEXT NOT NULL, installation TEXT, approver TEXT NOT NULL, generation INTEGER NOT NULL,
|
|
24
|
+
created TEXT, created_by TEXT, expires TEXT NOT NULL, consumed TEXT, consumed_channel TEXT, consumed_member TEXT, consumed_event TEXT,
|
|
25
|
+
PRIMARY KEY (provider, hash)
|
|
15
26
|
);
|
|
27
|
+
-- Everything an app sent us, once each (the key is the idempotency). kind 'update' is an applied (or pushed and
|
|
28
|
+
-- waiting) Telegram update; 'message' is a message the lead answers, queued to running to done or failed.
|
|
29
|
+
-- session: the lead session its turn was dispatched under, a pointer to its receipt (never an authority).
|
|
16
30
|
CREATE TABLE IF NOT EXISTS chat_event (
|
|
17
|
-
id TEXT
|
|
18
|
-
kind TEXT NOT NULL CHECK(kind IN ('message','action','pair','notice')),
|
|
31
|
+
${PROVIDER}, id TEXT NOT NULL, installation TEXT NOT NULL, binding INTEGER,
|
|
32
|
+
kind TEXT NOT NULL CHECK (kind IN ('message','action','pair','notice','update')),
|
|
19
33
|
channel TEXT NOT NULL, member TEXT NOT NULL, ts TEXT NOT NULL, thread TEXT NOT NULL,
|
|
20
|
-
payload TEXT NOT NULL, created TEXT NOT NULL,
|
|
21
|
-
|
|
22
|
-
next_at TEXT, problem TEXT
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
payload TEXT NOT NULL, created TEXT NOT NULL, session INTEGER,
|
|
35
|
+
state TEXT NOT NULL DEFAULT 'queued' CHECK (state IN ('queued','running','done','failed','dropped')),
|
|
36
|
+
next_at TEXT, problem TEXT, claim_owner TEXT, claim_until TEXT, attempts INTEGER NOT NULL DEFAULT 0,
|
|
37
|
+
turn INTEGER, started TEXT, finished TEXT, result TEXT, reply TEXT,
|
|
38
|
+
PRIMARY KEY (provider, id),
|
|
39
|
+
FOREIGN KEY (provider, binding) REFERENCES chat_binding(provider, id)
|
|
40
|
+
);
|
|
41
|
+
CREATE INDEX IF NOT EXISTS chat_event_pending ON chat_event(provider, installation, state, next_at);
|
|
42
|
+
CREATE INDEX IF NOT EXISTS chat_event_binding ON chat_event(provider, binding, state);
|
|
43
|
+
-- What we send, planned before any send and marked sent only on the app's own message id.
|
|
25
44
|
CREATE TABLE IF NOT EXISTS chat_part (
|
|
26
|
-
id INTEGER
|
|
27
|
-
|
|
45
|
+
${PROVIDER}, id INTEGER NOT NULL, event TEXT NOT NULL, ordinal INTEGER NOT NULL, payload TEXT NOT NULL,
|
|
46
|
+
state TEXT NOT NULL DEFAULT 'pending' CHECK (state IN ('pending','sent','dropped')),
|
|
28
47
|
message TEXT, file TEXT, uploaded INTEGER NOT NULL DEFAULT 0, attempts INTEGER NOT NULL DEFAULT 0,
|
|
29
|
-
uncertain INTEGER NOT NULL DEFAULT 0, next_at TEXT, problem TEXT, created TEXT NOT NULL,
|
|
30
|
-
UNIQUE(event,ordinal)
|
|
31
|
-
)
|
|
48
|
+
uncertain INTEGER NOT NULL DEFAULT 0, next_at TEXT, problem TEXT, created TEXT NOT NULL, sent TEXT,
|
|
49
|
+
PRIMARY KEY (provider, id), UNIQUE (provider, event, ordinal),
|
|
50
|
+
FOREIGN KEY (provider, event) REFERENCES chat_event(provider, id)
|
|
51
|
+
);
|
|
52
|
+
CREATE INDEX IF NOT EXISTS chat_part_pending ON chat_part(provider, state, next_at);
|
|
53
|
+
CREATE INDEX IF NOT EXISTS chat_part_message ON chat_part(provider, message);
|
|
54
|
+
-- A lead proposal's buttons (proposal), or a builder decision's (decision, option_id), one opaque token each.
|
|
55
|
+
-- A button rides its planned part, or (Telegram) the binding, chat and message it was placed on.
|
|
32
56
|
CREATE TABLE IF NOT EXISTS chat_action (
|
|
33
|
-
token TEXT
|
|
34
|
-
proposal INTEGER
|
|
35
|
-
|
|
36
|
-
)
|
|
57
|
+
${PROVIDER}, token TEXT NOT NULL, part INTEGER, binding INTEGER, chat TEXT, message TEXT,
|
|
58
|
+
proposal INTEGER REFERENCES mate_proposal(id) ON DELETE CASCADE,
|
|
59
|
+
decision INTEGER REFERENCES decision(id) ON DELETE CASCADE, option_id TEXT, note_digest TEXT,
|
|
60
|
+
phase TEXT NOT NULL CHECK (phase IN ('confirm','dismiss','yes','cancel','choose')),
|
|
61
|
+
created TEXT, expires TEXT, consumed TEXT,
|
|
62
|
+
PRIMARY KEY (provider, token),
|
|
63
|
+
CHECK ((proposal IS NULL) <> (decision IS NULL)),
|
|
64
|
+
FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
|
|
65
|
+
);
|
|
66
|
+
CREATE INDEX IF NOT EXISTS chat_action_part ON chat_action(provider, part);
|
|
67
|
+
CREATE INDEX IF NOT EXISTS chat_action_proposal ON chat_action(proposal);
|
|
68
|
+
CREATE INDEX IF NOT EXISTS chat_action_decision ON chat_action(decision);
|
|
37
69
|
CREATE TABLE IF NOT EXISTS chat_progress (
|
|
38
|
-
binding INTEGER NOT NULL
|
|
39
|
-
|
|
40
|
-
|
|
70
|
+
${PROVIDER}, binding INTEGER NOT NULL, run INTEGER NOT NULL REFERENCES run(id), part INTEGER NOT NULL, digest TEXT NOT NULL,
|
|
71
|
+
PRIMARY KEY (provider, binding, run),
|
|
72
|
+
FOREIGN KEY (provider, binding) REFERENCES chat_binding(provider, id),
|
|
73
|
+
FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
|
|
41
74
|
);
|
|
75
|
+
-- One live worker per installation (lease, its generation and the poll cursor), its connection and retry state,
|
|
76
|
+
-- the newest notification its notices started from, and where (Telegram) pushes updates.
|
|
42
77
|
CREATE TABLE IF NOT EXISTS chat_runtime (
|
|
43
|
-
installation TEXT
|
|
44
|
-
|
|
78
|
+
${PROVIDER}, installation TEXT NOT NULL, owner TEXT, lease_until TEXT, generation INTEGER NOT NULL DEFAULT 0,
|
|
79
|
+
cursor INTEGER NOT NULL DEFAULT 0, heartbeat TEXT, connected TEXT, problem TEXT, retry_at TEXT,
|
|
80
|
+
notification INTEGER NOT NULL DEFAULT 0, push_url TEXT, push_at TEXT, push_problem TEXT,
|
|
81
|
+
PRIMARY KEY (provider, installation)
|
|
45
82
|
);
|
|
46
|
-
|
|
47
|
-
/** v73: a chat's place in the shared team conversations — a channel follows one
|
|
48
|
-
* conversation, a DM may select one. Rows are revoked, never deleted. */
|
|
49
|
-
const CHAT_ROOM_SCHEMA = `
|
|
83
|
+
-- A chat's place in the shared team conversations: a group follows one conversation, a private chat may select one.
|
|
50
84
|
CREATE TABLE IF NOT EXISTS chat_room (
|
|
51
|
-
id INTEGER
|
|
52
|
-
kind TEXT NOT NULL CHECK(kind IN ('group','private')), conversation TEXT NOT NULL,
|
|
53
|
-
binding INTEGER NOT NULL
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
CREATE UNIQUE INDEX IF NOT EXISTS
|
|
85
|
+
${PROVIDER}, id INTEGER NOT NULL, installation TEXT NOT NULL, chat TEXT NOT NULL,
|
|
86
|
+
kind TEXT NOT NULL CHECK (kind IN ('group','private')), conversation TEXT NOT NULL REFERENCES team_conversation(id),
|
|
87
|
+
binding INTEGER NOT NULL, bound_by TEXT NOT NULL, bound TEXT NOT NULL, cursor INTEGER NOT NULL DEFAULT 0,
|
|
88
|
+
revoked TEXT, revoked_by TEXT,
|
|
89
|
+
PRIMARY KEY (provider, id),
|
|
90
|
+
FOREIGN KEY (provider, binding) REFERENCES chat_binding(provider, id)
|
|
91
|
+
);
|
|
92
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_room_live ON chat_room(provider, installation, chat) WHERE revoked IS NULL;
|
|
93
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_room_group ON chat_room(provider, conversation) WHERE revoked IS NULL AND kind = 'group';
|
|
94
|
+
-- Small transport facts an app must remember per chat (a Teams service URL). Never credentials.
|
|
59
95
|
CREATE TABLE IF NOT EXISTS chat_meta (
|
|
60
|
-
installation TEXT NOT NULL, key TEXT NOT NULL, value TEXT NOT NULL, updated TEXT NOT NULL,
|
|
61
|
-
PRIMARY KEY(installation, key)
|
|
96
|
+
${PROVIDER}, installation TEXT NOT NULL, key TEXT NOT NULL, value TEXT NOT NULL, updated TEXT NOT NULL,
|
|
97
|
+
PRIMARY KEY (provider, installation, key)
|
|
62
98
|
);
|
|
63
|
-
|
|
64
|
-
/** v88: flow decisions in the chat app, as on Telegram (telegram-flow.ts).
|
|
65
|
-
* A button is one opaque token for one visit (card, entry) of one card, on
|
|
66
|
-
* the part it rides; Edit and Send back open a prompt the person's next
|
|
67
|
-
* message in their DM answers. */
|
|
68
|
-
const CHAT_FLOW_SCHEMA = `
|
|
99
|
+
-- A flow decision's buttons (Approve, Edit, Send back, and the Yes or Cancel Approve arms) for one visit of one card.
|
|
69
100
|
CREATE TABLE IF NOT EXISTS chat_flow_action (
|
|
70
|
-
token TEXT
|
|
101
|
+
${PROVIDER}, token TEXT NOT NULL, part INTEGER, binding INTEGER, chat TEXT, message TEXT,
|
|
71
102
|
card INTEGER NOT NULL REFERENCES flow_card(id), entry INTEGER NOT NULL,
|
|
72
|
-
action TEXT NOT NULL CHECK(action IN ('approve','edit','send-back')),
|
|
103
|
+
action TEXT NOT NULL CHECK (action IN ('approve','edit','send-back','yes','cancel')),
|
|
104
|
+
created TEXT, expires TEXT NOT NULL, consumed TEXT,
|
|
105
|
+
PRIMARY KEY (provider, token),
|
|
106
|
+
FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
|
|
73
107
|
);
|
|
74
108
|
CREATE INDEX IF NOT EXISTS chat_flow_action_visit ON chat_flow_action(card, entry);
|
|
109
|
+
CREATE INDEX IF NOT EXISTS chat_flow_action_part ON chat_flow_action(provider, part);
|
|
110
|
+
-- Edit and Send back wait for the person's next message (or, on Telegram, a reply to the prompt message).
|
|
75
111
|
CREATE TABLE IF NOT EXISTS chat_flow_prompt (
|
|
76
|
-
id INTEGER
|
|
112
|
+
${PROVIDER}, id INTEGER NOT NULL, binding INTEGER NOT NULL, chat TEXT, message TEXT,
|
|
77
113
|
card INTEGER NOT NULL REFERENCES flow_card(id), entry INTEGER NOT NULL,
|
|
78
|
-
mode TEXT NOT NULL CHECK(mode IN ('edit','send-back')), created TEXT NOT NULL, expires TEXT NOT NULL, consumed TEXT
|
|
114
|
+
mode TEXT NOT NULL CHECK (mode IN ('edit','send-back')), created TEXT NOT NULL, expires TEXT NOT NULL, consumed TEXT,
|
|
115
|
+
PRIMARY KEY (provider, id)
|
|
79
116
|
);
|
|
80
|
-
CREATE INDEX IF NOT EXISTS chat_flow_prompt_open ON chat_flow_prompt(binding, consumed);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
* when sent) for one visit of one card, on the part it rides. A reply in that notice's thread is the note; chat_flow_note
|
|
84
|
-
* is "Use this as your note?" Yes / No about one other message (held: its event; words: what it said, kept only until
|
|
85
|
-
* answered, as an event's own payload is cleared once it is handled), asked once per visit.
|
|
86
|
-
* Never in CHAT_TABLES: an older database has no such table until this schema creates it. */
|
|
87
|
-
const CHAT_FLOW_CHOICE_SCHEMA = `
|
|
117
|
+
CREATE INDEX IF NOT EXISTS chat_flow_prompt_open ON chat_flow_prompt(provider, binding, consumed);
|
|
118
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_flow_prompt_message ON chat_flow_prompt(provider, chat, message) WHERE message IS NOT NULL;
|
|
119
|
+
-- A flow's "Person chooses" buttons: one per option (choice is its index, label its words when sent).
|
|
88
120
|
CREATE TABLE IF NOT EXISTS chat_flow_choice (
|
|
89
|
-
token TEXT
|
|
121
|
+
${PROVIDER}, token TEXT NOT NULL, part INTEGER, binding INTEGER, chat TEXT, message TEXT,
|
|
90
122
|
card INTEGER NOT NULL REFERENCES flow_card(id), entry INTEGER NOT NULL,
|
|
91
|
-
choice INTEGER NOT NULL, label TEXT NOT NULL, expires TEXT NOT NULL, consumed TEXT
|
|
123
|
+
choice INTEGER NOT NULL, label TEXT NOT NULL, created TEXT, expires TEXT NOT NULL, consumed TEXT,
|
|
124
|
+
PRIMARY KEY (provider, token),
|
|
125
|
+
FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
|
|
92
126
|
);
|
|
93
127
|
CREATE INDEX IF NOT EXISTS chat_flow_choice_visit ON chat_flow_choice(card, entry);
|
|
128
|
+
CREATE INDEX IF NOT EXISTS chat_flow_choice_part ON chat_flow_choice(provider, part);
|
|
129
|
+
-- "Use this as your note?" Yes / No about the person's message held (its event; words kept only until answered).
|
|
94
130
|
CREATE TABLE IF NOT EXISTS chat_flow_note (
|
|
95
|
-
token TEXT
|
|
131
|
+
${PROVIDER}, token TEXT NOT NULL, part INTEGER NOT NULL,
|
|
96
132
|
card INTEGER NOT NULL REFERENCES flow_card(id), entry INTEGER NOT NULL,
|
|
97
|
-
held TEXT NOT NULL, words TEXT, answer TEXT NOT NULL CHECK(answer IN ('yes','no')), expires TEXT NOT NULL, consumed TEXT
|
|
133
|
+
held TEXT NOT NULL, words TEXT, answer TEXT NOT NULL CHECK (answer IN ('yes','no')), expires TEXT NOT NULL, consumed TEXT,
|
|
134
|
+
PRIMARY KEY (provider, token),
|
|
135
|
+
FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
|
|
98
136
|
);
|
|
99
137
|
CREATE INDEX IF NOT EXISTS chat_flow_note_visit ON chat_flow_note(card, entry);
|
|
100
|
-
|
|
101
|
-
/** v93: a teammate's question in the chat app. One button per option (choice)
|
|
102
|
-
* and one to answer in words (choice NULL); that one opens a prompt the
|
|
103
|
-
* person's next message in their DM answers. Never in CHAT_TABLES: an older
|
|
104
|
-
* database has no such tables until this schema creates them. */
|
|
105
|
-
const CHAT_QUESTION_SCHEMA = `
|
|
138
|
+
-- A teammate's question: one button per option and one to answer in words (choice NULL).
|
|
106
139
|
CREATE TABLE IF NOT EXISTS chat_question_action (
|
|
107
|
-
token TEXT
|
|
108
|
-
question INTEGER NOT NULL REFERENCES teammate_question(id), choice TEXT, expires TEXT NOT NULL, consumed TEXT
|
|
140
|
+
${PROVIDER}, token TEXT NOT NULL, part INTEGER, binding INTEGER, chat TEXT, message TEXT,
|
|
141
|
+
question INTEGER NOT NULL REFERENCES teammate_question(id), choice TEXT, created TEXT, expires TEXT NOT NULL, consumed TEXT,
|
|
142
|
+
PRIMARY KEY (provider, token),
|
|
143
|
+
FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id)
|
|
109
144
|
);
|
|
110
145
|
CREATE INDEX IF NOT EXISTS chat_question_action_question ON chat_question_action(question);
|
|
111
146
|
CREATE TABLE IF NOT EXISTS chat_question_prompt (
|
|
112
|
-
id INTEGER
|
|
113
|
-
question INTEGER NOT NULL REFERENCES teammate_question(id), created TEXT NOT NULL, expires TEXT NOT NULL, consumed TEXT
|
|
147
|
+
${PROVIDER}, id INTEGER NOT NULL, binding INTEGER NOT NULL, chat TEXT, message TEXT,
|
|
148
|
+
question INTEGER NOT NULL REFERENCES teammate_question(id), created TEXT NOT NULL, expires TEXT NOT NULL, consumed TEXT,
|
|
149
|
+
PRIMARY KEY (provider, id)
|
|
114
150
|
);
|
|
115
|
-
CREATE INDEX IF NOT EXISTS chat_question_prompt_open ON chat_question_prompt(binding, consumed);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
* "Something else" (choice NULL). A tap sends the option as the owner's next message. Never in CHAT_TABLES. */
|
|
119
|
-
const CHAT_ASK_SCHEMA = `
|
|
151
|
+
CREATE INDEX IF NOT EXISTS chat_question_prompt_open ON chat_question_prompt(provider, binding, consumed);
|
|
152
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_question_prompt_message ON chat_question_prompt(provider, chat, message) WHERE message IS NOT NULL;
|
|
153
|
+
-- The lead's question to its owner (ask_owner): one button per option and one for "Something else" (choice NULL).
|
|
120
154
|
CREATE TABLE IF NOT EXISTS chat_ask_action (
|
|
121
|
-
token TEXT
|
|
122
|
-
|
|
155
|
+
${PROVIDER}, token TEXT NOT NULL, part INTEGER NOT NULL, turn INTEGER NOT NULL, choice INTEGER, expires TEXT NOT NULL, consumed TEXT,
|
|
156
|
+
PRIMARY KEY (provider, token),
|
|
157
|
+
FOREIGN KEY (provider, part) REFERENCES chat_part(provider, id) ON DELETE CASCADE
|
|
123
158
|
);
|
|
124
159
|
CREATE INDEX IF NOT EXISTS chat_ask_action_turn ON chat_ask_action(turn);
|
|
160
|
+
-- What one sent message carried, so a reply to it is about exactly that: a notification (kind 'notification', one row
|
|
161
|
+
-- per notification it showed), a builder decision ('decision') or the task a status showed ('task').
|
|
162
|
+
CREATE TABLE IF NOT EXISTS chat_message_ref (
|
|
163
|
+
${PROVIDER}, binding INTEGER NOT NULL, chat TEXT NOT NULL, message TEXT NOT NULL,
|
|
164
|
+
kind TEXT NOT NULL CHECK (kind IN ('notification','decision','task')),
|
|
165
|
+
notification INTEGER REFERENCES notification(id), destination TEXT, project TEXT,
|
|
166
|
+
task_ref INTEGER REFERENCES task_ref(id), task_id TEXT, run INTEGER,
|
|
167
|
+
decision INTEGER REFERENCES decision(id) ON DELETE CASCADE, created TEXT NOT NULL,
|
|
168
|
+
CHECK ((kind = 'notification') = (notification IS NOT NULL AND destination IS NOT NULL)),
|
|
169
|
+
CHECK ((kind = 'decision') = (decision IS NOT NULL)),
|
|
170
|
+
CHECK (kind <> 'task' OR task_id IS NOT NULL)
|
|
171
|
+
);
|
|
172
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_message_ref_notification ON chat_message_ref(provider, binding, chat, message, notification) WHERE kind = 'notification';
|
|
173
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_message_ref_one ON chat_message_ref(provider, binding, chat, message, kind) WHERE kind <> 'notification';
|
|
174
|
+
CREATE INDEX IF NOT EXISTS chat_message_ref_destination ON chat_message_ref(destination, notification);
|
|
175
|
+
CREATE INDEX IF NOT EXISTS chat_message_ref_task ON chat_message_ref(destination, task_ref) WHERE kind = 'notification';
|
|
176
|
+
-- A note typed as a reply to a builder decision, held until a tap answers with it. Only a later event replaces it.
|
|
177
|
+
CREATE TABLE IF NOT EXISTS chat_note_draft (
|
|
178
|
+
${PROVIDER}, id INTEGER NOT NULL, binding INTEGER NOT NULL,
|
|
179
|
+
decision INTEGER NOT NULL REFERENCES decision(id) ON DELETE CASCADE, event INTEGER NOT NULL,
|
|
180
|
+
message TEXT NOT NULL, reply_to TEXT NOT NULL, note TEXT NOT NULL,
|
|
181
|
+
state TEXT NOT NULL DEFAULT 'pending' CHECK (state IN ('pending','armed','superseded','consumed','discarded')),
|
|
182
|
+
created TEXT NOT NULL, expires TEXT NOT NULL,
|
|
183
|
+
PRIMARY KEY (provider, id),
|
|
184
|
+
FOREIGN KEY (provider, binding) REFERENCES chat_binding(provider, id)
|
|
185
|
+
);
|
|
186
|
+
CREATE UNIQUE INDEX IF NOT EXISTS chat_note_draft_live ON chat_note_draft(provider, binding, decision) WHERE state IN ('pending','armed');
|
|
187
|
+
-- Away mode: routine facts wait and go as one digest every every_ms (null: each fact as it lands).
|
|
188
|
+
CREATE TABLE IF NOT EXISTS chat_digest (
|
|
189
|
+
${PROVIDER}, every_ms INTEGER, set_by TEXT, set_at TEXT, last_sent_at TEXT,
|
|
190
|
+
PRIMARY KEY (provider)
|
|
191
|
+
);
|
|
125
192
|
`;
|
|
126
|
-
|
|
193
|
+
/** Every shared chat table, parents before children. */
|
|
194
|
+
export const CHAT_TABLES = [
|
|
127
195
|
"chat_binding",
|
|
128
196
|
"chat_pair",
|
|
129
197
|
"chat_event",
|
|
@@ -131,6 +199,16 @@ const CHAT_TABLES = [
|
|
|
131
199
|
"chat_action",
|
|
132
200
|
"chat_progress",
|
|
133
201
|
"chat_runtime",
|
|
202
|
+
"chat_room",
|
|
203
|
+
"chat_meta",
|
|
204
|
+
"chat_flow_action",
|
|
205
|
+
"chat_flow_prompt",
|
|
206
|
+
"chat_flow_choice",
|
|
207
|
+
"chat_flow_note",
|
|
208
|
+
"chat_question_action",
|
|
209
|
+
"chat_question_prompt",
|
|
210
|
+
"chat_ask_action",
|
|
211
|
+
"chat_message_ref",
|
|
212
|
+
"chat_note_draft",
|
|
213
|
+
"chat_digest",
|
|
134
214
|
];
|
|
135
|
-
export const chatSchema = (channel) => (CHAT_SCHEMA + CHAT_ROOM_SCHEMA + CHAT_FLOW_SCHEMA + CHAT_FLOW_CHOICE_SCHEMA + CHAT_QUESTION_SCHEMA + CHAT_ASK_SCHEMA).replaceAll("chat_", `${channel}_`);
|
|
136
|
-
export const chatTables = (channel) => CHAT_TABLES.map((name) => name.replace("chat_", `${channel}_`));
|
package/dist/contracts/cli.d.ts
CHANGED
|
@@ -323,13 +323,12 @@ export declare const COMMAND_OUTPUTS: {
|
|
|
323
323
|
assets: "assets";
|
|
324
324
|
auth: "auth";
|
|
325
325
|
chat: "chat";
|
|
326
|
-
"chat-stream": "chat-stream";
|
|
327
326
|
cli: "cli";
|
|
328
327
|
console: "console";
|
|
329
328
|
decisions: "decisions";
|
|
330
|
-
"flow-stream": "flow-stream";
|
|
331
329
|
flows: "flows";
|
|
332
330
|
health: "health";
|
|
331
|
+
live: "live";
|
|
333
332
|
mcp: "mcp";
|
|
334
333
|
metrics: "metrics";
|
|
335
334
|
other: "other";
|
|
@@ -339,7 +338,6 @@ export declare const COMMAND_OUTPUTS: {
|
|
|
339
338
|
settings: "settings";
|
|
340
339
|
tasks: "tasks";
|
|
341
340
|
team: "team";
|
|
342
|
-
"team-stream": "team-stream";
|
|
343
341
|
}> & z.core.$partial, z.ZodObject<{
|
|
344
342
|
count: z.ZodNumber;
|
|
345
343
|
p50Ms: z.ZodNullable<z.ZodNumber>;
|
|
@@ -177,7 +177,7 @@ export declare const CONSOLE_FORMS: {
|
|
|
177
177
|
};
|
|
178
178
|
export type ConsoleFormName = keyof typeof CONSOLE_FORMS;
|
|
179
179
|
/** The console POSTs whose handlers read no field (sign-out not even the shared guard): their contract is the empty form. */
|
|
180
|
-
export declare const BODILESS_POSTS: readonly ["POST /settings/lead/on", "POST /r/<run>/draft-repair", "POST /ledger/checkpoint", "POST /settings/backups/now", "POST /mode/revoke", "POST /settings/telegram/retry", "POST /providers/<provider>/resume", "POST /logout", "POST /t/<task>/unhold", "POST /t/<task>/plan", "POST /t/<task>/retry-review"];
|
|
180
|
+
export declare const BODILESS_POSTS: readonly ["POST /settings/models/<unknown action>", "POST /settings/lead/on", "POST /r/<run>/draft-repair", "POST /ledger/checkpoint", "POST /settings/backups/now", "POST /mode/revoke", "POST /settings/telegram/retry", "POST /providers/<provider>/resume", "POST /logout", "POST /t/<task>/unhold", "POST /t/<task>/plan", "POST /t/<task>/retry-review"];
|
|
181
181
|
/** The field names a console form's handler may read. */
|
|
182
182
|
export type FormFieldOf<N extends ConsoleFormName> = (typeof CONSOLE_FORMS)[N] extends FormContract<infer K> ? K : never;
|
|
183
183
|
/** `GET /ledger?format=json`: the chain's state, a page of entries (newest first) and the cursor for the next. */
|
|
@@ -73,10 +73,10 @@ export const CONSOLE_FORMS = {
|
|
|
73
73
|
mutationGuard: formContract("POST (every signed-in form)", ["csrf", "token", "digest", "nonce", "confirm"]),
|
|
74
74
|
ledgerTarget: formContract("POST (the action ledger's project)", ["repo"]),
|
|
75
75
|
projectCeiling: formContract("POST (project ceiling)", ["repo"]),
|
|
76
|
-
demo: formContract("POST /chat/demo/<
|
|
76
|
+
demo: formContract("POST /chat/demo/ask, /chat/demo/<id>/approve|change|revise|complete", ["message", "note"]),
|
|
77
77
|
updatesDismiss: formContract("POST /settings/updates/dismiss", ["version", "quiet", "return"]),
|
|
78
78
|
updatesChecks: formContract("POST /settings/updates/checks", ["check"]),
|
|
79
|
-
code: formContract("POST /code, /code/start, /code/<session>/<act>", ["repo", "password", "title", "model", "prompt", "requestId", "base", "candidate", "goal", "acceptance", "visual", "decision", "answers"], { prefixes: ["question:"] }),
|
|
79
|
+
code: formContract("POST /code, /code/start, /code/<session>/<act>, /code/<anything else>", ["repo", "password", "title", "model", "prompt", "requestId", "base", "candidate", "goal", "acceptance", "visual", "decision", "answers"], { prefixes: ["question:"] }),
|
|
80
80
|
skillsRevise: formContract("POST /settings/skills/revise", ["run", "repo", "feedback", "nonce"]),
|
|
81
81
|
skillsChange: formContract("POST /settings/skills/import, /settings/skills/change", ["repo", "identity", "revision", "method", "content", "files", "url", "action", "sha", "sample", "nonce", "restore"]),
|
|
82
82
|
kit: formContract("POST /kits/<kit>/<act>", ["repo"]),
|
|
@@ -111,11 +111,11 @@ export const CONSOLE_FORMS = {
|
|
|
111
111
|
knowledgeChange: formContract("POST /settings/knowledge/change", ["repo", "action", "identity", "revision", "instructions", "title", "content", "path", "id", "restore"]),
|
|
112
112
|
learningChange: formContract("POST /settings/learning/change", ["repo", "action", "identity", "revision", "lesson", "version", "sha"]),
|
|
113
113
|
projectSetup: formContract("POST /control/setup-preview, /control/setup-approve, /control/instructions-preview, /control/instructions-approve", ["repo", "nonce", "fingerprint", "token", "provider", "model", "command", "seconds"]),
|
|
114
|
-
slack: formContract("POST /settings/slack
|
|
114
|
+
slack: formContract("POST /settings/slack/connect|pair|unpair|disconnect|alerts", ["password", "app-token", "bot-token"]),
|
|
115
115
|
chatApproval: formContract("POST /settings/chat-approval/confirm, /settings/chat-approval/save, /settings/chat-approval/off", ["scope", "full-access", "cap-usd", "nonce", "digest", "token"]),
|
|
116
116
|
telegramPair: formContract("POST /settings/telegram/pair, /settings/telegram/unpair", ["password"]),
|
|
117
|
-
teams: formContract("POST /settings/teams
|
|
118
|
-
discord: formContract("POST /settings/discord
|
|
117
|
+
teams: formContract("POST /settings/teams/connect|pair|unpair|disconnect|alerts", ["password", "app-id", "tenant", "secret"]),
|
|
118
|
+
discord: formContract("POST /settings/discord/connect|pair|unpair|disconnect|alerts", ["password", "bot-token"]),
|
|
119
119
|
messaging: formContract("POST /settings/messaging", ["primary"]),
|
|
120
120
|
permissionDefault: formContract("POST /settings/permission-default", ["permission-mode"]),
|
|
121
121
|
qualityDefault: formContract("POST /settings/quality-default", ["quality-mode"]),
|
|
@@ -188,6 +188,7 @@ export const CONSOLE_FORMS = {
|
|
|
188
188
|
};
|
|
189
189
|
/** The console POSTs whose handlers read no field (sign-out not even the shared guard): their contract is the empty form. */
|
|
190
190
|
export const BODILESS_POSTS = [
|
|
191
|
+
"POST /settings/models/<unknown action>",
|
|
191
192
|
"POST /settings/lead/on",
|
|
192
193
|
"POST /r/<run>/draft-repair",
|
|
193
194
|
"POST /ledger/checkpoint",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* message whose button can't be read is answered with why (`data.custom_id: not a Toolroll button`), and nothing is done.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
|
+
import { CHAT_BUTTON_TOKEN } from "./chat-content.js";
|
|
8
9
|
import { parseContract } from "./contract.js";
|
|
9
10
|
const user = z.object({ id: z.string() });
|
|
10
11
|
/** The interaction around a tap (type 3: a message component): the app, the person, the channel, the message. */
|
|
@@ -22,7 +23,7 @@ export const discordComponentInteractionSchema = z.object({
|
|
|
22
23
|
});
|
|
23
24
|
/** Toolroll's button data: `so_` and a one-time token. */
|
|
24
25
|
export const discordButtonSchema = z.object({
|
|
25
|
-
custom_id: z.string().regex(
|
|
26
|
+
custom_id: z.string().regex(new RegExp(`^so_${CHAT_BUTTON_TOKEN.source.slice(1)}`), { error: "not a Toolroll button" }),
|
|
26
27
|
});
|
|
27
28
|
export function readDiscordComponentInteraction(body) {
|
|
28
29
|
return parseContract(discordComponentInteractionSchema, body);
|
|
@@ -21,13 +21,12 @@ export declare const healthSnapshotSchema: z.ZodObject<{
|
|
|
21
21
|
assets: "assets";
|
|
22
22
|
auth: "auth";
|
|
23
23
|
chat: "chat";
|
|
24
|
-
"chat-stream": "chat-stream";
|
|
25
24
|
cli: "cli";
|
|
26
25
|
console: "console";
|
|
27
26
|
decisions: "decisions";
|
|
28
|
-
"flow-stream": "flow-stream";
|
|
29
27
|
flows: "flows";
|
|
30
28
|
health: "health";
|
|
29
|
+
live: "live";
|
|
31
30
|
mcp: "mcp";
|
|
32
31
|
metrics: "metrics";
|
|
33
32
|
other: "other";
|
|
@@ -37,7 +36,6 @@ export declare const healthSnapshotSchema: z.ZodObject<{
|
|
|
37
36
|
settings: "settings";
|
|
38
37
|
tasks: "tasks";
|
|
39
38
|
team: "team";
|
|
40
|
-
"team-stream": "team-stream";
|
|
41
39
|
}> & z.core.$partial, z.ZodObject<{
|
|
42
40
|
count: z.ZodNumber;
|
|
43
41
|
p50Ms: z.ZodNullable<z.ZodNumber>;
|
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { parseContract } from "./contract.js";
|
|
9
|
+
import { CHAT_BUTTON_TOKEN } from "./chat-content.js";
|
|
9
10
|
/** Toolroll's buttons: toolroll_* since the rename; standing_orders_* buttons on older messages still work. */
|
|
10
|
-
export const SLACK_BUTTON_ACTION = /^(?:toolroll|standing_orders)_(?:confirm|dismiss|yes|cancel|flow_approve|flow_edit|flow_send_back|flow_choose_[0-3]|flow_note_(?:yes|no)|question_choice|question_words)$/;
|
|
11
|
+
export const SLACK_BUTTON_ACTION = /^(?:toolroll|standing_orders)_(?:confirm|dismiss|yes|cancel|flow_approve|flow_edit|flow_send_back|flow_choose_[0-3]|flow_note_(?:yes|no)|question_choice|question_words|decide_[0-9]{1,2})$/;
|
|
11
12
|
/** A link button opens its page in Slack's own client; Slack still reports the tap, and there is nothing to do. */
|
|
12
13
|
export const SLACK_LINK_ACTION = /^(?:toolroll|standing_orders)_link(?:_[0-9]+)?$/;
|
|
13
|
-
const token = z.string().regex(
|
|
14
|
+
const token = z.string().regex(CHAT_BUTTON_TOKEN, { error: "must be a Toolroll button token" });
|
|
14
15
|
/** The interaction around a tap: who, and the message the button is on. */
|
|
15
16
|
export const slackBlockActionsSchema = z.object({
|
|
16
17
|
type: z.literal("block_actions"),
|
|
@@ -155,10 +155,6 @@ declare const STORE_COLUMN_VALUES: {
|
|
|
155
155
|
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
156
156
|
}, z.core.$loose>>;
|
|
157
157
|
}, z.core.$loose>;
|
|
158
|
-
readonly "telegram_conversation_part.keyboard_json": z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
159
|
-
text: z.ZodString;
|
|
160
|
-
callback_data: z.ZodString;
|
|
161
|
-
}, z.core.$loose>>>;
|
|
162
158
|
readonly "publication_grant.capabilities": z.ZodArray<z.ZodEnum<{
|
|
163
159
|
"open-pr": "open-pr";
|
|
164
160
|
"push-branch": "push-branch";
|
|
@@ -254,7 +250,7 @@ declare const STORE_COLUMN_VALUES: {
|
|
|
254
250
|
export type StoreColumn = keyof typeof STORE_COLUMN_VALUES;
|
|
255
251
|
export type StoreColumnValue<C extends StoreColumn> = z.infer<(typeof STORE_COLUMN_VALUES)[C]>;
|
|
256
252
|
/** Every JSON column the store reads itself, by `table.column`. */
|
|
257
|
-
export declare const STORE_COLUMNS: ("approval_policy.protected_paths" | "backend_grant.mutations" | "backend_grant.paths" | "coordinator_proposal.outcome_json" | "coordinator_proposal.payload_json" | "criterion_review.screenshots_json" | "decision.options" | "flow_card.source_json" | "flow_comment.mentions_json" | "lead_config.about_json" | "mate_ask.options_json" | "mate_proposal.outcome_json" | "mate_proposal.payload_json" | "mutation.result" | "operating_mode.terms_json" | "plan_revision.changed_fields" | "proof_verdict.matrix_json" | "proof_verdict.reasons_json" | "publication_grant.capabilities" | "repair_chain.unresolved_json" | "run_check.suites_json" | "run_checkpoint.snapshot_json" | "run_tool.tools_json" | "runner.agents" | "runner.repos" | "task_ref.capability_requirements" | "task_ref.zones" | "task_scope.acceptance_json" | "task_scope.touches" | "teammate_call.input_json" | "teammate_event.detail_json" | "teammate_question.options_json" | "teammate_suggestion.evidence_json" | "teammate_suggestion.rule_json" | "teammate_suggestion.was_json" | "teammate_tool.actions_json" | "teammate_tool.rules_json" | "
|
|
253
|
+
export declare const STORE_COLUMNS: ("approval_policy.protected_paths" | "backend_grant.mutations" | "backend_grant.paths" | "coordinator_proposal.outcome_json" | "coordinator_proposal.payload_json" | "criterion_review.screenshots_json" | "decision.options" | "flow_card.source_json" | "flow_comment.mentions_json" | "lead_config.about_json" | "mate_ask.options_json" | "mate_proposal.outcome_json" | "mate_proposal.payload_json" | "mutation.result" | "operating_mode.terms_json" | "plan_revision.changed_fields" | "proof_verdict.matrix_json" | "proof_verdict.reasons_json" | "publication_grant.capabilities" | "repair_chain.unresolved_json" | "run_check.suites_json" | "run_checkpoint.snapshot_json" | "run_tool.tools_json" | "runner.agents" | "runner.repos" | "task_ref.capability_requirements" | "task_ref.zones" | "task_scope.acceptance_json" | "task_scope.touches" | "teammate_call.input_json" | "teammate_event.detail_json" | "teammate_question.options_json" | "teammate_suggestion.evidence_json" | "teammate_suggestion.rule_json" | "teammate_suggestion.was_json" | "teammate_tool.actions_json" | "teammate_tool.rules_json" | "tool_seal.tools_json")[];
|
|
258
254
|
/** A SQL projection, not a physical column; replay it separately after its owning column. */
|
|
259
255
|
export declare const STORE_PROJECTIONS: readonly ["run_tool.tools_json.fence"];
|
|
260
256
|
/** These readers historically only parsed JSON. Shape errors must not change their values or catch boundaries. */
|
|
@@ -16,7 +16,6 @@ import { decisionOptionSchema } from "./decision.js";
|
|
|
16
16
|
import { scopeTermsSchema, storedRubricSchema } from "./scope.js";
|
|
17
17
|
import { criterionEvidenceSchema, proofCriterionSchema } from "./proof.js";
|
|
18
18
|
import { sharedActionSchema } from "./chat-actions.js";
|
|
19
|
-
import { telegramCallbackButtonSchema } from "./telegram-callback.js";
|
|
20
19
|
import { readVersioned, versioned } from "./contract.js";
|
|
21
20
|
/** Dynamic tool arguments, event details and operation results have no common field contract. */
|
|
22
21
|
const savedObject = z.looseObject({});
|
|
@@ -53,7 +52,6 @@ const savedProgressSchema = z.looseObject({
|
|
|
53
52
|
id: z.string(), state: z.enum(["pending", "current", "completed", "blocked"]), note: z.string().nullable().optional(),
|
|
54
53
|
})),
|
|
55
54
|
});
|
|
56
|
-
const savedKeyboardSchema = z.array(z.array(telegramCallbackButtonSchema.extend({ callback_data: z.string() }).loose()));
|
|
57
55
|
const savedMatrixRowSchema = proofCriterionSchema.pick({ id: true, statement: true }).extend({
|
|
58
56
|
id: z.string(), statement: z.string(), requiredEvidence: savedList, state: z.string(), detail: savedList,
|
|
59
57
|
answered: z.array(criterionEvidenceSchema.extend({ ref: z.string() }).loose()).optional(),
|
|
@@ -88,7 +86,6 @@ const STORE_COLUMN_VALUES = {
|
|
|
88
86
|
"mutation.result": z.unknown(),
|
|
89
87
|
"plan_revision.changed_fields": z.array(z.string()),
|
|
90
88
|
"run_checkpoint.snapshot_json": savedProgressSchema,
|
|
91
|
-
"telegram_conversation_part.keyboard_json": savedKeyboardSchema,
|
|
92
89
|
"publication_grant.capabilities": z.array(z.enum(["push-branch", "open-pr"])),
|
|
93
90
|
"task_ref.zones": savedList,
|
|
94
91
|
"task_ref.capability_requirements": savedList,
|
|
@@ -115,7 +112,7 @@ export const LEGACY_JSON_COLUMNS = [
|
|
|
115
112
|
"teammate_event.detail_json", "task_scope.touches", "task_scope.acceptance_json",
|
|
116
113
|
"operating_mode.terms_json", "decision.options", "run_tool.tools_json",
|
|
117
114
|
"run_tool.tools_json.fence", "mate_ask.options_json", "mutation.result", "plan_revision.changed_fields",
|
|
118
|
-
"run_checkpoint.snapshot_json", "
|
|
115
|
+
"run_checkpoint.snapshot_json", "publication_grant.capabilities",
|
|
119
116
|
"coordinator_proposal.payload_json", "coordinator_proposal.outcome_json",
|
|
120
117
|
"mate_proposal.payload_json", "mate_proposal.outcome_json",
|
|
121
118
|
];
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* is answered with why (`value.so: must be a Toolroll button token`), and nothing is done.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
|
+
import { CHAT_BUTTON_TOKEN } from "./chat-content.js";
|
|
8
9
|
import { parseContract } from "./contract.js";
|
|
9
|
-
export const teamsSubmitSchema = z.object({ so: z.string().regex(
|
|
10
|
+
export const teamsSubmitSchema = z.object({ so: z.string().regex(CHAT_BUTTON_TOKEN, { error: "must be a Toolroll button token" }) });
|
|
10
11
|
/** A submit's one-time token. */
|
|
11
12
|
export function readTeamsSubmit(value) {
|
|
12
13
|
const read = parseContract(z.object({ value: teamsSubmitSchema }), { value });
|
package/dist/control-ui.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/** Shared setup views over the existing project configuration and approval doors. */
|
|
2
|
+
import { type Html } from "./html.js";
|
|
2
3
|
import type { ProviderId } from "./provider.js";
|
|
3
4
|
import type { ProviderConnection } from "./provider-connection.js";
|
|
4
5
|
import { type ModelChoice } from "./setup-guide.js";
|
|
5
6
|
import type { SetupInputs } from "./control-setup.js";
|
|
6
7
|
import { type OpenRouterModels } from "./openrouter-models.js";
|
|
7
|
-
export declare function hiddenFields(values: Record<string, string>): string;
|
|
8
8
|
export declare function connectionWords(connection: ProviderConnection): string;
|
|
9
|
-
export declare function connectionHtml(provider: ProviderId, connection: ProviderConnection, task?: string):
|
|
9
|
+
export declare function connectionHtml(provider: ProviderId, connection: ProviderConnection, task?: string): Html;
|
|
10
10
|
export declare function controlSetupHtml(data: {
|
|
11
11
|
repo: string;
|
|
12
12
|
csrf: string;
|
|
@@ -25,5 +25,6 @@ export declare function controlSetupHtml(data: {
|
|
|
25
25
|
installed: boolean;
|
|
26
26
|
message?: string;
|
|
27
27
|
};
|
|
28
|
-
}):
|
|
29
|
-
|
|
28
|
+
}): Html;
|
|
29
|
+
/** `fields` may still carry the session's csrf (a caller's habit): postForm writes the one CSRF field. */
|
|
30
|
+
export declare function setupPreviewHtml(inputs: SetupInputs, fields: Record<string, string>): Html;
|