소스 정보
- 저장소
- dilgerma/nebulit-code-generators
- 최근 소스 활동
- 2026년 2월 16일 20:00
- 감지된 SKILL.md 언어
- 영어
- 스타
- 22
- 포크
- 9
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
SOC 직업 분류 기준
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/dilgerma/nebulit-code-generators --skill automation-slice명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | automation-slice |
| description | builds an automation slice from an event model |
Make sure to read the Agents.md file before building anything.
If the processors-Array is not empty, it´s an automation slice.
Important - an automation slice is "just" a state-change slice with an additional automation that triggers the command. So also read the skill for 'state-change-slice'
restaurantId in their metadata (camelCase)locationId or location_id - these are outdated and forbiddenrestaurant_id column (snake_case)Automations are processes that happen in the background, based on a TODO List. TODO Lists are always tables (read models) and each row in the table is a TODO Item.
The automation is only responsible to:
┌─────────────────┐
│ TODO List │ (Read Model - Inbound Dependency)
│ "items to do" │ Example: "clerks_to_invite", "items_to_fetch"
└────────┬────────┘
│
│ reads
│
┌────────▼────────┐
│ processor.ts │ (CRON scheduled automation)
│ │ - Fetches TODO items
│ │ - Fires commands
└────────┬────────┘
│
│ invokes
│
┌────────▼────────┐
│ CommandHandler │ (State-change logic)
│ Command.ts │ - decide() function
│ routes.ts │ - evolve() function
└─────────────────┘
An automation slice consists of:
Two patterns exist in the codebase:
import {ProcessorConfig, ProcessorTodoItem, startProcessor} from "../../process/process";
import {handleYourCommand} from "./YourCommandCommand";
export type ItemToProcess = {
itemId: string,
// other fields from read model
}
const config: ProcessorConfig = {
schedule: "*/5 * * * * *", // Every 5 seconds (cron format)
endpoint: "your-todo-list-collection", // Read model endpoint
query: {
"status": "OPEN", // Filter criteria
"_limit": "1" // Process one at a time
}
}
const handler = async (item: ItemToProcess & ProcessorTodoItem) => {
console.log(`Processing item: ${item.itemId}`)
try {
await handleYourCommand(`aggregate-${item.itemId}`, {
type: "YourCommand",
data: {
: item.,
},
: {}
})
.()
} (error) {
.(, error)
}
}
processor = {
: {
.()
startProcessor<>(config, handler)
}
}
import {ProcessorConfig} from "../../process/process";
import {YourCommand, handleYourCommand} from "./YourCommandCommand";
import cron from "node-cron";
import {createServiceClient} from "../../supabase/api";
const config: ProcessorConfig = {
schedule: '*/30 * * * * *', // Every 30 seconds
endpoint: "your_todo_table", // Supabase table name
}
export const processor = {
start: () => {
cron.schedule(config.schedule, async () => {
console.log("Running process")
let client = createServiceClient()
let result = await client.from(config.endpoint).select("*")
if (result.count == 0) {
console.log(`Nothing to do for ${config.endpoint}`)
return;
}
( item result. ?? []) {
: = {
: ,
: {
: item.!
},
: {}
}
id = item.
(!id) {
}
(id, command)
}
})
}
}
┌───────────── second (0-59)
│ ┌─────────── minute (0-59)
│ │ ┌───────── hour (0-23)
│ │ │ ┌─────── day of month (1-31)
│ │ │ │ ┌───── month (1-12)
│ │ │ │ │ ┌─── day of week (0-7)
│ │ │ │ │ │
* * * * * *
Common schedules:
*/5 * * * * * - Every 5 seconds*/30 * * * * * - Every 30 seconds0 */1 * * * * - Every minute0 0 * * * * - Every hourTODO List Read Model: clerks_to_invite table
Automation: src/slices/ConfirmInvitation/processor.ts
Command: ConfirmInvitationCommand
Event Emitted: ClerkInvitationConfirmed
// processor.ts
const config: ProcessorConfig = {
schedule: '*/30 * * * * *',
endpoint: "clerks_to_invite",
}
// Fetches clerks from TODO list and confirms their invitations
for (const clerk of result.data ?? []) {
const command: ConfirmInvitationCommand = {
type: "ConfirmInvitation",
data: {
clerkId: clerk.clerkId!
},
metadata: {}
}
await handleConfirmInvitation(clerk.clerkId, command)
}
in each slice folder, generate a file .slice.json
{
"id" : "<slice id>",
"slice": "<slice title>",
"context": "<contextx>",
"link": "https://miro.com/app/board/<board-id>=/?moveToWidget=<slice id>"
}
<things>_to_<action> (e.g., clerks_to_invite, items_to_fetch)/api/query/<name>-collection endpointstatus field ("OPEN", "PROCESSING", "DONE")_limit: "1" to process one item at a time, preventing concurrent issuescatalogue-${itemId})[Command]Command.ts with decide/evolve functionsroutes.ts for HTTP API endpointSample input: read 'templates/sample-input.json'
The input defines: