@pinet/slack-bridge 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/LICENSE +21 -0
- package/README.md +570 -0
- package/dist/activity-log.d.ts +62 -0
- package/dist/activity-log.js +293 -0
- package/dist/agent-completion-runtime.d.ts +17 -0
- package/dist/agent-completion-runtime.js +26 -0
- package/dist/agent-event-runtime.d.ts +13 -0
- package/dist/agent-event-runtime.js +27 -0
- package/dist/agent-prompt-guidance.d.ts +22 -0
- package/dist/agent-prompt-guidance.js +46 -0
- package/dist/broker/adapters/slack.d.ts +74 -0
- package/dist/broker/adapters/slack.js +563 -0
- package/dist/broker/adapters/types.d.ts +1 -0
- package/dist/broker/adapters/types.js +1 -0
- package/dist/broker/agent-messaging.d.ts +1 -0
- package/dist/broker/agent-messaging.js +1 -0
- package/dist/broker/auth.d.ts +1 -0
- package/dist/broker/auth.js +1 -0
- package/dist/broker/client.d.ts +167 -0
- package/dist/broker/client.js +624 -0
- package/dist/broker/control-plane-dashboard.d.ts +98 -0
- package/dist/broker/control-plane-dashboard.js +213 -0
- package/dist/broker/ghost-reaper.d.ts +49 -0
- package/dist/broker/ghost-reaper.js +209 -0
- package/dist/broker/index.d.ts +36 -0
- package/dist/broker/index.js +90 -0
- package/dist/broker/leader.d.ts +1 -0
- package/dist/broker/leader.js +1 -0
- package/dist/broker/maintenance.d.ts +1 -0
- package/dist/broker/maintenance.js +1 -0
- package/dist/broker/message-send.d.ts +1 -0
- package/dist/broker/message-send.js +1 -0
- package/dist/broker/paths.d.ts +1 -0
- package/dist/broker/paths.js +1 -0
- package/dist/broker/raw-tcp-loopback.d.ts +1 -0
- package/dist/broker/raw-tcp-loopback.js +1 -0
- package/dist/broker/router.d.ts +1 -0
- package/dist/broker/router.js +1 -0
- package/dist/broker/schema.d.ts +9 -0
- package/dist/broker/schema.js +63 -0
- package/dist/broker/socket-server.d.ts +120 -0
- package/dist/broker/socket-server.js +1087 -0
- package/dist/broker/types.d.ts +1 -0
- package/dist/broker/types.js +1 -0
- package/dist/broker-delivery.d.ts +10 -0
- package/dist/broker-delivery.js +26 -0
- package/dist/broker-inbound-persistence.d.ts +11 -0
- package/dist/broker-inbound-persistence.js +22 -0
- package/dist/broker-prompt-loader.d.ts +34 -0
- package/dist/broker-prompt-loader.js +185 -0
- package/dist/broker-runtime-access.d.ts +14 -0
- package/dist/broker-runtime-access.js +20 -0
- package/dist/broker-runtime.d.ts +100 -0
- package/dist/broker-runtime.js +533 -0
- package/dist/broker-thread-owner-hints.d.ts +10 -0
- package/dist/broker-thread-owner-hints.js +14 -0
- package/dist/canvases.d.ts +80 -0
- package/dist/canvases.js +221 -0
- package/dist/command-registration-runtime.d.ts +9 -0
- package/dist/command-registration-runtime.js +9 -0
- package/dist/core-tool-guardrails.d.ts +24 -0
- package/dist/core-tool-guardrails.js +66 -0
- package/dist/deploy-manifest.d.ts +27 -0
- package/dist/deploy-manifest.js +197 -0
- package/dist/follower-delivery.d.ts +16 -0
- package/dist/follower-delivery.js +70 -0
- package/dist/follower-runtime.d.ts +61 -0
- package/dist/follower-runtime.js +350 -0
- package/dist/git-metadata.d.ts +35 -0
- package/dist/git-metadata.js +88 -0
- package/dist/guardrails.d.ts +69 -0
- package/dist/guardrails.js +283 -0
- package/dist/helpers.d.ts +550 -0
- package/dist/helpers.js +2711 -0
- package/dist/home-tab.d.ts +27 -0
- package/dist/home-tab.js +242 -0
- package/dist/imessage-tools.d.ts +33 -0
- package/dist/imessage-tools.js +96 -0
- package/dist/inbox-drain-runtime.d.ts +30 -0
- package/dist/inbox-drain-runtime.js +71 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1330 -0
- package/dist/persisted-runtime-state.d.ts +52 -0
- package/dist/persisted-runtime-state.js +98 -0
- package/dist/pinet-activity-formatting.d.ts +20 -0
- package/dist/pinet-activity-formatting.js +43 -0
- package/dist/pinet-agent-status.d.ts +36 -0
- package/dist/pinet-agent-status.js +48 -0
- package/dist/pinet-commands.d.ts +70 -0
- package/dist/pinet-commands.js +402 -0
- package/dist/pinet-confirmation-replies.d.ts +7 -0
- package/dist/pinet-confirmation-replies.js +30 -0
- package/dist/pinet-control-plane-dashboard.d.ts +34 -0
- package/dist/pinet-control-plane-dashboard.js +86 -0
- package/dist/pinet-home-tabs.d.ts +36 -0
- package/dist/pinet-home-tabs.js +101 -0
- package/dist/pinet-maintenance-delivery.d.ts +22 -0
- package/dist/pinet-maintenance-delivery.js +45 -0
- package/dist/pinet-mesh-ops.d.ts +97 -0
- package/dist/pinet-mesh-ops.js +266 -0
- package/dist/pinet-registration-gate.d.ts +14 -0
- package/dist/pinet-registration-gate.js +42 -0
- package/dist/pinet-remote-control-acks.d.ts +16 -0
- package/dist/pinet-remote-control-acks.js +46 -0
- package/dist/pinet-remote-control.d.ts +17 -0
- package/dist/pinet-remote-control.js +74 -0
- package/dist/pinet-runtime-composition.d.ts +27 -0
- package/dist/pinet-runtime-composition.js +20 -0
- package/dist/pinet-tools.d.ts +67 -0
- package/dist/pinet-tools.js +1211 -0
- package/dist/prompts/broker/default.md +41 -0
- package/dist/prompts/broker/tmux.md +49 -0
- package/dist/ralph-loop.d.ts +76 -0
- package/dist/ralph-loop.js +524 -0
- package/dist/reaction-triggers.d.ts +25 -0
- package/dist/reaction-triggers.js +171 -0
- package/dist/repo-tool-guardrails.d.ts +20 -0
- package/dist/repo-tool-guardrails.js +81 -0
- package/dist/runtime-agent-context.d.ts +93 -0
- package/dist/runtime-agent-context.js +302 -0
- package/dist/runtime-mode.d.ts +10 -0
- package/dist/runtime-mode.js +39 -0
- package/dist/scheduled-wakeups.d.ts +1 -0
- package/dist/scheduled-wakeups.js +1 -0
- package/dist/session-ui-runtime.d.ts +20 -0
- package/dist/session-ui-runtime.js +163 -0
- package/dist/single-player-runtime.d.ts +71 -0
- package/dist/single-player-runtime.js +436 -0
- package/dist/skins/cosmere.json +1571 -0
- package/dist/skins/foundation.json +1304 -0
- package/dist/slack-access.d.ts +186 -0
- package/dist/slack-access.js +462 -0
- package/dist/slack-api.d.ts +2 -0
- package/dist/slack-api.js +1 -0
- package/dist/slack-block-kit.d.ts +36 -0
- package/dist/slack-block-kit.js +242 -0
- package/dist/slack-export.d.ts +31 -0
- package/dist/slack-export.js +206 -0
- package/dist/slack-message-context.d.ts +15 -0
- package/dist/slack-message-context.js +207 -0
- package/dist/slack-modals.d.ts +13 -0
- package/dist/slack-modals.js +79 -0
- package/dist/slack-pinet-runtime-adapter.d.ts +16 -0
- package/dist/slack-pinet-runtime-adapter.js +72 -0
- package/dist/slack-presence.d.ts +36 -0
- package/dist/slack-presence.js +89 -0
- package/dist/slack-request-runtime.d.ts +8 -0
- package/dist/slack-request-runtime.js +19 -0
- package/dist/slack-runtime-access.d.ts +28 -0
- package/dist/slack-runtime-access.js +107 -0
- package/dist/slack-scope-diagnostics.d.ts +31 -0
- package/dist/slack-scope-diagnostics.js +235 -0
- package/dist/slack-socket-dedup.d.ts +7 -0
- package/dist/slack-socket-dedup.js +135 -0
- package/dist/slack-thread-status.d.ts +41 -0
- package/dist/slack-thread-status.js +156 -0
- package/dist/slack-tool-policy-runtime.d.ts +36 -0
- package/dist/slack-tool-policy-runtime.js +96 -0
- package/dist/slack-tools.d.ts +52 -0
- package/dist/slack-tools.js +2688 -0
- package/dist/slack-turn-guardrails.d.ts +19 -0
- package/dist/slack-turn-guardrails.js +36 -0
- package/dist/slack-upload.d.ts +49 -0
- package/dist/slack-upload.js +224 -0
- package/dist/task-assignments.d.ts +45 -0
- package/dist/task-assignments.js +527 -0
- package/dist/thread-confirmations.d.ts +22 -0
- package/dist/thread-confirmations.js +139 -0
- package/dist/tool-registration-runtime.d.ts +13 -0
- package/dist/tool-registration-runtime.js +13 -0
- package/dist/ttl-cache.d.ts +47 -0
- package/dist/ttl-cache.js +105 -0
- package/manifest.yaml +57 -0
- package/package.json +60 -0
- package/skills/pinet-skin-creator/SKILL.md +109 -0
- package/skills/pinet-skin-creator/references/descriptor-format.md +99 -0
- package/skills/pinet-skin-creator/references/safety-checklist.md +56 -0
- package/skills/pinet-skin-creator/templates/pinet-skin-descriptor.json +77 -0
- package/skills/slack-bridge/SKILL.md +360 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type SlackBridgeSettings } from "./helpers.js";
|
|
3
|
+
import type { SinglePlayerThreadInfo } from "./single-player-runtime.js";
|
|
4
|
+
export interface PersistedState {
|
|
5
|
+
threads?: [string, SinglePlayerThreadInfo][];
|
|
6
|
+
lastDmChannel?: string | null;
|
|
7
|
+
userNames?: [string, string][];
|
|
8
|
+
agentName?: string;
|
|
9
|
+
agentEmoji?: string;
|
|
10
|
+
agentStableId?: string;
|
|
11
|
+
brokerStableId?: string;
|
|
12
|
+
lastPinetRole?: "broker" | "worker";
|
|
13
|
+
activeSkinTheme?: string | null;
|
|
14
|
+
agentPersonality?: string | null;
|
|
15
|
+
agentAliases?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface PersistedRuntimeStateStringCache {
|
|
18
|
+
entries: () => Iterable<[string, string]>;
|
|
19
|
+
has: (key: string) => boolean;
|
|
20
|
+
set: (key: string, value: string) => void;
|
|
21
|
+
}
|
|
22
|
+
export interface PersistedRuntimeStateDeps {
|
|
23
|
+
pi: Pick<ExtensionAPI, "appendEntry">;
|
|
24
|
+
threads: Map<string, SinglePlayerThreadInfo>;
|
|
25
|
+
userNames: PersistedRuntimeStateStringCache;
|
|
26
|
+
getLastDmChannel: () => string | null;
|
|
27
|
+
setLastDmChannel: (channelId: string | null) => void;
|
|
28
|
+
getAgentName: () => string;
|
|
29
|
+
setAgentName: (name: string) => void;
|
|
30
|
+
getAgentEmoji: () => string;
|
|
31
|
+
setAgentEmoji: (emoji: string) => void;
|
|
32
|
+
getAgentStableId: () => string;
|
|
33
|
+
setAgentStableId: (stableId: string) => void;
|
|
34
|
+
getBrokerStableId: () => string;
|
|
35
|
+
setBrokerStableId: (stableId: string) => void;
|
|
36
|
+
getBrokerRole: () => "broker" | "follower" | null;
|
|
37
|
+
getActiveSkinTheme: () => string | null;
|
|
38
|
+
setActiveSkinTheme: (theme: string | null) => void;
|
|
39
|
+
getAgentPersonality: () => string | null;
|
|
40
|
+
setAgentPersonality: (personality: string | null) => void;
|
|
41
|
+
agentAliases: Set<string>;
|
|
42
|
+
setAgentOwnerToken: (ownerToken: string) => void;
|
|
43
|
+
getSettings: () => SlackBridgeSettings;
|
|
44
|
+
formatError: (error: unknown) => string;
|
|
45
|
+
}
|
|
46
|
+
export interface PersistedRuntimeStateManager {
|
|
47
|
+
persistStateNow: () => void;
|
|
48
|
+
persistState: () => void;
|
|
49
|
+
flushPersist: () => void;
|
|
50
|
+
restorePersistedRuntimeState: (ctx: ExtensionContext) => void;
|
|
51
|
+
}
|
|
52
|
+
export declare function createPersistedRuntimeState(deps: PersistedRuntimeStateDeps): PersistedRuntimeStateManager;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import { buildPinetOwnerToken, resolveAgentStableId, resolveBrokerStableId, resolvePersistedAgentIdentity, } from "./helpers.js";
|
|
3
|
+
export function createPersistedRuntimeState(deps) {
|
|
4
|
+
let persistTimer = null;
|
|
5
|
+
function persistStateNow() {
|
|
6
|
+
persistTimer = null;
|
|
7
|
+
try {
|
|
8
|
+
deps.pi.appendEntry("slack-bridge-state", {
|
|
9
|
+
threads: Array.from(deps.threads.entries()),
|
|
10
|
+
lastDmChannel: deps.getLastDmChannel(),
|
|
11
|
+
userNames: Array.from(deps.userNames.entries()),
|
|
12
|
+
agentName: deps.getAgentName(),
|
|
13
|
+
agentEmoji: deps.getAgentEmoji(),
|
|
14
|
+
agentStableId: deps.getAgentStableId(),
|
|
15
|
+
brokerStableId: deps.getBrokerStableId(),
|
|
16
|
+
lastPinetRole: deps.getBrokerRole() === "broker" ? "broker" : "worker",
|
|
17
|
+
activeSkinTheme: deps.getActiveSkinTheme(),
|
|
18
|
+
agentPersonality: deps.getAgentPersonality(),
|
|
19
|
+
agentAliases: [...deps.agentAliases],
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(`[slack-bridge] persistState failed: ${deps.formatError(error)}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function persistState() {
|
|
27
|
+
if (persistTimer) {
|
|
28
|
+
clearTimeout(persistTimer);
|
|
29
|
+
}
|
|
30
|
+
persistTimer = setTimeout(persistStateNow, 1_000);
|
|
31
|
+
}
|
|
32
|
+
function flushPersist() {
|
|
33
|
+
if (!persistTimer) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
clearTimeout(persistTimer);
|
|
37
|
+
persistStateNow();
|
|
38
|
+
}
|
|
39
|
+
function restorePersistedRuntimeState(ctx) {
|
|
40
|
+
try {
|
|
41
|
+
let savedState = null;
|
|
42
|
+
for (const entry of ctx.sessionManager.getEntries()) {
|
|
43
|
+
if (entry.type === "custom" && entry.customType === "slack-bridge-state") {
|
|
44
|
+
savedState = entry.data;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const restoredRole = savedState?.lastPinetRole === "broker" ? "broker" : "worker";
|
|
48
|
+
const agentStableId = resolveAgentStableId(savedState?.agentStableId, ctx.sessionManager.getSessionFile(), os.hostname(), ctx.cwd, ctx.sessionManager.getLeafId());
|
|
49
|
+
const brokerStableId = resolveBrokerStableId(savedState?.brokerStableId, os.hostname(), ctx.cwd);
|
|
50
|
+
deps.setAgentStableId(agentStableId);
|
|
51
|
+
deps.setBrokerStableId(brokerStableId);
|
|
52
|
+
deps.setAgentOwnerToken(buildPinetOwnerToken(restoredRole === "broker" ? brokerStableId : agentStableId));
|
|
53
|
+
const identitySeed = restoredRole === "broker"
|
|
54
|
+
? brokerStableId
|
|
55
|
+
: (ctx.sessionManager.getSessionFile() ?? agentStableId);
|
|
56
|
+
deps.setActiveSkinTheme(savedState?.activeSkinTheme ?? null);
|
|
57
|
+
deps.setAgentPersonality(savedState?.agentPersonality ?? null);
|
|
58
|
+
deps.agentAliases.clear();
|
|
59
|
+
for (const alias of savedState?.agentAliases ?? []) {
|
|
60
|
+
if (alias) {
|
|
61
|
+
deps.agentAliases.add(alias);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const restoredIdentity = resolvePersistedAgentIdentity(deps.getSettings(), savedState?.agentName, savedState?.agentEmoji, process.env.PI_NICKNAME, identitySeed, restoredRole);
|
|
65
|
+
deps.setAgentName(restoredIdentity.name);
|
|
66
|
+
deps.setAgentEmoji(restoredIdentity.emoji);
|
|
67
|
+
if (savedState) {
|
|
68
|
+
if (savedState.threads) {
|
|
69
|
+
for (const [threadTs, info] of savedState.threads) {
|
|
70
|
+
if (!deps.threads.has(threadTs)) {
|
|
71
|
+
deps.threads.set(threadTs, info);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (savedState.lastDmChannel && !deps.getLastDmChannel()) {
|
|
76
|
+
deps.setLastDmChannel(savedState.lastDmChannel);
|
|
77
|
+
}
|
|
78
|
+
if (savedState.userNames) {
|
|
79
|
+
for (const [userId, userName] of savedState.userNames) {
|
|
80
|
+
if (!deps.userNames.has(userId)) {
|
|
81
|
+
deps.userNames.set(userId, userName);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
persistStateNow();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error(`[slack-bridge] restore failed: ${deps.formatError(error)}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
persistStateNow,
|
|
94
|
+
persistState,
|
|
95
|
+
flushPersist,
|
|
96
|
+
restorePersistedRuntimeState,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ActivityLogTone } from "./activity-log.js";
|
|
2
|
+
export type PinetTrackedAssignmentStatus = "assigned" | "branch_pushed" | "pr_open" | "pr_merged" | "pr_closed";
|
|
3
|
+
export interface PinetActivityFormattingAgentRecord {
|
|
4
|
+
emoji: string;
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PinetActivityFormattingBrokerDbPort {
|
|
8
|
+
getAgentById: (agentId: string) => PinetActivityFormattingAgentRecord | null;
|
|
9
|
+
}
|
|
10
|
+
export interface PinetActivityFormattingDeps {
|
|
11
|
+
getActiveBrokerDb: () => PinetActivityFormattingBrokerDbPort | null;
|
|
12
|
+
}
|
|
13
|
+
export interface PinetActivityFormatting {
|
|
14
|
+
formatTrackedAgent: (agentId: string) => string;
|
|
15
|
+
summarizeTrackedAssignmentStatus: (status: PinetTrackedAssignmentStatus, prNumber: number | null, branch: string | null) => {
|
|
16
|
+
summary: string;
|
|
17
|
+
tone: ActivityLogTone;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function createPinetActivityFormatting(deps: PinetActivityFormattingDeps): PinetActivityFormatting;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export function createPinetActivityFormatting(deps) {
|
|
2
|
+
function formatTrackedAgent(agentId) {
|
|
3
|
+
const agent = deps.getActiveBrokerDb()?.getAgentById(agentId);
|
|
4
|
+
if (!agent) {
|
|
5
|
+
return agentId;
|
|
6
|
+
}
|
|
7
|
+
return `${agent.emoji} ${agent.name}`.trim();
|
|
8
|
+
}
|
|
9
|
+
function summarizeTrackedAssignmentStatus(status, prNumber, branch) {
|
|
10
|
+
switch (status) {
|
|
11
|
+
case "pr_merged":
|
|
12
|
+
return {
|
|
13
|
+
summary: `PR #${prNumber ?? "?"} merged`,
|
|
14
|
+
tone: "success",
|
|
15
|
+
};
|
|
16
|
+
case "pr_open":
|
|
17
|
+
return {
|
|
18
|
+
summary: `PR #${prNumber ?? "?"} opened for review`,
|
|
19
|
+
tone: "success",
|
|
20
|
+
};
|
|
21
|
+
case "pr_closed":
|
|
22
|
+
return {
|
|
23
|
+
summary: `PR #${prNumber ?? "?"} closed without merge`,
|
|
24
|
+
tone: "warning",
|
|
25
|
+
};
|
|
26
|
+
case "branch_pushed":
|
|
27
|
+
return {
|
|
28
|
+
summary: `commits pushed on ${branch ?? "tracked branch"}`,
|
|
29
|
+
tone: "info",
|
|
30
|
+
};
|
|
31
|
+
case "assigned":
|
|
32
|
+
default:
|
|
33
|
+
return {
|
|
34
|
+
summary: "assigned",
|
|
35
|
+
tone: "info",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
formatTrackedAgent,
|
|
41
|
+
summarizeTrackedAssignmentStatus,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { SlackBridgeRuntimeMode } from "./runtime-mode.js";
|
|
3
|
+
export type PinetAgentStatusValue = "working" | "idle";
|
|
4
|
+
export interface PinetAgentStatusBrokerDbPort {
|
|
5
|
+
updateAgentStatus: (agentId: string, status: PinetAgentStatusValue) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface PinetAgentStatusDeps {
|
|
8
|
+
getPinetEnabled: () => boolean;
|
|
9
|
+
getBrokerRole: () => "broker" | "follower" | null;
|
|
10
|
+
getDesiredAgentStatus: () => PinetAgentStatusValue;
|
|
11
|
+
setDesiredAgentStatus: (status: PinetAgentStatusValue) => void;
|
|
12
|
+
getActiveBrokerDb: () => PinetAgentStatusBrokerDbPort | null;
|
|
13
|
+
getActiveBrokerSelfId: () => string | null;
|
|
14
|
+
hasFollowerClient: () => boolean;
|
|
15
|
+
syncFollowerDesiredStatus: (status: PinetAgentStatusValue, options: {
|
|
16
|
+
force?: boolean;
|
|
17
|
+
}) => Promise<void>;
|
|
18
|
+
runBrokerMaintenance: (ctx: ExtensionContext) => void;
|
|
19
|
+
getInboxLength: () => number;
|
|
20
|
+
getCurrentRuntimeMode: () => SlackBridgeRuntimeMode;
|
|
21
|
+
maybeDrainInboxIfIdle: (ctx: ExtensionContext) => boolean;
|
|
22
|
+
getExtensionContext: () => ExtensionContext | undefined;
|
|
23
|
+
}
|
|
24
|
+
export interface PinetAgentStatus {
|
|
25
|
+
syncDesiredAgentStatus: (options?: {
|
|
26
|
+
force?: boolean;
|
|
27
|
+
}) => Promise<void>;
|
|
28
|
+
reportStatus: (status: PinetAgentStatusValue) => Promise<void>;
|
|
29
|
+
signalAgentFree: (ctx?: ExtensionContext, options?: {
|
|
30
|
+
requirePinet?: boolean;
|
|
31
|
+
}) => Promise<{
|
|
32
|
+
queuedInboxCount: number;
|
|
33
|
+
drainedQueuedInbox: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
export declare function createPinetAgentStatus(deps: PinetAgentStatusDeps): PinetAgentStatus;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export function createPinetAgentStatus(deps) {
|
|
2
|
+
async function syncDesiredAgentStatus(options = {}) {
|
|
3
|
+
if (!deps.getPinetEnabled()) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
const desiredAgentStatus = deps.getDesiredAgentStatus();
|
|
7
|
+
if (deps.getBrokerRole() === "broker") {
|
|
8
|
+
const db = deps.getActiveBrokerDb();
|
|
9
|
+
const selfId = deps.getActiveBrokerSelfId();
|
|
10
|
+
if (!db || !selfId) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
db.updateAgentStatus(selfId, desiredAgentStatus);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (deps.getBrokerRole() === "follower" && deps.hasFollowerClient()) {
|
|
17
|
+
await deps.syncFollowerDesiredStatus(desiredAgentStatus, options);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function reportStatus(status) {
|
|
21
|
+
deps.setDesiredAgentStatus(status);
|
|
22
|
+
await syncDesiredAgentStatus();
|
|
23
|
+
}
|
|
24
|
+
async function signalAgentFree(ctx, options = {}) {
|
|
25
|
+
const pinetEnabled = deps.getPinetEnabled();
|
|
26
|
+
if (!pinetEnabled && options.requirePinet) {
|
|
27
|
+
throw new Error("Pinet is not running. Use /pinet start or /pinet follow first.");
|
|
28
|
+
}
|
|
29
|
+
const maintenanceCtx = ctx ?? deps.getExtensionContext() ?? undefined;
|
|
30
|
+
if (pinetEnabled) {
|
|
31
|
+
await reportStatus("idle");
|
|
32
|
+
if (deps.getBrokerRole() === "broker" && maintenanceCtx) {
|
|
33
|
+
deps.runBrokerMaintenance(maintenanceCtx);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const queuedInboxCount = deps.getInboxLength();
|
|
37
|
+
const shouldDrainQueuedInbox = pinetEnabled || deps.getCurrentRuntimeMode() === "single";
|
|
38
|
+
const drainedQueuedInbox = shouldDrainQueuedInbox && queuedInboxCount > 0 && maintenanceCtx
|
|
39
|
+
? deps.maybeDrainInboxIfIdle(maintenanceCtx)
|
|
40
|
+
: false;
|
|
41
|
+
return { queuedInboxCount, drainedQueuedInbox };
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
syncDesiredAgentStatus,
|
|
45
|
+
reportStatus,
|
|
46
|
+
signalAgentFree,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type FollowerRuntimeDiagnostic, type SlackBridgeSettings } from "./helpers.js";
|
|
3
|
+
import { type LoggedActivityLogEntry } from "./activity-log.js";
|
|
4
|
+
import { type SlackScopeDiagnostics } from "./slack-scope-diagnostics.js";
|
|
5
|
+
import type { SlackBridgeRuntimeMode } from "./runtime-mode.js";
|
|
6
|
+
import type { RalphSnoozeStatus } from "./ralph-loop.js";
|
|
7
|
+
export interface PinetCommandsDeps {
|
|
8
|
+
pinetEnabled: () => boolean;
|
|
9
|
+
pinetRegistrationBlocked: () => boolean;
|
|
10
|
+
runtimeMode: () => SlackBridgeRuntimeMode;
|
|
11
|
+
runtimeConnected: () => boolean;
|
|
12
|
+
brokerRole: () => "broker" | "follower" | null;
|
|
13
|
+
agentName: () => string;
|
|
14
|
+
agentEmoji: () => string;
|
|
15
|
+
agentOwnerToken: () => string;
|
|
16
|
+
agentPersonality: () => string | null;
|
|
17
|
+
agentAliases: () => Set<string>;
|
|
18
|
+
botUserId: () => string | null;
|
|
19
|
+
activeSkinTheme: () => string | null;
|
|
20
|
+
lastDmChannel: () => string | null;
|
|
21
|
+
followerRuntimeDiagnostic: () => FollowerRuntimeDiagnostic | null;
|
|
22
|
+
threads: () => Map<string, {
|
|
23
|
+
owner?: string;
|
|
24
|
+
}>;
|
|
25
|
+
allowedUsers: () => Set<string> | null;
|
|
26
|
+
inboxLength: () => number;
|
|
27
|
+
recentActivityLogEntries: (limit: number) => ReadonlyArray<LoggedActivityLogEntry>;
|
|
28
|
+
slackScopeDiagnostics: () => SlackScopeDiagnostics;
|
|
29
|
+
settings: () => SlackBridgeSettings;
|
|
30
|
+
lastBrokerMaintenance: () => {
|
|
31
|
+
pendingBacklogCount: number;
|
|
32
|
+
assignedBacklogCount: number;
|
|
33
|
+
reapedAgentIds: string[];
|
|
34
|
+
repairedThreadClaims: number;
|
|
35
|
+
anomalies: string[];
|
|
36
|
+
} | null;
|
|
37
|
+
ralphSnoozeStatus?: () => RalphSnoozeStatus | null;
|
|
38
|
+
snoozeRalphLoop?: (input: {
|
|
39
|
+
durationMs: number;
|
|
40
|
+
reason?: string | null;
|
|
41
|
+
}) => RalphSnoozeStatus;
|
|
42
|
+
clearRalphSnooze?: () => RalphSnoozeStatus;
|
|
43
|
+
getBrokerControlPlaneHomeTabViewerIds: () => string[];
|
|
44
|
+
lastBrokerControlPlaneHomeTabRefreshAt: () => string | null;
|
|
45
|
+
lastBrokerControlPlaneHomeTabError: () => string | null;
|
|
46
|
+
getPinetRegistrationBlockReason: () => string;
|
|
47
|
+
connectAsBroker: (ctx: ExtensionContext) => Promise<void>;
|
|
48
|
+
connectAsFollower: (ctx: ExtensionContext) => Promise<void>;
|
|
49
|
+
reloadPinetRuntime: (ctx: ExtensionContext) => Promise<void>;
|
|
50
|
+
disconnectFollower: (ctx: ExtensionContext) => Promise<{
|
|
51
|
+
unregisterError: string | null;
|
|
52
|
+
}>;
|
|
53
|
+
sendPinetAgentMessage: (target: string, body: string) => Promise<{
|
|
54
|
+
messageId: number;
|
|
55
|
+
target: string;
|
|
56
|
+
}>;
|
|
57
|
+
signalAgentFree: (ctx: ExtensionContext, options: {
|
|
58
|
+
requirePinet?: boolean;
|
|
59
|
+
}) => Promise<{
|
|
60
|
+
queuedInboxCount: number;
|
|
61
|
+
drainedQueuedInbox: boolean;
|
|
62
|
+
}>;
|
|
63
|
+
applyLocalAgentIdentity: (name: string, emoji: string, personality: string | null) => void;
|
|
64
|
+
setExtStatus: (ctx: ExtensionContext, state: "ok" | "reconnecting" | "error" | "off") => void;
|
|
65
|
+
setExtCtx: (ctx: ExtensionContext) => void;
|
|
66
|
+
}
|
|
67
|
+
export type PinetCommandAction = "start" | "follow" | "unfollow" | "reload" | "exit" | "free" | "status" | "logs" | "rename" | "snooze";
|
|
68
|
+
export declare function formatPinetCommandHelp(): string;
|
|
69
|
+
export declare function runPinetCommandAction(deps: PinetCommandsDeps, action: PinetCommandAction, args: string, ctx: ExtensionContext, usageCommand?: string): Promise<void>;
|
|
70
|
+
export declare function registerPinetCommands(pi: ExtensionAPI, deps: PinetCommandsDeps): void;
|