@poncho-ai/cli 0.12.0 → 0.13.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/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +13 -0
- package/dist/{chunk-XIFWXRUB.js → chunk-CUCEDHME.js} +125 -3
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-interactive-ink-64QEOUXL.js → run-interactive-ink-VZBOYJYS.js} +1 -1
- package/package.json +4 -3
- package/src/index.ts +130 -0
- package/src/init-feature-context.ts +5 -0
- package/src/init-onboarding.ts +10 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/cli@0.
|
|
2
|
+
> @poncho-ai/cli@0.13.0 build /home/runner/work/poncho-ai/poncho-ai/packages/cli
|
|
3
3
|
> tsup src/index.ts src/cli.ts --format esm --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es2022
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[32mESM[39m [1mdist/cli.js [22m[32m94.00 B[39m
|
|
11
|
-
[32mESM[39m [1mdist/run-interactive-ink-64QEOUXL.js [22m[32m53.83 KB[39m
|
|
12
11
|
[32mESM[39m [1mdist/index.js [22m[32m857.00 B[39m
|
|
13
|
-
[32mESM[39m [1mdist/
|
|
14
|
-
[32mESM[39m
|
|
12
|
+
[32mESM[39m [1mdist/run-interactive-ink-VZBOYJYS.js [22m[32m53.83 KB[39m
|
|
13
|
+
[32mESM[39m [1mdist/chunk-CUCEDHME.js [22m[32m245.47 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 47ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 3770ms
|
|
17
17
|
[32mDTS[39m [1mdist/cli.d.ts [22m[32m20.00 B[39m
|
|
18
18
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.56 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @poncho-ai/cli
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#10](https://github.com/cesr/poncho-ai/pull/10) [`d5bce7b`](https://github.com/cesr/poncho-ai/commit/d5bce7be5890c657bea915eb0926feb6de66b218) Thanks [@cesr](https://github.com/cesr)! - Add generic messaging layer with Slack as the first adapter. Agents can now respond to @mentions in Slack by adding `messaging: [{ platform: 'slack' }]` to `poncho.config.js`. Includes signature verification, threaded conversations, processing indicators, and Vercel `waitUntil` support.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`d5bce7b`](https://github.com/cesr/poncho-ai/commit/d5bce7be5890c657bea915eb0926feb6de66b218)]:
|
|
12
|
+
- @poncho-ai/messaging@0.2.0
|
|
13
|
+
- @poncho-ai/harness@0.13.1
|
|
14
|
+
- @poncho-ai/sdk@1.0.1
|
|
15
|
+
|
|
3
16
|
## 0.12.0
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
|
@@ -22,6 +22,10 @@ import {
|
|
|
22
22
|
resolveStateConfig
|
|
23
23
|
} from "@poncho-ai/harness";
|
|
24
24
|
import { getTextContent } from "@poncho-ai/sdk";
|
|
25
|
+
import {
|
|
26
|
+
AgentBridge,
|
|
27
|
+
SlackAdapter
|
|
28
|
+
} from "@poncho-ai/messaging";
|
|
25
29
|
import Busboy from "busboy";
|
|
26
30
|
import { Command } from "commander";
|
|
27
31
|
import dotenv from "dotenv";
|
|
@@ -3509,12 +3513,17 @@ var buildConfigFromOnboardingAnswers = (answers) => {
|
|
|
3509
3513
|
enabled: telemetryEnabled
|
|
3510
3514
|
};
|
|
3511
3515
|
maybeSet(telemetry, "otlp", answers["telemetry.otlp"]);
|
|
3512
|
-
|
|
3516
|
+
const messagingPlatform = String(answers["messaging.platform"] ?? "none");
|
|
3517
|
+
const config = {
|
|
3513
3518
|
mcp: [],
|
|
3514
3519
|
auth,
|
|
3515
3520
|
storage,
|
|
3516
3521
|
telemetry
|
|
3517
3522
|
};
|
|
3523
|
+
if (messagingPlatform !== "none") {
|
|
3524
|
+
config.messaging = [{ platform: messagingPlatform }];
|
|
3525
|
+
}
|
|
3526
|
+
return config;
|
|
3518
3527
|
};
|
|
3519
3528
|
var collectEnvVars = (answers) => {
|
|
3520
3529
|
const envVars = /* @__PURE__ */ new Set();
|
|
@@ -3658,11 +3667,13 @@ var summarizeConfig = (config) => {
|
|
|
3658
3667
|
const memoryEnabled = config?.storage?.memory?.enabled ?? config?.memory?.enabled ?? false;
|
|
3659
3668
|
const authRequired = config?.auth?.required ?? false;
|
|
3660
3669
|
const telemetryEnabled = config?.telemetry?.enabled ?? true;
|
|
3670
|
+
const messagingPlatforms = (config?.messaging ?? []).map((m) => m.platform);
|
|
3661
3671
|
return [
|
|
3662
3672
|
`storage: ${provider}`,
|
|
3663
3673
|
`memory tools: ${memoryEnabled ? "enabled" : "disabled"}`,
|
|
3664
3674
|
`auth: ${authRequired ? "required" : "not required"}`,
|
|
3665
|
-
`telemetry: ${telemetryEnabled ? "enabled" : "disabled"}
|
|
3675
|
+
`telemetry: ${telemetryEnabled ? "enabled" : "disabled"}`,
|
|
3676
|
+
...messagingPlatforms.length > 0 ? [`messaging: ${messagingPlatforms.join(", ")}`] : []
|
|
3666
3677
|
];
|
|
3667
3678
|
};
|
|
3668
3679
|
var getOnboardingMarkerPath = async (workingDir) => {
|
|
@@ -3738,6 +3749,7 @@ var consumeFirstRunIntro = async (workingDir, input2) => {
|
|
|
3738
3749
|
"- **Turn on telemetry**: Track usage with OpenTelemetry/OTLP",
|
|
3739
3750
|
"- **Add MCP servers**: Connect external tool servers",
|
|
3740
3751
|
"- **Schedule cron jobs**: Set up recurring tasks in AGENT.md frontmatter",
|
|
3752
|
+
"- **Connect to Slack**: Set up messaging so users can @mention this agent in Slack",
|
|
3741
3753
|
"",
|
|
3742
3754
|
"Just let me know what you'd like to work on!\n"
|
|
3743
3755
|
].join("\n");
|
|
@@ -4181,6 +4193,24 @@ cron:
|
|
|
4181
4193
|
- Docker/Fly.io: scheduler runs automatically.
|
|
4182
4194
|
- Trigger manually: \`curl http://localhost:3000/api/cron/daily-report\`
|
|
4183
4195
|
|
|
4196
|
+
## Messaging (Slack)
|
|
4197
|
+
|
|
4198
|
+
Connect your agent to Slack so it responds to @mentions:
|
|
4199
|
+
|
|
4200
|
+
1. Create a Slack App at [api.slack.com/apps](https://api.slack.com/apps)
|
|
4201
|
+
2. Add Bot Token Scopes: \`app_mentions:read\`, \`chat:write\`, \`reactions:write\`
|
|
4202
|
+
3. Enable Event Subscriptions, set Request URL to \`https://<your-url>/api/messaging/slack\`, subscribe to \`app_mention\`
|
|
4203
|
+
4. Install to workspace, copy Bot Token and Signing Secret
|
|
4204
|
+
5. Set env vars:
|
|
4205
|
+
\`\`\`
|
|
4206
|
+
SLACK_BOT_TOKEN=xoxb-...
|
|
4207
|
+
SLACK_SIGNING_SECRET=...
|
|
4208
|
+
\`\`\`
|
|
4209
|
+
6. Add to \`poncho.config.js\`:
|
|
4210
|
+
\`\`\`javascript
|
|
4211
|
+
messaging: [{ platform: 'slack' }]
|
|
4212
|
+
\`\`\`
|
|
4213
|
+
|
|
4184
4214
|
## Deployment
|
|
4185
4215
|
|
|
4186
4216
|
\`\`\`bash
|
|
@@ -4883,6 +4913,90 @@ var createRequestHandler = async (options) => {
|
|
|
4883
4913
|
workingDir,
|
|
4884
4914
|
agentId: identity.id
|
|
4885
4915
|
});
|
|
4916
|
+
const messagingRoutes = /* @__PURE__ */ new Map();
|
|
4917
|
+
const messagingRouteRegistrar = (method, path, routeHandler) => {
|
|
4918
|
+
let byMethod = messagingRoutes.get(path);
|
|
4919
|
+
if (!byMethod) {
|
|
4920
|
+
byMethod = /* @__PURE__ */ new Map();
|
|
4921
|
+
messagingRoutes.set(path, byMethod);
|
|
4922
|
+
}
|
|
4923
|
+
byMethod.set(method, routeHandler);
|
|
4924
|
+
};
|
|
4925
|
+
const messagingRunner = {
|
|
4926
|
+
async getOrCreateConversation(conversationId, meta) {
|
|
4927
|
+
const existing = await conversationStore.get(conversationId);
|
|
4928
|
+
if (existing) {
|
|
4929
|
+
return { messages: existing.messages };
|
|
4930
|
+
}
|
|
4931
|
+
const now = Date.now();
|
|
4932
|
+
const conversation = {
|
|
4933
|
+
conversationId,
|
|
4934
|
+
title: meta.title ?? `${meta.platform} thread`,
|
|
4935
|
+
messages: [],
|
|
4936
|
+
ownerId: meta.ownerId,
|
|
4937
|
+
tenantId: null,
|
|
4938
|
+
createdAt: now,
|
|
4939
|
+
updatedAt: now
|
|
4940
|
+
};
|
|
4941
|
+
await conversationStore.update(conversation);
|
|
4942
|
+
return { messages: [] };
|
|
4943
|
+
},
|
|
4944
|
+
async run(conversationId, input2) {
|
|
4945
|
+
const output = await harness.runToCompletion({
|
|
4946
|
+
task: input2.task,
|
|
4947
|
+
messages: input2.messages
|
|
4948
|
+
});
|
|
4949
|
+
const response = output.result.response ?? "";
|
|
4950
|
+
const conversation = await conversationStore.get(conversationId);
|
|
4951
|
+
if (conversation) {
|
|
4952
|
+
conversation.messages = [
|
|
4953
|
+
...input2.messages,
|
|
4954
|
+
{ role: "user", content: input2.task },
|
|
4955
|
+
{ role: "assistant", content: response }
|
|
4956
|
+
];
|
|
4957
|
+
await conversationStore.update(conversation);
|
|
4958
|
+
}
|
|
4959
|
+
return { response };
|
|
4960
|
+
}
|
|
4961
|
+
};
|
|
4962
|
+
const messagingBridges = [];
|
|
4963
|
+
if (config?.messaging && config.messaging.length > 0) {
|
|
4964
|
+
let waitUntilHook;
|
|
4965
|
+
if (process.env.VERCEL) {
|
|
4966
|
+
try {
|
|
4967
|
+
const modName = "@vercel/functions";
|
|
4968
|
+
const mod = await import(
|
|
4969
|
+
/* webpackIgnore: true */
|
|
4970
|
+
modName
|
|
4971
|
+
);
|
|
4972
|
+
waitUntilHook = mod.waitUntil;
|
|
4973
|
+
} catch {
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
for (const channelConfig of config.messaging) {
|
|
4977
|
+
if (channelConfig.platform === "slack") {
|
|
4978
|
+
const adapter = new SlackAdapter({
|
|
4979
|
+
botTokenEnv: channelConfig.botTokenEnv,
|
|
4980
|
+
signingSecretEnv: channelConfig.signingSecretEnv
|
|
4981
|
+
});
|
|
4982
|
+
const bridge = new AgentBridge({
|
|
4983
|
+
adapter,
|
|
4984
|
+
runner: messagingRunner,
|
|
4985
|
+
waitUntil: waitUntilHook
|
|
4986
|
+
});
|
|
4987
|
+
adapter.registerRoutes(messagingRouteRegistrar);
|
|
4988
|
+
try {
|
|
4989
|
+
await bridge.start();
|
|
4990
|
+
messagingBridges.push(bridge);
|
|
4991
|
+
console.log(` Slack messaging enabled at /api/messaging/slack`);
|
|
4992
|
+
} catch (err) {
|
|
4993
|
+
console.warn(
|
|
4994
|
+
` Slack messaging disabled: ${err instanceof Error ? err.message : String(err)}`
|
|
4995
|
+
);
|
|
4996
|
+
}
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
}
|
|
4886
5000
|
const sessionStore = new SessionStore();
|
|
4887
5001
|
const loginRateLimiter = new LoginRateLimiter();
|
|
4888
5002
|
const authToken = process.env.PONCHO_AUTH_TOKEN ?? "";
|
|
@@ -4940,6 +5054,14 @@ var createRequestHandler = async (options) => {
|
|
|
4940
5054
|
writeJson(response, 200, { status: "ok" });
|
|
4941
5055
|
return;
|
|
4942
5056
|
}
|
|
5057
|
+
const messagingByMethod = messagingRoutes.get(pathname ?? "");
|
|
5058
|
+
if (messagingByMethod) {
|
|
5059
|
+
const routeHandler = messagingByMethod.get(request.method ?? "");
|
|
5060
|
+
if (routeHandler) {
|
|
5061
|
+
await routeHandler(request, response);
|
|
5062
|
+
return;
|
|
5063
|
+
}
|
|
5064
|
+
}
|
|
4943
5065
|
const cookies = parseCookies(request);
|
|
4944
5066
|
const sessionId = cookies.poncho_session;
|
|
4945
5067
|
const session = sessionId ? sessionStore.get(sessionId) : void 0;
|
|
@@ -6036,7 +6158,7 @@ var runInteractive = async (workingDir, params) => {
|
|
|
6036
6158
|
await harness.initialize();
|
|
6037
6159
|
const identity = await ensureAgentIdentity2(workingDir);
|
|
6038
6160
|
try {
|
|
6039
|
-
const { runInteractiveInk } = await import("./run-interactive-ink-
|
|
6161
|
+
const { runInteractiveInk } = await import("./run-interactive-ink-VZBOYJYS.js");
|
|
6040
6162
|
await runInteractiveInk({
|
|
6041
6163
|
harness,
|
|
6042
6164
|
params,
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poncho-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "CLI for building and deploying AI agents",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
"react": "^19.2.4",
|
|
28
28
|
"react-devtools-core": "^6.1.5",
|
|
29
29
|
"yaml": "^2.8.1",
|
|
30
|
-
"@poncho-ai/
|
|
31
|
-
"@poncho-ai/
|
|
30
|
+
"@poncho-ai/messaging": "0.2.0",
|
|
31
|
+
"@poncho-ai/harness": "0.13.1",
|
|
32
|
+
"@poncho-ai/sdk": "1.0.1"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@types/busboy": "^1.5.4",
|
package/src/index.ts
CHANGED
|
@@ -29,6 +29,13 @@ import {
|
|
|
29
29
|
} from "@poncho-ai/harness";
|
|
30
30
|
import type { AgentEvent, FileInput, Message, RunInput } from "@poncho-ai/sdk";
|
|
31
31
|
import { getTextContent } from "@poncho-ai/sdk";
|
|
32
|
+
import {
|
|
33
|
+
AgentBridge,
|
|
34
|
+
SlackAdapter,
|
|
35
|
+
type AgentRunner,
|
|
36
|
+
type MessagingAdapter,
|
|
37
|
+
type RouteRegistrar,
|
|
38
|
+
} from "@poncho-ai/messaging";
|
|
32
39
|
import Busboy from "busboy";
|
|
33
40
|
import { Command } from "commander";
|
|
34
41
|
import dotenv from "dotenv";
|
|
@@ -567,6 +574,24 @@ cron:
|
|
|
567
574
|
- Docker/Fly.io: scheduler runs automatically.
|
|
568
575
|
- Trigger manually: \`curl http://localhost:3000/api/cron/daily-report\`
|
|
569
576
|
|
|
577
|
+
## Messaging (Slack)
|
|
578
|
+
|
|
579
|
+
Connect your agent to Slack so it responds to @mentions:
|
|
580
|
+
|
|
581
|
+
1. Create a Slack App at [api.slack.com/apps](https://api.slack.com/apps)
|
|
582
|
+
2. Add Bot Token Scopes: \`app_mentions:read\`, \`chat:write\`, \`reactions:write\`
|
|
583
|
+
3. Enable Event Subscriptions, set Request URL to \`https://<your-url>/api/messaging/slack\`, subscribe to \`app_mention\`
|
|
584
|
+
4. Install to workspace, copy Bot Token and Signing Secret
|
|
585
|
+
5. Set env vars:
|
|
586
|
+
\`\`\`
|
|
587
|
+
SLACK_BOT_TOKEN=xoxb-...
|
|
588
|
+
SLACK_SIGNING_SECRET=...
|
|
589
|
+
\`\`\`
|
|
590
|
+
6. Add to \`poncho.config.js\`:
|
|
591
|
+
\`\`\`javascript
|
|
592
|
+
messaging: [{ platform: 'slack' }]
|
|
593
|
+
\`\`\`
|
|
594
|
+
|
|
570
595
|
## Deployment
|
|
571
596
|
|
|
572
597
|
\`\`\`bash
|
|
@@ -1371,6 +1396,100 @@ export const createRequestHandler = async (options?: {
|
|
|
1371
1396
|
workingDir,
|
|
1372
1397
|
agentId: identity.id,
|
|
1373
1398
|
});
|
|
1399
|
+
// ---------------------------------------------------------------------------
|
|
1400
|
+
// Messaging adapters (Slack, etc.) — routes bypass Poncho auth; each
|
|
1401
|
+
// adapter handles its own request verification (e.g. Slack signing secret).
|
|
1402
|
+
// ---------------------------------------------------------------------------
|
|
1403
|
+
const messagingRoutes = new Map<string, Map<string, (req: IncomingMessage, res: ServerResponse) => Promise<void>>>();
|
|
1404
|
+
const messagingRouteRegistrar: RouteRegistrar = (method, path, routeHandler) => {
|
|
1405
|
+
let byMethod = messagingRoutes.get(path);
|
|
1406
|
+
if (!byMethod) {
|
|
1407
|
+
byMethod = new Map();
|
|
1408
|
+
messagingRoutes.set(path, byMethod);
|
|
1409
|
+
}
|
|
1410
|
+
byMethod.set(method, routeHandler);
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
const messagingRunner: AgentRunner = {
|
|
1414
|
+
async getOrCreateConversation(conversationId, meta) {
|
|
1415
|
+
const existing = await conversationStore.get(conversationId);
|
|
1416
|
+
if (existing) {
|
|
1417
|
+
return { messages: existing.messages };
|
|
1418
|
+
}
|
|
1419
|
+
const now = Date.now();
|
|
1420
|
+
const conversation = {
|
|
1421
|
+
conversationId,
|
|
1422
|
+
title: meta.title ?? `${meta.platform} thread`,
|
|
1423
|
+
messages: [] as Message[],
|
|
1424
|
+
ownerId: meta.ownerId,
|
|
1425
|
+
tenantId: null,
|
|
1426
|
+
createdAt: now,
|
|
1427
|
+
updatedAt: now,
|
|
1428
|
+
};
|
|
1429
|
+
await conversationStore.update(conversation);
|
|
1430
|
+
return { messages: [] };
|
|
1431
|
+
},
|
|
1432
|
+
async run(conversationId, input) {
|
|
1433
|
+
const output = await harness.runToCompletion({
|
|
1434
|
+
task: input.task,
|
|
1435
|
+
messages: input.messages,
|
|
1436
|
+
});
|
|
1437
|
+
const response = output.result.response ?? "";
|
|
1438
|
+
|
|
1439
|
+
const conversation = await conversationStore.get(conversationId);
|
|
1440
|
+
if (conversation) {
|
|
1441
|
+
conversation.messages = [
|
|
1442
|
+
...input.messages,
|
|
1443
|
+
{ role: "user" as const, content: input.task },
|
|
1444
|
+
{ role: "assistant" as const, content: response },
|
|
1445
|
+
];
|
|
1446
|
+
await conversationStore.update(conversation);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
return { response };
|
|
1450
|
+
},
|
|
1451
|
+
};
|
|
1452
|
+
|
|
1453
|
+
const messagingBridges: AgentBridge[] = [];
|
|
1454
|
+
if (config?.messaging && config.messaging.length > 0) {
|
|
1455
|
+
let waitUntilHook: ((promise: Promise<unknown>) => void) | undefined;
|
|
1456
|
+
if (process.env.VERCEL) {
|
|
1457
|
+
try {
|
|
1458
|
+
// Dynamic require via variable so TypeScript doesn't attempt static
|
|
1459
|
+
// resolution of @vercel/functions (only present in Vercel deployments).
|
|
1460
|
+
const modName = "@vercel/functions";
|
|
1461
|
+
const mod = await import(/* webpackIgnore: true */ modName);
|
|
1462
|
+
waitUntilHook = mod.waitUntil;
|
|
1463
|
+
} catch {
|
|
1464
|
+
// @vercel/functions not installed -- fall through to no-op.
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
for (const channelConfig of config.messaging) {
|
|
1469
|
+
if (channelConfig.platform === "slack") {
|
|
1470
|
+
const adapter = new SlackAdapter({
|
|
1471
|
+
botTokenEnv: channelConfig.botTokenEnv,
|
|
1472
|
+
signingSecretEnv: channelConfig.signingSecretEnv,
|
|
1473
|
+
});
|
|
1474
|
+
const bridge = new AgentBridge({
|
|
1475
|
+
adapter,
|
|
1476
|
+
runner: messagingRunner,
|
|
1477
|
+
waitUntil: waitUntilHook,
|
|
1478
|
+
});
|
|
1479
|
+
adapter.registerRoutes(messagingRouteRegistrar);
|
|
1480
|
+
try {
|
|
1481
|
+
await bridge.start();
|
|
1482
|
+
messagingBridges.push(bridge);
|
|
1483
|
+
console.log(` Slack messaging enabled at /api/messaging/slack`);
|
|
1484
|
+
} catch (err) {
|
|
1485
|
+
console.warn(
|
|
1486
|
+
` Slack messaging disabled: ${err instanceof Error ? err.message : String(err)}`,
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1374
1493
|
const sessionStore = new SessionStore();
|
|
1375
1494
|
const loginRateLimiter = new LoginRateLimiter();
|
|
1376
1495
|
|
|
@@ -1442,6 +1561,17 @@ export const createRequestHandler = async (options?: {
|
|
|
1442
1561
|
return;
|
|
1443
1562
|
}
|
|
1444
1563
|
|
|
1564
|
+
// Messaging adapter routes bypass Poncho auth (they verify requests
|
|
1565
|
+
// using platform-specific mechanisms, e.g. Slack signing secret).
|
|
1566
|
+
const messagingByMethod = messagingRoutes.get(pathname ?? "");
|
|
1567
|
+
if (messagingByMethod) {
|
|
1568
|
+
const routeHandler = messagingByMethod.get(request.method ?? "");
|
|
1569
|
+
if (routeHandler) {
|
|
1570
|
+
await routeHandler(request, response);
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1445
1575
|
const cookies = parseCookies(request);
|
|
1446
1576
|
const sessionId = cookies.poncho_session;
|
|
1447
1577
|
const session = sessionId ? sessionStore.get(sessionId) : undefined;
|
|
@@ -29,11 +29,15 @@ const summarizeConfig = (config: PonchoConfig | undefined): string[] => {
|
|
|
29
29
|
const memoryEnabled = config?.storage?.memory?.enabled ?? config?.memory?.enabled ?? false;
|
|
30
30
|
const authRequired = config?.auth?.required ?? false;
|
|
31
31
|
const telemetryEnabled = config?.telemetry?.enabled ?? true;
|
|
32
|
+
const messagingPlatforms = (config?.messaging ?? []).map((m) => m.platform);
|
|
32
33
|
return [
|
|
33
34
|
`storage: ${provider}`,
|
|
34
35
|
`memory tools: ${memoryEnabled ? "enabled" : "disabled"}`,
|
|
35
36
|
`auth: ${authRequired ? "required" : "not required"}`,
|
|
36
37
|
`telemetry: ${telemetryEnabled ? "enabled" : "disabled"}`,
|
|
38
|
+
...(messagingPlatforms.length > 0
|
|
39
|
+
? [`messaging: ${messagingPlatforms.join(", ")}`]
|
|
40
|
+
: []),
|
|
37
41
|
];
|
|
38
42
|
};
|
|
39
43
|
|
|
@@ -127,6 +131,7 @@ export const consumeFirstRunIntro = async (
|
|
|
127
131
|
"- **Turn on telemetry**: Track usage with OpenTelemetry/OTLP",
|
|
128
132
|
"- **Add MCP servers**: Connect external tool servers",
|
|
129
133
|
"- **Schedule cron jobs**: Set up recurring tasks in AGENT.md frontmatter",
|
|
134
|
+
"- **Connect to Slack**: Set up messaging so users can @mention this agent in Slack",
|
|
130
135
|
"",
|
|
131
136
|
"Just let me know what you'd like to work on!\n",
|
|
132
137
|
].join("\n");
|
package/src/init-onboarding.ts
CHANGED
|
@@ -339,12 +339,20 @@ export const buildConfigFromOnboardingAnswers = (
|
|
|
339
339
|
};
|
|
340
340
|
maybeSet(telemetry, "otlp", answers["telemetry.otlp"]);
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
const messagingPlatform = String(answers["messaging.platform"] ?? "none");
|
|
343
|
+
|
|
344
|
+
const config: PonchoConfig = {
|
|
343
345
|
mcp: [],
|
|
344
346
|
auth,
|
|
345
347
|
storage,
|
|
346
348
|
telemetry,
|
|
347
349
|
};
|
|
350
|
+
|
|
351
|
+
if (messagingPlatform !== "none") {
|
|
352
|
+
config.messaging = [{ platform: messagingPlatform as "slack" }];
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return config;
|
|
348
356
|
};
|
|
349
357
|
|
|
350
358
|
export const isDefaultOnboardingConfig = (
|
|
@@ -354,7 +362,7 @@ export const isDefaultOnboardingConfig = (
|
|
|
354
362
|
return true;
|
|
355
363
|
}
|
|
356
364
|
const topLevelKeys = Object.keys(config);
|
|
357
|
-
const allowedTopLevel = new Set(["mcp", "auth", "storage", "telemetry"]);
|
|
365
|
+
const allowedTopLevel = new Set(["mcp", "auth", "storage", "telemetry", "messaging"]);
|
|
358
366
|
if (topLevelKeys.some((key) => !allowedTopLevel.has(key))) {
|
|
359
367
|
return false;
|
|
360
368
|
}
|