@irvingdinh/porygon-z 0.1.3

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.
Files changed (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/dist/app.module.d.ts +2 -0
  4. package/dist/app.module.js +21 -0
  5. package/dist/app.module.js.map +1 -0
  6. package/dist/core/config/config.d.ts +13 -0
  7. package/dist/core/config/config.js +67 -0
  8. package/dist/core/config/config.js.map +1 -0
  9. package/dist/core/core.module.d.ts +2 -0
  10. package/dist/core/core.module.js +24 -0
  11. package/dist/core/core.module.js.map +1 -0
  12. package/dist/core/modules/config.module.d.ts +1 -0
  13. package/dist/core/modules/config.module.js +10 -0
  14. package/dist/core/modules/config.module.js.map +1 -0
  15. package/dist/core/modules/index.d.ts +1 -0
  16. package/dist/core/modules/index.js +6 -0
  17. package/dist/core/modules/index.js.map +1 -0
  18. package/dist/core/services/index.d.ts +2 -0
  19. package/dist/core/services/index.js +6 -0
  20. package/dist/core/services/index.js.map +1 -0
  21. package/dist/core/services/template.service.d.ts +7 -0
  22. package/dist/core/services/template.service.js +93 -0
  23. package/dist/core/services/template.service.js.map +1 -0
  24. package/dist/core/templates/slack/commands/command-cd-error-escape.handlebars +1 -0
  25. package/dist/core/templates/slack/commands/command-cd-error-not-found.handlebars +1 -0
  26. package/dist/core/templates/slack/commands/command-cd-ok.handlebars +1 -0
  27. package/dist/core/templates/slack/commands/command-cd-show.handlebars +1 -0
  28. package/dist/core/templates/slack/commands/command-kill-ok.handlebars +1 -0
  29. package/dist/core/templates/slack/commands/command-ll-error.handlebars +2 -0
  30. package/dist/core/templates/slack/commands/command-ll-ok.handlebars +1 -0
  31. package/dist/core/templates/slack/commands/command-sh-error-usage.handlebars +1 -0
  32. package/dist/core/templates/slack/commands/command-workspace-ok-created.handlebars +9 -0
  33. package/dist/core/templates/slack/commands/command-workspace-ok.handlebars +7 -0
  34. package/dist/core/templates/slack/listeners/listener-message-attachments.handlebars +13 -0
  35. package/dist/core/templates/slack/listeners/listener-message-error.handlebars +1 -0
  36. package/dist/core/templates/slack/listeners/listener-message-follow-up-prompt.handlebars +26 -0
  37. package/dist/core/templates/slack/listeners/listener-message-session-corrupted.handlebars +1 -0
  38. package/dist/core/templates/slack/listeners/listener-message-session-expired.handlebars +1 -0
  39. package/dist/core/templates/slack/listeners/listener-message-system-prompt.handlebars +79 -0
  40. package/dist/main.d.ts +2 -0
  41. package/dist/main.js +11 -0
  42. package/dist/main.js.map +1 -0
  43. package/dist/slack/services/attachment.service.d.ts +23 -0
  44. package/dist/slack/services/attachment.service.js +113 -0
  45. package/dist/slack/services/attachment.service.js.map +1 -0
  46. package/dist/slack/services/bot.service.d.ts +16 -0
  47. package/dist/slack/services/bot.service.js +61 -0
  48. package/dist/slack/services/bot.service.js.map +1 -0
  49. package/dist/slack/services/claude-formatter.service.d.ts +9 -0
  50. package/dist/slack/services/claude-formatter.service.js +116 -0
  51. package/dist/slack/services/claude-formatter.service.js.map +1 -0
  52. package/dist/slack/services/claude.service.d.ts +48 -0
  53. package/dist/slack/services/claude.service.js +97 -0
  54. package/dist/slack/services/claude.service.js.map +1 -0
  55. package/dist/slack/services/commands/command-cd.service.d.ts +12 -0
  56. package/dist/slack/services/commands/command-cd.service.js +88 -0
  57. package/dist/slack/services/commands/command-cd.service.js.map +1 -0
  58. package/dist/slack/services/commands/command-kill.service.d.ts +12 -0
  59. package/dist/slack/services/commands/command-kill.service.js +40 -0
  60. package/dist/slack/services/commands/command-kill.service.js.map +1 -0
  61. package/dist/slack/services/commands/command-ll.service.d.ts +12 -0
  62. package/dist/slack/services/commands/command-ll.service.js +52 -0
  63. package/dist/slack/services/commands/command-ll.service.js.map +1 -0
  64. package/dist/slack/services/commands/command-sh.service.d.ts +10 -0
  65. package/dist/slack/services/commands/command-sh.service.js +38 -0
  66. package/dist/slack/services/commands/command-sh.service.js.map +1 -0
  67. package/dist/slack/services/commands/command-workspace.service.d.ts +15 -0
  68. package/dist/slack/services/commands/command-workspace.service.js +302 -0
  69. package/dist/slack/services/commands/command-workspace.service.js.map +1 -0
  70. package/dist/slack/services/commands/index.d.ts +13 -0
  71. package/dist/slack/services/commands/index.js +26 -0
  72. package/dist/slack/services/commands/index.js.map +1 -0
  73. package/dist/slack/services/commands/registry.service.d.ts +13 -0
  74. package/dist/slack/services/commands/registry.service.js +38 -0
  75. package/dist/slack/services/commands/registry.service.js.map +1 -0
  76. package/dist/slack/services/index.d.ts +15 -0
  77. package/dist/slack/services/index.js +22 -0
  78. package/dist/slack/services/index.js.map +1 -0
  79. package/dist/slack/services/listeners/index.d.ts +9 -0
  80. package/dist/slack/services/listeners/index.js +16 -0
  81. package/dist/slack/services/listeners/index.js.map +1 -0
  82. package/dist/slack/services/listeners/listener-message.service.d.ts +28 -0
  83. package/dist/slack/services/listeners/listener-message.service.js +297 -0
  84. package/dist/slack/services/listeners/listener-message.service.js.map +1 -0
  85. package/dist/slack/services/listeners/registry.service.d.ts +13 -0
  86. package/dist/slack/services/listeners/registry.service.js +38 -0
  87. package/dist/slack/services/listeners/registry.service.js.map +1 -0
  88. package/dist/slack/services/thread.service.d.ts +22 -0
  89. package/dist/slack/services/thread.service.js +125 -0
  90. package/dist/slack/services/thread.service.js.map +1 -0
  91. package/dist/slack/services/workspace.service.d.ts +21 -0
  92. package/dist/slack/services/workspace.service.js +98 -0
  93. package/dist/slack/services/workspace.service.js.map +1 -0
  94. package/dist/slack/slack.module.d.ts +2 -0
  95. package/dist/slack/slack.module.js +23 -0
  96. package/dist/slack/slack.module.js.map +1 -0
  97. package/dist/tsconfig.build.tsbuildinfo +1 -0
  98. package/package.json +75 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Irving Dinh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # Porygon-Z
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@irvingdinh/porygon-z.svg)](https://www.npmjs.com/package/@irvingdinh/porygon-z)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Node.js Version](https://img.shields.io/node/v/@irvingdinh/porygon-z.svg)](https://nodejs.org)
6
+
7
+ Run Claude Code directly from Slack. Porygon-Z connects your Slack workspace to Claude's coding capabilities — ask questions, execute tasks, and manage files without leaving your chat.
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ SLACK_APP_TOKEN=xapp-... SLACK_BOT_TOKEN=xoxb-... npx @irvingdinh/porygon-z@latest
13
+ ```
14
+
15
+ ## Prerequisites
16
+
17
+ - **Node.js** >= 20
18
+ - **Claude CLI** — installed, configured, and authenticated ([installation guide](https://docs.anthropic.com/en/docs/claude-code/getting-started))
19
+ - **Slack App** — with Socket Mode enabled and the required scopes (see [Appendix: Slack App Setup](#appendix-slack-app-setup))
20
+
21
+ ## Configuration
22
+
23
+ Porygon-Z is configured through environment variables:
24
+
25
+ | Variable | Required | Description |
26
+ |---|---|---|
27
+ | `SLACK_APP_TOKEN` | Yes | Slack app-level token (`xapp-...`) for Socket Mode |
28
+ | `SLACK_BOT_TOKEN` | Yes | Slack bot token (`xoxb-...`) for API calls |
29
+ | `DATA_DIR` | No | Data directory (defaults to `~/.porygon-z`) |
30
+
31
+ You can set these inline, export them, or use a `.env` file in your working directory.
32
+
33
+ ## Usage
34
+
35
+ Once running, send a direct message to the Porygon-Z bot in Slack. It will spawn a Claude Code session to handle your request and stream the response back to your thread.
36
+
37
+ ### Slash Commands
38
+
39
+ | Command | Description |
40
+ |---|---|
41
+ | `/workspace` | Configure the workspace for the current channel — set working directory, Claude model, effort level, and permission mode |
42
+ | `/cd <path>` | Change the working directory for the current channel |
43
+ | `/ll` | List files in the current working directory |
44
+ | `/kill` | Kill all running Claude processes |
45
+
46
+ ### Features
47
+
48
+ - **Streaming responses** — see Claude's thinking and tool usage in real-time
49
+ - **Session persistence** — continue conversations across messages in the same thread
50
+ - **File handling** — attach files to your message; generated files are uploaded back
51
+ - **Per-channel workspaces** — configure different working directories, models, and settings per channel
52
+ - **Thread serialization** — requests within a thread are processed one at a time to prevent conflicts
53
+
54
+ ### Workspace Configuration
55
+
56
+ Use the `/workspace` command to configure per-channel settings:
57
+
58
+ - **Working directory** — where Claude executes commands
59
+ - **Model** — Claude model to use (e.g., `sonnet`, `opus`)
60
+ - **Effort level** — Claude's effort level (`low`, `medium`, `high`, `max`)
61
+ - **Permission mode** — controls Claude's autonomy (`plan`, `auto`, `bypassPermissions`)
62
+
63
+ ## Development
64
+
65
+ ```bash
66
+ # Install dependencies
67
+ npm install
68
+
69
+ # Run in watch mode
70
+ npm run start:dev
71
+
72
+ # Build
73
+ npm run build
74
+
75
+ # Lint
76
+ npm run lint
77
+ ```
78
+
79
+ ## License
80
+
81
+ [MIT](LICENSE)
82
+
83
+ ---
84
+
85
+ ## Appendix: Slack App Setup
86
+
87
+ Follow these steps to create and configure a Slack app for Porygon-Z.
88
+
89
+ ### 1. Create a New Slack App
90
+
91
+ 1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App**
92
+ 2. Choose **From scratch**
93
+ 3. Enter an app name (e.g., "Porygon-Z") and select your workspace
94
+ 4. Click **Create App**
95
+
96
+ ### 2. Enable Socket Mode
97
+
98
+ 1. In the left sidebar, go to **Socket Mode**
99
+ 2. Toggle **Enable Socket Mode** on
100
+ 3. When prompted, create an app-level token with the `connections:write` scope
101
+ 4. Name it (e.g., "socket-token") and click **Generate**
102
+ 5. Copy the token (`xapp-...`) — this is your `SLACK_APP_TOKEN`
103
+
104
+ ### 3. Configure Bot Token Scopes
105
+
106
+ 1. Go to **OAuth & Permissions** in the left sidebar
107
+ 2. Under **Scopes > Bot Token Scopes**, add the following:
108
+
109
+ | Scope | Purpose |
110
+ |---|---|
111
+ | `chat:write` | Send messages |
112
+ | `chat:write.customize` | Send messages with custom username/avatar |
113
+ | `files:read` | Download user-attached files |
114
+ | `files:write` | Upload generated files |
115
+ | `reactions:write` | Add status emoji reactions |
116
+ | `app_mentions:read` | Detect @mentions |
117
+ | `channels:read` | Access channel info |
118
+ | `channels:history` | Read channel messages |
119
+ | `groups:read` | Access private channel info |
120
+ | `groups:history` | Read private channel messages |
121
+ | `im:read` | Access DM info |
122
+ | `im:history` | Read DM messages |
123
+ | `mpim:history` | Read group DM messages |
124
+ | `users:read` | Access user info |
125
+
126
+ 3. Click **Install to Workspace** (or **Reinstall** if already installed)
127
+ 4. Copy the **Bot User OAuth Token** (`xoxb-...`) — this is your `SLACK_BOT_TOKEN`
128
+
129
+ ### 4. Subscribe to Bot Events
130
+
131
+ 1. Go to **Event Subscriptions** in the left sidebar
132
+ 2. Toggle **Enable Events** on
133
+ 3. Under **Subscribe to bot events**, add:
134
+ - `message.im` — listens for direct messages to the bot
135
+
136
+ ### 5. Register Slash Commands
137
+
138
+ 1. Go to **Slash Commands** in the left sidebar
139
+ 2. Create the following commands:
140
+
141
+ | Command | Short Description |
142
+ |---|---|
143
+ | `/workspace` | Configure workspace settings |
144
+ | `/cd` | Change working directory |
145
+ | `/ll` | List files |
146
+ | `/kill` | Kill running processes |
147
+
148
+ For each command, set the **Request URL** to any placeholder (Socket Mode does not use it).
149
+
150
+ ### 6. Configure App Home
151
+
152
+ 1. Go to **App Home** in the left sidebar
153
+ 2. Under **Show Tabs**, enable **Messages Tab**
154
+ 3. Check **Allow users to send Slash commands and messages from the messages tab**
155
+
156
+ ### 7. Start Porygon-Z
157
+
158
+ ```bash
159
+ SLACK_APP_TOKEN=xapp-... SLACK_BOT_TOKEN=xoxb-... npx @irvingdinh/porygon-z@latest
160
+ ```
161
+
162
+ Send a direct message to your bot in Slack — you should see it respond with Claude's output.
@@ -0,0 +1,2 @@
1
+ export declare class AppModule {
2
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AppModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const core_module_1 = require("./core/core.module");
12
+ const slack_module_1 = require("./slack/slack.module");
13
+ let AppModule = class AppModule {
14
+ };
15
+ exports.AppModule = AppModule;
16
+ exports.AppModule = AppModule = __decorate([
17
+ (0, common_1.Module)({
18
+ imports: [core_module_1.CoreModule, slack_module_1.SlackModule],
19
+ })
20
+ ], AppModule);
21
+ //# sourceMappingURL=app.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AAExC,oDAAgD;AAChD,uDAAmD;AAK5C,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAHrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,wBAAU,EAAE,0BAAW,CAAC;KACnC,CAAC;GACW,SAAS,CAAG"}
@@ -0,0 +1,13 @@
1
+ export interface AppConfig {
2
+ slack: {
3
+ appToken: string;
4
+ botToken: string;
5
+ };
6
+ dir: {
7
+ home: string;
8
+ temp: string;
9
+ };
10
+ }
11
+ export declare const config: () => {
12
+ root: AppConfig;
13
+ };
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.config = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const os = __importStar(require("node:os"));
39
+ const path = __importStar(require("node:path"));
40
+ const ensureHomeDir = () => {
41
+ const dir = process.env.DATA_DIR || path.join(os.homedir(), '.porygon-z');
42
+ fs.mkdirSync(dir, { recursive: true });
43
+ return dir;
44
+ };
45
+ const ensureTempDir = () => {
46
+ return os.tmpdir();
47
+ };
48
+ const ensureEnv = (env) => {
49
+ if (process.env[env] === undefined) {
50
+ throw new Error(`${env} is required`);
51
+ }
52
+ return process.env[env];
53
+ };
54
+ const config = () => ({
55
+ root: {
56
+ slack: {
57
+ appToken: ensureEnv('SLACK_APP_TOKEN'),
58
+ botToken: ensureEnv('SLACK_BOT_TOKEN'),
59
+ },
60
+ dir: {
61
+ home: ensureHomeDir(),
62
+ temp: ensureTempDir(),
63
+ },
64
+ },
65
+ });
66
+ exports.config = config;
67
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/core/config/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,4CAA8B;AAC9B,gDAAkC;AAalC,MAAM,aAAa,GAAG,GAAW,EAAE;IACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;IAC1E,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,GAAW,EAAE;IACjC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;IACxC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEK,MAAM,MAAM,GAAG,GAAwB,EAAE,CAAC,CAAC;IAChD,IAAI,EAAE;QACJ,KAAK,EAAE;YACL,QAAQ,EAAE,SAAS,CAAC,iBAAiB,CAAC;YACtC,QAAQ,EAAE,SAAS,CAAC,iBAAiB,CAAC;SACvC;QACD,GAAG,EAAE;YACH,IAAI,EAAE,aAAa,EAAE;YACrB,IAAI,EAAE,aAAa,EAAE;SACtB;KACF;CACF,CAAC,CAAC;AAXU,QAAA,MAAM,UAWhB"}
@@ -0,0 +1,2 @@
1
+ export declare class CoreModule {
2
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CoreModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const modules_1 = require("./modules");
12
+ const services_1 = require("./services");
13
+ let CoreModule = class CoreModule {
14
+ };
15
+ exports.CoreModule = CoreModule;
16
+ exports.CoreModule = CoreModule = __decorate([
17
+ (0, common_1.Global)(),
18
+ (0, common_1.Module)({
19
+ imports: [...modules_1.modules],
20
+ providers: [...services_1.services],
21
+ exports: [...services_1.services],
22
+ })
23
+ ], CoreModule);
24
+ //# sourceMappingURL=core.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.module.js","sourceRoot":"","sources":["../../src/core/core.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAEhD,uCAAoC;AACpC,yCAAsC;AAQ/B,IAAM,UAAU,GAAhB,MAAM,UAAU;CAAG,CAAA;AAAb,gCAAU;qBAAV,UAAU;IANtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,GAAG,iBAAO,CAAC;QACrB,SAAS,EAAE,CAAC,GAAG,mBAAQ,CAAC;QACxB,OAAO,EAAE,CAAC,GAAG,mBAAQ,CAAC;KACvB,CAAC;GACW,UAAU,CAAG"}
@@ -0,0 +1 @@
1
+ export declare const configModule: Promise<import("@nestjs/common").DynamicModule>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configModule = void 0;
4
+ const config_1 = require("@nestjs/config");
5
+ const config_2 = require("../config/config");
6
+ exports.configModule = config_1.ConfigModule.forRoot({
7
+ isGlobal: true,
8
+ load: [config_2.config],
9
+ });
10
+ //# sourceMappingURL=config.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.module.js","sourceRoot":"","sources":["../../../src/core/modules/config.module.ts"],"names":[],"mappings":";;;AAAA,2CAA8C;AAE9C,6CAA0C;AAE7B,QAAA,YAAY,GAAG,qBAAY,CAAC,OAAO,CAAC;IAC/C,QAAQ,EAAE,IAAI;IACd,IAAI,EAAE,CAAC,eAAM,CAAC;CACf,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const modules: Promise<import("@nestjs/common").DynamicModule>[];
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.modules = void 0;
4
+ const config_module_1 = require("./config.module");
5
+ exports.modules = [config_module_1.configModule];
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/modules/index.ts"],"names":[],"mappings":";;;AAAA,mDAA+C;AAElC,QAAA,OAAO,GAAG,CAAC,4BAAY,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { TemplateService } from './template.service';
2
+ export declare const services: (typeof TemplateService)[];
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.services = void 0;
4
+ const template_service_1 = require("./template.service");
5
+ exports.services = [template_service_1.TemplateService];
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/services/index.ts"],"names":[],"mappings":";;;AAAA,yDAAqD;AAExC,QAAA,QAAQ,GAAG,CAAC,kCAAe,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare class TemplateService {
2
+ private readonly logger;
3
+ private readonly templates;
4
+ constructor();
5
+ render(name: string, context?: Record<string, unknown>): string;
6
+ private loadTemplates;
7
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ var TemplateService_1;
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.TemplateService = void 0;
50
+ const fs = __importStar(require("node:fs"));
51
+ const path = __importStar(require("node:path"));
52
+ const common_1 = require("@nestjs/common");
53
+ const handlebars_1 = __importDefault(require("handlebars"));
54
+ let TemplateService = TemplateService_1 = class TemplateService {
55
+ logger = new common_1.Logger(TemplateService_1.name);
56
+ templates = new Map();
57
+ constructor() {
58
+ const templatesDir = path.join(__dirname, '..', 'templates');
59
+ this.loadTemplates(templatesDir, '');
60
+ this.logger.log(`Loaded ${this.templates.size} template(s)`);
61
+ }
62
+ render(name, context = {}) {
63
+ const template = this.templates.get(name);
64
+ if (!template) {
65
+ throw new Error(`Template not found: ${name}`);
66
+ }
67
+ return template(context);
68
+ }
69
+ loadTemplates(dir, prefix) {
70
+ if (!fs.existsSync(dir))
71
+ return;
72
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
73
+ for (const entry of entries) {
74
+ const fullPath = path.join(dir, entry.name);
75
+ if (entry.isDirectory()) {
76
+ const nextPrefix = prefix ? `${prefix}.${entry.name}` : entry.name;
77
+ this.loadTemplates(fullPath, nextPrefix);
78
+ }
79
+ else if (entry.name.endsWith('.handlebars')) {
80
+ const name = entry.name.replace(/\.handlebars$/, '');
81
+ const key = prefix ? `${prefix}.${name}` : name;
82
+ const source = fs.readFileSync(fullPath, 'utf-8');
83
+ this.templates.set(key, handlebars_1.default.compile(source));
84
+ }
85
+ }
86
+ }
87
+ };
88
+ exports.TemplateService = TemplateService;
89
+ exports.TemplateService = TemplateService = TemplateService_1 = __decorate([
90
+ (0, common_1.Injectable)(),
91
+ __metadata("design:paramtypes", [])
92
+ ], TemplateService);
93
+ //# sourceMappingURL=template.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.service.js","sourceRoot":"","sources":["../../../src/core/services/template.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAElC,2CAAoD;AACpD,4DAAoC;AAG7B,IAAM,eAAe,uBAArB,MAAM,eAAe;IACT,MAAM,GAAG,IAAI,eAAM,CAAC,iBAAe,CAAC,IAAI,CAAC,CAAC;IAC1C,SAAS,GAAG,IAAI,GAAG,EAAuC,CAAC;IAE5E;QACE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,cAAc,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,UAAmC,EAAE;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAEO,aAAa,CAAC,GAAW,EAAE,MAAc;QAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO;QAEhC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAE5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;gBACnE,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAC3C,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;gBACrD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChD,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAClD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAA;AArCY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;;GACA,eAAe,CAqC3B"}
@@ -0,0 +1 @@
1
+ :x: Invalid path: `{{target}}` escapes the current directory.
@@ -0,0 +1 @@
1
+ :x: Directory does not exist: `{{resolved}}`
@@ -0,0 +1 @@
1
+ :file_folder: Changed directory to `{{cwd}}`
@@ -0,0 +1 @@
1
+ :file_folder: Current directory: `{{cwd}}`
@@ -0,0 +1 @@
1
+ :skull_and_crossbones: Killed {{count}} running Claude process{{#if plural}}es{{/if}}.
@@ -0,0 +1,2 @@
1
+ :x: `{{cwd}}`
2
+ ```{{message}}```
@@ -0,0 +1 @@
1
+ ```{{output}}```
@@ -0,0 +1 @@
1
+ :x: Usage: `/sh <command>` — e.g. `/sh make restart`
@@ -0,0 +1,9 @@
1
+ :warning: Directory `{{cwd}}` did not exist and was created.
2
+
3
+ :white_check_mark: Workspace configuration saved.
4
+
5
+ > *Working Directory:* `{{cwd}}`
6
+ > *Model:* `{{model}}`
7
+ > *Effort:* `{{effort}}`
8
+ > *Permission Mode:* `{{permissionLabel}}`
9
+ {{#if hasSystemPrompt}}> *Workspace Instruction:* _(set)_{{else}}> *Workspace Instruction:* _(none)_{{/if}}
@@ -0,0 +1,7 @@
1
+ :white_check_mark: Workspace configuration saved.
2
+
3
+ > *Working Directory:* `{{cwd}}`
4
+ > *Model:* `{{model}}`
5
+ > *Effort:* `{{effort}}`
6
+ > *Permission Mode:* `{{permissionLabel}}`
7
+ {{#if hasSystemPrompt}}> *Workspace Instruction:* _(set)_{{else}}> *Workspace Instruction:* _(none)_{{/if}}
@@ -0,0 +1,13 @@
1
+ {{#if attachments.length}}
2
+ The user attached {{attachments.length}} file(s) with this message:
3
+ {{#each attachments}}
4
+ {{#if this.renamed}}
5
+ - {{this.path}} (original filename: "{{this.originalName}}", renamed to avoid collision)
6
+ {{else}}
7
+ - {{this.path}}
8
+ {{/if}}
9
+ {{/each}}
10
+
11
+ {{/if}}
12
+ All attachments from this conversation thread are available in: {{attachmentsDirPath}}
13
+ Read files from there as needed when the user's request references them.
@@ -0,0 +1 @@
1
+ :x: Internal error: {{message}}
@@ -0,0 +1,26 @@
1
+ You received a follow-up message from the user via Slack. Your response will be posted back to the same Slack thread by the Porygon-Z bot. Read and follow the instructions below, then process the user's message at the end of this prompt.
2
+
3
+ {{#if workspacePrompt}}
4
+ ## Workspace Instructions
5
+
6
+ {{{workspacePrompt}}}
7
+
8
+ {{/if}}
9
+ ## Attachments
10
+
11
+ {{#if attachmentsSection}}
12
+ ### Inbound
13
+
14
+ {{{attachmentsSection}}}
15
+
16
+ {{/if}}
17
+ ### Outbound
18
+
19
+ If you want to share files with the user, write them to: {{uploadDir}}
20
+ The bot will automatically upload anything placed in that directory after you finish.
21
+
22
+ ## User's Message
23
+
24
+ <UserMessage>
25
+ {{userMessage}}
26
+ </UserMessage>
@@ -0,0 +1 @@
1
+ :warning: Session data was corrupted, starting a fresh conversation.
@@ -0,0 +1 @@
1
+ :warning: Previous session expired. Starting a fresh conversation...