@kelpie/server 0.5.2 → 0.7.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/README.md +5 -2
- package/dist/app.d.ts +13 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +9 -0
- package/dist/app.js.map +1 -1
- package/dist/boot.d.ts +42 -0
- package/dist/boot.d.ts.map +1 -0
- package/dist/boot.js +57 -0
- package/dist/boot.js.map +1 -0
- package/dist/index.d.ts +20 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/actor.d.ts +9 -1
- package/dist/lib/actor.d.ts.map +1 -1
- package/dist/lib/actor.js +13 -0
- package/dist/lib/actor.js.map +1 -1
- package/dist/lib/config.d.ts +51 -6
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +11 -5
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/email.d.ts +15 -63
- package/dist/lib/email.d.ts.map +1 -1
- package/dist/lib/email.js +13 -65
- package/dist/lib/email.js.map +1 -1
- package/dist/lib/fromEnv.d.ts +60 -0
- package/dist/lib/fromEnv.d.ts.map +1 -0
- package/dist/lib/fromEnv.js +94 -0
- package/dist/lib/fromEnv.js.map +1 -0
- package/dist/lib/ids.d.ts +6 -0
- package/dist/lib/ids.d.ts.map +1 -1
- package/dist/lib/ids.js +6 -0
- package/dist/lib/ids.js.map +1 -1
- package/dist/lib/kelpieConfigFile.d.ts +129 -0
- package/dist/lib/kelpieConfigFile.d.ts.map +1 -0
- package/dist/lib/kelpieConfigFile.js +112 -0
- package/dist/lib/kelpieConfigFile.js.map +1 -0
- package/dist/lib/logger.d.ts +38 -7
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +58 -20
- package/dist/lib/logger.js.map +1 -1
- package/dist/modules/agent-tasks/index.d.ts.map +1 -1
- package/dist/modules/agent-tasks/index.js +4 -1
- package/dist/modules/agent-tasks/index.js.map +1 -1
- package/dist/modules/agent-tasks/prompt.d.ts +36 -6
- package/dist/modules/agent-tasks/prompt.d.ts.map +1 -1
- package/dist/modules/agent-tasks/prompt.js +33 -4
- package/dist/modules/agent-tasks/prompt.js.map +1 -1
- package/dist/modules/agent-tasks/service.d.ts.map +1 -1
- package/dist/modules/agent-tasks/service.js +3 -2
- package/dist/modules/agent-tasks/service.js.map +1 -1
- package/dist/modules/agent-tasks/wire.d.ts +11 -0
- package/dist/modules/agent-tasks/wire.d.ts.map +1 -1
- package/dist/modules/agent-tasks/wire.js +1 -0
- package/dist/modules/agent-tasks/wire.js.map +1 -1
- package/dist/modules/auth/index.d.ts.map +1 -1
- package/dist/modules/auth/index.js +8 -7
- package/dist/modules/auth/index.js.map +1 -1
- package/dist/modules/companies/events.d.ts +22 -0
- package/dist/modules/companies/events.d.ts.map +1 -0
- package/dist/modules/companies/events.js +8 -0
- package/dist/modules/companies/events.js.map +1 -0
- package/dist/modules/companies/index.d.ts.map +1 -1
- package/dist/modules/companies/index.js +2 -0
- package/dist/modules/companies/index.js.map +1 -1
- package/dist/modules/companies/service.d.ts +1 -0
- package/dist/modules/companies/service.d.ts.map +1 -1
- package/dist/modules/companies/service.js +8 -11
- package/dist/modules/companies/service.js.map +1 -1
- package/dist/modules/core.d.ts.map +1 -1
- package/dist/modules/core.js +4 -0
- package/dist/modules/core.js.map +1 -1
- package/dist/modules/deals/events.d.ts +31 -0
- package/dist/modules/deals/events.d.ts.map +1 -0
- package/dist/modules/deals/events.js +12 -0
- package/dist/modules/deals/events.js.map +1 -0
- package/dist/modules/deals/index.d.ts.map +1 -1
- package/dist/modules/deals/index.js +2 -0
- package/dist/modules/deals/index.js.map +1 -1
- package/dist/modules/deals/service.d.ts +1 -0
- package/dist/modules/deals/service.d.ts.map +1 -1
- package/dist/modules/deals/service.js +9 -18
- package/dist/modules/deals/service.js.map +1 -1
- package/dist/modules/decisions/events.d.ts +21 -0
- package/dist/modules/decisions/events.d.ts.map +1 -0
- package/dist/modules/decisions/events.js +11 -0
- package/dist/modules/decisions/events.js.map +1 -0
- package/dist/modules/decisions/index.d.ts.map +1 -1
- package/dist/modules/decisions/index.js +2 -0
- package/dist/modules/decisions/index.js.map +1 -1
- package/dist/modules/decisions/service.d.ts +1 -0
- package/dist/modules/decisions/service.d.ts.map +1 -1
- package/dist/modules/decisions/service.js +4 -7
- package/dist/modules/decisions/service.js.map +1 -1
- package/dist/modules/eventCatalogs.d.ts +35 -0
- package/dist/modules/eventCatalogs.d.ts.map +1 -0
- package/dist/modules/eventCatalogs.js +35 -0
- package/dist/modules/eventCatalogs.js.map +1 -0
- package/dist/modules/forms/events.d.ts +37 -0
- package/dist/modules/forms/events.d.ts.map +1 -0
- package/dist/modules/forms/events.js +15 -0
- package/dist/modules/forms/events.js.map +1 -0
- package/dist/modules/forms/index.d.ts.map +1 -1
- package/dist/modules/forms/index.js +2 -0
- package/dist/modules/forms/index.js.map +1 -1
- package/dist/modules/forms/service.d.ts +1 -0
- package/dist/modules/forms/service.d.ts.map +1 -1
- package/dist/modules/forms/service.js +8 -11
- package/dist/modules/forms/service.js.map +1 -1
- package/dist/modules/forms/submission.d.ts +5 -0
- package/dist/modules/forms/submission.d.ts.map +1 -1
- package/dist/modules/forms/submission.js +54 -28
- package/dist/modules/forms/submission.js.map +1 -1
- package/dist/modules/handbook/events.d.ts +28 -0
- package/dist/modules/handbook/events.d.ts.map +1 -0
- package/dist/modules/handbook/events.js +14 -0
- package/dist/modules/handbook/events.js.map +1 -0
- package/dist/modules/handbook/index.d.ts.map +1 -1
- package/dist/modules/handbook/index.js +2 -0
- package/dist/modules/handbook/index.js.map +1 -1
- package/dist/modules/handbook/service.d.ts +1 -0
- package/dist/modules/handbook/service.d.ts.map +1 -1
- package/dist/modules/handbook/service.js +8 -15
- package/dist/modules/handbook/service.js.map +1 -1
- package/dist/modules/hiring/candidates.d.ts +1 -0
- package/dist/modules/hiring/candidates.d.ts.map +1 -1
- package/dist/modules/hiring/candidates.js +8 -11
- package/dist/modules/hiring/candidates.js.map +1 -1
- package/dist/modules/hiring/events.d.ts +35 -0
- package/dist/modules/hiring/events.d.ts.map +1 -0
- package/dist/modules/hiring/events.js +11 -0
- package/dist/modules/hiring/events.js.map +1 -0
- package/dist/modules/hiring/index.d.ts.map +1 -1
- package/dist/modules/hiring/index.js +2 -0
- package/dist/modules/hiring/index.js.map +1 -1
- package/dist/modules/hiring/roles.d.ts +1 -0
- package/dist/modules/hiring/roles.d.ts.map +1 -1
- package/dist/modules/hiring/roles.js +8 -11
- package/dist/modules/hiring/roles.js.map +1 -1
- package/dist/modules/import-export/drafts.d.ts +9 -0
- package/dist/modules/import-export/drafts.d.ts.map +1 -1
- package/dist/modules/import-export/drafts.js +25 -0
- package/dist/modules/import-export/drafts.js.map +1 -1
- package/dist/modules/import-export/events.d.ts +22 -0
- package/dist/modules/import-export/events.d.ts.map +1 -0
- package/dist/modules/import-export/events.js +12 -0
- package/dist/modules/import-export/events.js.map +1 -0
- package/dist/modules/import-export/exportRows.d.ts +9 -0
- package/dist/modules/import-export/exportRows.d.ts.map +1 -1
- package/dist/modules/import-export/exportRows.js +10 -1
- package/dist/modules/import-export/exportRows.js.map +1 -1
- package/dist/modules/import-export/index.d.ts.map +1 -1
- package/dist/modules/import-export/index.js +2 -0
- package/dist/modules/import-export/index.js.map +1 -1
- package/dist/modules/import-export/plan.d.ts +23 -1
- package/dist/modules/import-export/plan.d.ts.map +1 -1
- package/dist/modules/import-export/plan.js +62 -3
- package/dist/modules/import-export/plan.js.map +1 -1
- package/dist/modules/import-export/presets.d.ts.map +1 -1
- package/dist/modules/import-export/presets.js +25 -0
- package/dist/modules/import-export/presets.js.map +1 -1
- package/dist/modules/import-export/repository.d.ts +17 -0
- package/dist/modules/import-export/repository.d.ts.map +1 -1
- package/dist/modules/import-export/repository.js +21 -1
- package/dist/modules/import-export/repository.js.map +1 -1
- package/dist/modules/import-export/routes.d.ts.map +1 -1
- package/dist/modules/import-export/routes.js +5 -1
- package/dist/modules/import-export/routes.js.map +1 -1
- package/dist/modules/import-export/schema.d.ts +55 -0
- package/dist/modules/import-export/schema.d.ts.map +1 -1
- package/dist/modules/import-export/schema.js +13 -1
- package/dist/modules/import-export/schema.js.map +1 -1
- package/dist/modules/import-export/service.d.ts +9 -1
- package/dist/modules/import-export/service.d.ts.map +1 -1
- package/dist/modules/import-export/service.js +104 -17
- package/dist/modules/import-export/service.js.map +1 -1
- package/dist/modules/import-export/tools.d.ts.map +1 -1
- package/dist/modules/import-export/tools.js +7 -1
- package/dist/modules/import-export/tools.js.map +1 -1
- package/dist/modules/import-export/writes.d.ts +16 -0
- package/dist/modules/import-export/writes.d.ts.map +1 -1
- package/dist/modules/import-export/writes.js +77 -2
- package/dist/modules/import-export/writes.js.map +1 -1
- package/dist/modules/notes/events.d.ts +22 -0
- package/dist/modules/notes/events.d.ts.map +1 -0
- package/dist/modules/notes/events.js +12 -0
- package/dist/modules/notes/events.js.map +1 -0
- package/dist/modules/notes/index.d.ts.map +1 -1
- package/dist/modules/notes/index.js +2 -0
- package/dist/modules/notes/index.js.map +1 -1
- package/dist/modules/notes/service.d.ts +1 -0
- package/dist/modules/notes/service.d.ts.map +1 -1
- package/dist/modules/notes/service.js +4 -7
- package/dist/modules/notes/service.js.map +1 -1
- package/dist/modules/opportunities/events.d.ts +31 -0
- package/dist/modules/opportunities/events.d.ts.map +1 -0
- package/dist/modules/opportunities/events.js +12 -0
- package/dist/modules/opportunities/events.js.map +1 -0
- package/dist/modules/opportunities/index.d.ts.map +1 -1
- package/dist/modules/opportunities/index.js +2 -0
- package/dist/modules/opportunities/index.js.map +1 -1
- package/dist/modules/opportunities/service.d.ts +1 -0
- package/dist/modules/opportunities/service.d.ts.map +1 -1
- package/dist/modules/opportunities/service.js +9 -18
- package/dist/modules/opportunities/service.js.map +1 -1
- package/dist/modules/partnerships/events.d.ts +31 -0
- package/dist/modules/partnerships/events.d.ts.map +1 -0
- package/dist/modules/partnerships/events.js +12 -0
- package/dist/modules/partnerships/events.js.map +1 -0
- package/dist/modules/partnerships/index.d.ts.map +1 -1
- package/dist/modules/partnerships/index.js +2 -0
- package/dist/modules/partnerships/index.js.map +1 -1
- package/dist/modules/partnerships/service.d.ts +1 -0
- package/dist/modules/partnerships/service.d.ts.map +1 -1
- package/dist/modules/partnerships/service.js +9 -18
- package/dist/modules/partnerships/service.js.map +1 -1
- package/dist/modules/people/events.d.ts +28 -0
- package/dist/modules/people/events.d.ts.map +1 -0
- package/dist/modules/people/events.js +18 -0
- package/dist/modules/people/events.js.map +1 -0
- package/dist/modules/people/index.d.ts.map +1 -1
- package/dist/modules/people/index.js +2 -0
- package/dist/modules/people/index.js.map +1 -1
- package/dist/modules/people/service.d.ts +1 -0
- package/dist/modules/people/service.d.ts.map +1 -1
- package/dist/modules/people/service.js +8 -11
- package/dist/modules/people/service.js.map +1 -1
- package/dist/modules/pipelines/service.d.ts +4 -0
- package/dist/modules/pipelines/service.d.ts.map +1 -1
- package/dist/modules/pipelines/service.js +31 -8
- package/dist/modules/pipelines/service.js.map +1 -1
- package/dist/modules/plans/events.d.ts +21 -0
- package/dist/modules/plans/events.d.ts.map +1 -0
- package/dist/modules/plans/events.js +11 -0
- package/dist/modules/plans/events.js.map +1 -0
- package/dist/modules/plans/index.d.ts.map +1 -1
- package/dist/modules/plans/index.js +2 -0
- package/dist/modules/plans/index.js.map +1 -1
- package/dist/modules/plans/service.d.ts +1 -0
- package/dist/modules/plans/service.d.ts.map +1 -1
- package/dist/modules/plans/service.js +6 -14
- package/dist/modules/plans/service.js.map +1 -1
- package/dist/modules/positions/events.d.ts +22 -0
- package/dist/modules/positions/events.d.ts.map +1 -0
- package/dist/modules/positions/events.js +8 -0
- package/dist/modules/positions/events.js.map +1 -0
- package/dist/modules/positions/index.d.ts.map +1 -1
- package/dist/modules/positions/index.js +2 -0
- package/dist/modules/positions/index.js.map +1 -1
- package/dist/modules/positions/service.d.ts +1 -0
- package/dist/modules/positions/service.d.ts.map +1 -1
- package/dist/modules/positions/service.js +8 -11
- package/dist/modules/positions/service.js.map +1 -1
- package/dist/modules/raises/events.d.ts +31 -0
- package/dist/modules/raises/events.d.ts.map +1 -0
- package/dist/modules/raises/events.js +12 -0
- package/dist/modules/raises/events.js.map +1 -0
- package/dist/modules/raises/index.d.ts.map +1 -1
- package/dist/modules/raises/index.js +2 -0
- package/dist/modules/raises/index.js.map +1 -1
- package/dist/modules/raises/service.d.ts +1 -0
- package/dist/modules/raises/service.d.ts.map +1 -1
- package/dist/modules/raises/service.js +9 -18
- package/dist/modules/raises/service.js.map +1 -1
- package/dist/modules/reseal.d.ts +55 -0
- package/dist/modules/reseal.d.ts.map +1 -1
- package/dist/modules/reseal.js +90 -1
- package/dist/modules/reseal.js.map +1 -1
- package/dist/modules/smtp-email/index.d.ts +69 -0
- package/dist/modules/smtp-email/index.d.ts.map +1 -0
- package/dist/modules/smtp-email/index.js +82 -0
- package/dist/modules/smtp-email/index.js.map +1 -0
- package/dist/modules/webhooks/index.d.ts.map +1 -1
- package/dist/modules/webhooks/index.js +5 -1
- package/dist/modules/webhooks/index.js.map +1 -1
- package/dist/modules/webhooks/payloads.d.ts +22 -7
- package/dist/modules/webhooks/payloads.d.ts.map +1 -1
- package/dist/modules/webhooks/payloads.js +63 -44
- package/dist/modules/webhooks/payloads.js.map +1 -1
- package/dist/modules/workspace/events.d.ts +52 -0
- package/dist/modules/workspace/events.d.ts.map +1 -0
- package/dist/modules/workspace/events.js +16 -0
- package/dist/modules/workspace/events.js.map +1 -0
- package/dist/modules/workspace/index.d.ts.map +1 -1
- package/dist/modules/workspace/index.js +6 -2
- package/dist/modules/workspace/index.js.map +1 -1
- package/dist/modules/workspace/service.d.ts +1 -0
- package/dist/modules/workspace/service.d.ts.map +1 -1
- package/dist/modules/workspace/service.js +13 -15
- package/dist/modules/workspace/service.js.map +1 -1
- package/dist/runtime/events.d.ts +86 -108
- package/dist/runtime/events.d.ts.map +1 -1
- package/dist/runtime/events.js +123 -52
- package/dist/runtime/events.js.map +1 -1
- package/dist/runtime/module.d.ts +54 -2
- package/dist/runtime/module.d.ts.map +1 -1
- package/dist/runtime/registry.d.ts +23 -0
- package/dist/runtime/registry.d.ts.map +1 -1
- package/dist/runtime/registry.js +102 -2
- package/dist/runtime/registry.js.map +1 -1
- package/dist/runtime/transaction.d.ts +29 -4
- package/dist/runtime/transaction.d.ts.map +1 -1
- package/dist/runtime/transaction.js +48 -7
- package/dist/runtime/transaction.js.map +1 -1
- package/dist/testing/app.d.ts +5 -1
- package/dist/testing/app.d.ts.map +1 -1
- package/dist/testing/app.js +13 -3
- package/dist/testing/app.js.map +1 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js +6 -3
- package/dist/testing/database.js.map +1 -1
- package/dist/testing/services.d.ts +21 -1
- package/dist/testing/services.d.ts.map +1 -1
- package/dist/testing/services.js +20 -5
- package/dist/testing/services.js.map +1 -1
- package/migrations/0019_sharp_red_skull.sql +4 -0
- package/migrations/0020_early_nemesis.sql +2 -0
- package/migrations/meta/0019_snapshot.json +5138 -0
- package/migrations/meta/0020_snapshot.json +5138 -0
- package/migrations/meta/_journal.json +14 -0
- package/package.json +5 -2
- package/src/app.ts +26 -0
- package/src/boot.ts +89 -0
- package/src/index.ts +52 -9
- package/src/lib/actor.ts +15 -1
- package/src/lib/config.ts +65 -7
- package/src/lib/email.ts +22 -92
- package/src/lib/fromEnv.ts +143 -0
- package/src/lib/ids.ts +6 -0
- package/src/lib/kelpieConfigFile.ts +291 -0
- package/src/lib/logger.ts +92 -34
- package/src/modules/agent-tasks/index.ts +4 -1
- package/src/modules/agent-tasks/prompt.ts +57 -9
- package/src/modules/agent-tasks/service.ts +3 -2
- package/src/modules/agent-tasks/wire.ts +12 -0
- package/src/modules/auth/index.ts +11 -9
- package/src/modules/companies/events.ts +25 -0
- package/src/modules/companies/index.ts +2 -0
- package/src/modules/companies/service.ts +8 -11
- package/src/modules/core.ts +4 -0
- package/src/modules/deals/events.ts +34 -0
- package/src/modules/deals/index.ts +2 -0
- package/src/modules/deals/service.ts +17 -18
- package/src/modules/decisions/events.ts +24 -0
- package/src/modules/decisions/index.ts +2 -0
- package/src/modules/decisions/service.ts +8 -7
- package/src/modules/eventCatalogs.ts +35 -0
- package/src/modules/forms/events.ts +37 -0
- package/src/modules/forms/index.ts +2 -0
- package/src/modules/forms/service.ts +12 -11
- package/src/modules/forms/submission.ts +80 -29
- package/src/modules/handbook/events.ts +31 -0
- package/src/modules/handbook/index.ts +2 -0
- package/src/modules/handbook/service.ts +8 -15
- package/src/modules/hiring/candidates.ts +8 -11
- package/src/modules/hiring/events.ts +36 -0
- package/src/modules/hiring/index.ts +2 -0
- package/src/modules/hiring/roles.ts +8 -11
- package/src/modules/import-export/drafts.ts +27 -0
- package/src/modules/import-export/events.ts +25 -0
- package/src/modules/import-export/exportRows.ts +10 -1
- package/src/modules/import-export/index.ts +2 -0
- package/src/modules/import-export/plan.ts +107 -5
- package/src/modules/import-export/presets.ts +25 -0
- package/src/modules/import-export/repository.ts +35 -1
- package/src/modules/import-export/routes.ts +5 -0
- package/src/modules/import-export/schema.ts +13 -0
- package/src/modules/import-export/service.ts +153 -19
- package/src/modules/import-export/tools.ts +9 -0
- package/src/modules/import-export/writes.ts +116 -3
- package/src/modules/notes/events.ts +25 -0
- package/src/modules/notes/index.ts +2 -0
- package/src/modules/notes/service.ts +8 -7
- package/src/modules/opportunities/events.ts +34 -0
- package/src/modules/opportunities/index.ts +2 -0
- package/src/modules/opportunities/service.ts +17 -18
- package/src/modules/partnerships/events.ts +34 -0
- package/src/modules/partnerships/index.ts +2 -0
- package/src/modules/partnerships/service.ts +17 -18
- package/src/modules/people/events.ts +36 -0
- package/src/modules/people/index.ts +2 -0
- package/src/modules/people/service.ts +97 -87
- package/src/modules/pipelines/service.ts +47 -8
- package/src/modules/plans/events.ts +24 -0
- package/src/modules/plans/index.ts +2 -0
- package/src/modules/plans/service.ts +14 -14
- package/src/modules/positions/events.ts +25 -0
- package/src/modules/positions/index.ts +2 -0
- package/src/modules/positions/service.ts +8 -11
- package/src/modules/raises/events.ts +34 -0
- package/src/modules/raises/index.ts +2 -0
- package/src/modules/raises/service.ts +17 -18
- package/src/modules/reseal.ts +144 -1
- package/src/modules/smtp-email/index.ts +119 -0
- package/src/modules/webhooks/index.ts +5 -1
- package/src/modules/webhooks/payloads.ts +94 -48
- package/src/modules/workspace/events.ts +46 -0
- package/src/modules/workspace/index.ts +6 -2
- package/src/modules/workspace/service.ts +37 -15
- package/src/runtime/events.ts +268 -107
- package/src/runtime/module.ts +55 -2
- package/src/runtime/registry.ts +169 -1
- package/src/runtime/transaction.ts +94 -17
- package/src/testing/app.ts +18 -4
- package/src/testing/database.ts +6 -3
- package/src/testing/services.ts +34 -5
|
@@ -3,12 +3,22 @@ import type { AgentTaskDefinition, AgentTaskTargetType } from '@kelpie/schemas'
|
|
|
3
3
|
/**
|
|
4
4
|
* Renders the markdown prompt a ResolvedTask carries. Pure: every fact arrives
|
|
5
5
|
* as an argument, so the template is unit-testable and Copy and Run cannot
|
|
6
|
-
* drift — both read the
|
|
6
|
+
* drift — both read the strings this file produces.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Two renderers, one shared body.
|
|
9
|
+
*
|
|
10
|
+
* - {@link renderBasePrompt} returns the general request: the task title,
|
|
11
|
+
* the target, the required reads, the handbook pages, related ids,
|
|
12
|
+
* workspace signals, the task instructions, and the write policy. It
|
|
13
|
+
* says nothing about *how* the receiver should apply the changes.
|
|
14
|
+
* - {@link renderExternalAgentPrompt} wraps the base with framing for an
|
|
15
|
+
* agent that calls the CRM itself — the opening line about MCP / the
|
|
16
|
+
* public API and the closing "Done when… applied allowed updates" tail.
|
|
17
|
+
*
|
|
18
|
+
* The resolved-task and dispatch payloads carry both. The copy-prompt UI
|
|
19
|
+
* flow serves the external-agent version by default; the hosted AI in the
|
|
20
|
+
* cloud reads the base and adds its own structured-output framing. Two
|
|
21
|
+
* consumers, two wrappers, one body.
|
|
12
22
|
*/
|
|
13
23
|
|
|
14
24
|
/** A handbook page the task requires, resolved to this workspace's own copy. */
|
|
@@ -99,7 +109,13 @@ function firstRead(targetType: AgentTaskTargetType): string {
|
|
|
99
109
|
return 'Load the target record and agent fields.'
|
|
100
110
|
}
|
|
101
111
|
|
|
102
|
-
|
|
112
|
+
/**
|
|
113
|
+
* The shared body. Renders everything a receiver needs to *understand* the
|
|
114
|
+
* task, without telling it how to apply results. Callers wrap this with an
|
|
115
|
+
* opening and closing that matches how the receiver will execute (call the
|
|
116
|
+
* CRM, or return structured data for a caller to apply).
|
|
117
|
+
*/
|
|
118
|
+
export function renderBasePrompt(
|
|
103
119
|
definition: AgentTaskDefinition,
|
|
104
120
|
targetType: AgentTaskTargetType,
|
|
105
121
|
targetId: string,
|
|
@@ -107,9 +123,6 @@ export function renderPrompt(
|
|
|
107
123
|
): string {
|
|
108
124
|
return `# Agent task: ${definition.label}
|
|
109
125
|
|
|
110
|
-
You are operating on the Kelpie workspace **${inputs.workspaceName}** via MCP / the public API.
|
|
111
|
-
Bring your own model. Kelpie does not bundle AI.
|
|
112
|
-
|
|
113
126
|
## Task
|
|
114
127
|
- **Id:** \`${definition.id}\`
|
|
115
128
|
- **Intent:** ${definition.description}
|
|
@@ -133,8 +146,43 @@ ${definition.instructions}
|
|
|
133
146
|
|
|
134
147
|
## Write policy
|
|
135
148
|
${definition.writePolicy}
|
|
149
|
+
`
|
|
150
|
+
}
|
|
136
151
|
|
|
152
|
+
/**
|
|
153
|
+
* The external-agent-framed prompt. Adds the opening line about MCP / the
|
|
154
|
+
* public API and the closing "Done when" tail to the base. This is what the
|
|
155
|
+
* Copy button hands to the user and what dispatch sends by default; an
|
|
156
|
+
* agent that runs its own tool loop against the CRM reads this and works
|
|
157
|
+
* from it directly.
|
|
158
|
+
*/
|
|
159
|
+
export function renderExternalAgentPrompt(
|
|
160
|
+
definition: AgentTaskDefinition,
|
|
161
|
+
targetType: AgentTaskTargetType,
|
|
162
|
+
targetId: string,
|
|
163
|
+
inputs: PromptInputs,
|
|
164
|
+
): string {
|
|
165
|
+
const opening = `# Agent task: ${definition.label}
|
|
166
|
+
|
|
167
|
+
You are operating on the Kelpie workspace **${inputs.workspaceName}** via MCP / the public API.
|
|
168
|
+
Bring your own model. Kelpie does not bundle AI.
|
|
169
|
+
`
|
|
170
|
+
|
|
171
|
+
// The base opens with its own `# Agent task:` header; strip it so the
|
|
172
|
+
// combined prompt has one heading rather than two.
|
|
173
|
+
const base = renderBasePrompt(definition, targetType, targetId, inputs)
|
|
174
|
+
const bodyWithoutHeading = base.replace(/^# Agent task:[^\n]*\n\n?/u, '')
|
|
175
|
+
|
|
176
|
+
return `${opening}
|
|
177
|
+
${bodyWithoutHeading}
|
|
137
178
|
## Done when
|
|
138
179
|
You have applied allowed updates via MCP/API (or asked the human when blocked), and summarised what changed.
|
|
139
180
|
`
|
|
140
181
|
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Backwards-compatible alias for the pre-split renderer. Existing callers
|
|
185
|
+
* that produced the "wrapped" prompt keep working. New callers pick
|
|
186
|
+
* {@link renderBasePrompt} or {@link renderExternalAgentPrompt} directly.
|
|
187
|
+
*/
|
|
188
|
+
export const renderPrompt = renderExternalAgentPrompt
|
|
@@ -14,7 +14,7 @@ import { requireWorkspaceId } from '../auth/actor.ts'
|
|
|
14
14
|
import { roleAllows } from '../workspace/roles.ts'
|
|
15
15
|
import { AGENT_TASK_DEFINITIONS, findTask, tasksFor } from './catalog.ts'
|
|
16
16
|
import type { DispatchEngine } from './dispatch.ts'
|
|
17
|
-
import {
|
|
17
|
+
import { renderBasePrompt, renderExternalAgentPrompt } from './prompt.ts'
|
|
18
18
|
import * as repository from './repository.ts'
|
|
19
19
|
import { AGENT_SORTS, DEFAULT_AGENT_SORT, DEFAULT_RUN_SORT, RUN_SORTS } from './repository.ts'
|
|
20
20
|
import type { AgentRecord, RunFilters, RunRecord } from './repository.ts'
|
|
@@ -184,7 +184,8 @@ export function createAgentTasksService(dependencies: AgentTasksDependencies): A
|
|
|
184
184
|
taskId: definition.id,
|
|
185
185
|
targetType: target.targetType,
|
|
186
186
|
targetId: target.targetId,
|
|
187
|
-
prompt:
|
|
187
|
+
prompt: renderExternalAgentPrompt(definition, target.targetType, target.targetId, inputs),
|
|
188
|
+
basePrompt: renderBasePrompt(definition, target.targetType, target.targetId, inputs),
|
|
188
189
|
context: {
|
|
189
190
|
targetLabel: inputs.targetLabel,
|
|
190
191
|
deepLink: inputs.deepLink,
|
|
@@ -21,7 +21,18 @@ export interface ResolvedTaskView {
|
|
|
21
21
|
readonly taskId: string
|
|
22
22
|
readonly targetType: AgentTaskTargetType
|
|
23
23
|
readonly targetId: string
|
|
24
|
+
/**
|
|
25
|
+
* The external-agent-framed prompt: opens with "operating via MCP / the
|
|
26
|
+
* public API", ends with "Done when… applied allowed updates". This is
|
|
27
|
+
* what Copy hands to a user and what a customer agent reads.
|
|
28
|
+
*/
|
|
24
29
|
readonly prompt: string
|
|
30
|
+
/**
|
|
31
|
+
* The shared body without the framing. What an agent that returns
|
|
32
|
+
* structured data (the hosted AI is the one that ships) reads before
|
|
33
|
+
* adding its own instructions.
|
|
34
|
+
*/
|
|
35
|
+
readonly basePrompt: string
|
|
25
36
|
readonly context: ContextPackView
|
|
26
37
|
}
|
|
27
38
|
|
|
@@ -31,6 +42,7 @@ export function resolvedTaskResponse(resolved: ResolvedTaskView): Record<string,
|
|
|
31
42
|
target_type: resolved.targetType,
|
|
32
43
|
target_id: resolved.targetId,
|
|
33
44
|
prompt: resolved.prompt,
|
|
45
|
+
base_prompt: resolved.basePrompt,
|
|
34
46
|
context: {
|
|
35
47
|
target_label: resolved.context.targetLabel,
|
|
36
48
|
deep_link: resolved.context.deepLink,
|
|
@@ -13,12 +13,10 @@ import { createAuthService } from './service.ts'
|
|
|
13
13
|
* `users`.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
const
|
|
17
|
-
.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})
|
|
21
|
-
.merge(appUrlConfigSchema)
|
|
16
|
+
const nodeEnvSchema = z.object({
|
|
17
|
+
/** Cookies go out `Secure` everywhere except development. */
|
|
18
|
+
NODE_ENV: z.enum(['development', 'test', 'production']),
|
|
19
|
+
})
|
|
22
20
|
|
|
23
21
|
export function createAuthModule(migrationsDirectory: string): KelpieModule {
|
|
24
22
|
return {
|
|
@@ -26,14 +24,18 @@ export function createAuthModule(migrationsDirectory: string): KelpieModule {
|
|
|
26
24
|
structural: true,
|
|
27
25
|
|
|
28
26
|
register(context) {
|
|
29
|
-
const
|
|
27
|
+
const { NODE_ENV } = context.config(nodeEnvSchema)
|
|
28
|
+
// Prefer the top-level `appBaseUrl` from the assembly's kelpie.config.ts;
|
|
29
|
+
// fall back to the schema read for older assemblies that don't declare it.
|
|
30
|
+
const appBaseUrl = context.appBaseUrl ?? context.config(appUrlConfigSchema).APP_BASE_URL
|
|
31
|
+
|
|
30
32
|
const service = createAuthService({
|
|
31
33
|
db: context.db,
|
|
32
34
|
transaction: context.transaction,
|
|
33
35
|
email: context.email,
|
|
34
36
|
createId: context.createId,
|
|
35
37
|
now: context.now,
|
|
36
|
-
appBaseUrl
|
|
38
|
+
appBaseUrl,
|
|
37
39
|
})
|
|
38
40
|
|
|
39
41
|
context.schema(schema, migrationsDirectory)
|
|
@@ -46,7 +48,7 @@ export function createAuthModule(migrationsDirectory: string): KelpieModule {
|
|
|
46
48
|
// `Secure` everywhere except development. A test host reaches the API
|
|
47
49
|
// over http through a test client, which stores the cookie regardless
|
|
48
50
|
// of the flag, so test is not excluded.
|
|
49
|
-
cookie: { secure:
|
|
51
|
+
cookie: { secure: NODE_ENV !== 'development' },
|
|
50
52
|
})
|
|
51
53
|
})
|
|
52
54
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { ModuleEventCatalog } from '../../runtime/module.ts'
|
|
4
|
+
|
|
5
|
+
/** Domain events published by the companies module. */
|
|
6
|
+
|
|
7
|
+
export const companiesEvents = {
|
|
8
|
+
'companies.company.created': z.object({}).strict(),
|
|
9
|
+
'companies.company.updated': z.object({ changed: z.array(z.string()).readonly() }),
|
|
10
|
+
'companies.company.deleted': z.object({}).strict(),
|
|
11
|
+
} satisfies ModuleEventCatalog
|
|
12
|
+
|
|
13
|
+
export type CompanyCreatedData = Record<string, never>
|
|
14
|
+
export interface CompanyUpdatedData {
|
|
15
|
+
readonly changed: readonly string[]
|
|
16
|
+
}
|
|
17
|
+
export type CompanyDeletedData = Record<string, never>
|
|
18
|
+
|
|
19
|
+
declare module '../../runtime/events.ts' {
|
|
20
|
+
interface KelpieEventMap {
|
|
21
|
+
'companies.company.created': CompanyCreatedData
|
|
22
|
+
'companies.company.updated': CompanyUpdatedData
|
|
23
|
+
'companies.company.deleted': CompanyDeletedData
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
2
2
|
import { createActivityRecorder } from '../activities/index.ts'
|
|
3
|
+
import { companiesEvents } from './events.ts'
|
|
3
4
|
import { mountCompaniesRoutes } from './routes.ts'
|
|
4
5
|
import * as schema from './schema.ts'
|
|
5
6
|
import { createCompaniesService } from './service.ts'
|
|
@@ -16,6 +17,7 @@ export function createCompaniesModule(migrationsDirectory: string): KelpieModule
|
|
|
16
17
|
id: 'companies',
|
|
17
18
|
requires: ['workspace', 'activities'],
|
|
18
19
|
structural: true,
|
|
20
|
+
events: companiesEvents,
|
|
19
21
|
|
|
20
22
|
register(context) {
|
|
21
23
|
const service = createCompaniesService({
|
|
@@ -10,8 +10,10 @@ import type { TransactionScope } from '../../runtime/transaction.ts'
|
|
|
10
10
|
import type { ActivityRecorder } from '../activities/recorder.ts'
|
|
11
11
|
import { describeCreation, describeUpdate } from '../activities/wording.ts'
|
|
12
12
|
import type { FieldLabels } from '../activities/wording.ts'
|
|
13
|
+
import { toEventActor } from '../../lib/actor.ts'
|
|
13
14
|
import type { Actor } from '../auth/actor.ts'
|
|
14
15
|
import { requireWorkspaceId } from '../auth/actor.ts'
|
|
16
|
+
import './events.ts'
|
|
15
17
|
import { deleteRecordsAttachedTo } from '../attachedRecords.ts'
|
|
16
18
|
import { referencedElsewhere } from '../references.ts'
|
|
17
19
|
import * as repository from './repository.ts'
|
|
@@ -185,10 +187,10 @@ export function createCompaniesService(dependencies: CompaniesDependencies): Com
|
|
|
185
187
|
...describeCreation('Company'),
|
|
186
188
|
})
|
|
187
189
|
|
|
188
|
-
events.emit('
|
|
190
|
+
events.emit('companies.company.created', { type: 'company', id: created.id }, {})
|
|
189
191
|
|
|
190
192
|
return toView(created)
|
|
191
|
-
})
|
|
193
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
192
194
|
},
|
|
193
195
|
|
|
194
196
|
async update(actor, id, changes) {
|
|
@@ -228,15 +230,10 @@ export function createCompaniesService(dependencies: CompaniesDependencies): Com
|
|
|
228
230
|
...describeUpdate(changed, COMPANY_FIELD_LABELS, existing, columns),
|
|
229
231
|
})
|
|
230
232
|
|
|
231
|
-
events.emit('
|
|
232
|
-
workspaceId,
|
|
233
|
-
objectType: 'company',
|
|
234
|
-
recordId: id,
|
|
235
|
-
changedFields: changed,
|
|
236
|
-
})
|
|
233
|
+
events.emit('companies.company.updated', { type: 'company', id }, { changed })
|
|
237
234
|
|
|
238
235
|
return toView(updated)
|
|
239
|
-
})
|
|
236
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
240
237
|
},
|
|
241
238
|
|
|
242
239
|
async remove(actor, id) {
|
|
@@ -260,8 +257,8 @@ export function createCompaniesService(dependencies: CompaniesDependencies): Com
|
|
|
260
257
|
throw error
|
|
261
258
|
}
|
|
262
259
|
|
|
263
|
-
events.emit('
|
|
264
|
-
})
|
|
260
|
+
events.emit('companies.company.deleted', { type: 'company', id }, {})
|
|
261
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
265
262
|
},
|
|
266
263
|
}
|
|
267
264
|
}
|
package/src/modules/core.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { createPlansModule } from './plans/index.ts'
|
|
|
22
22
|
import { createPositionsModule } from './positions/index.ts'
|
|
23
23
|
import { createRaisesModule } from './raises/index.ts'
|
|
24
24
|
import { createSearchModule } from './search/index.ts'
|
|
25
|
+
import { createSmtpEmailModule } from './smtp-email/index.ts'
|
|
25
26
|
import { createWebhooksModule } from './webhooks/index.ts'
|
|
26
27
|
import { createWorkspaceModule } from './workspace/index.ts'
|
|
27
28
|
|
|
@@ -65,4 +66,7 @@ export const coreModules: readonly KelpieModule[] = [
|
|
|
65
66
|
createImportExportModule(coreMigrationsDirectory),
|
|
66
67
|
createAgentTasksModule(coreMigrationsDirectory),
|
|
67
68
|
createWebhooksModule(coreMigrationsDirectory),
|
|
69
|
+
// Owns no tables. Registers a `'smtp'` provider with core's email runtime;
|
|
70
|
+
// the factory only runs if the assembly's `email.provider` picks it.
|
|
71
|
+
createSmtpEmailModule(),
|
|
68
72
|
]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { ModuleEventCatalog } from '../../runtime/module.ts'
|
|
4
|
+
|
|
5
|
+
/** Domain events published by the deals module. */
|
|
6
|
+
|
|
7
|
+
export const dealsEvents = {
|
|
8
|
+
'deals.deal.created': z.object({}).strict(),
|
|
9
|
+
'deals.deal.updated': z.object({ changed: z.array(z.string()).readonly() }),
|
|
10
|
+
'deals.deal.deleted': z.object({}).strict(),
|
|
11
|
+
'deals.deal.stage_changed': z.object({
|
|
12
|
+
fromStageId: z.string().nullable(),
|
|
13
|
+
toStageId: z.string(),
|
|
14
|
+
}),
|
|
15
|
+
} satisfies ModuleEventCatalog
|
|
16
|
+
|
|
17
|
+
export type DealCreatedData = Record<string, never>
|
|
18
|
+
export interface DealUpdatedData {
|
|
19
|
+
readonly changed: readonly string[]
|
|
20
|
+
}
|
|
21
|
+
export type DealDeletedData = Record<string, never>
|
|
22
|
+
export interface DealStageChangedData {
|
|
23
|
+
readonly fromStageId: string | null
|
|
24
|
+
readonly toStageId: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare module '../../runtime/events.ts' {
|
|
28
|
+
interface KelpieEventMap {
|
|
29
|
+
'deals.deal.created': DealCreatedData
|
|
30
|
+
'deals.deal.updated': DealUpdatedData
|
|
31
|
+
'deals.deal.deleted': DealDeletedData
|
|
32
|
+
'deals.deal.stage_changed': DealStageChangedData
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
2
2
|
import { createActivityRecorder } from '../activities/index.ts'
|
|
3
|
+
import { dealsEvents } from './events.ts'
|
|
3
4
|
import { mountDealsRoutes } from './routes.ts'
|
|
4
5
|
import * as schema from './schema.ts'
|
|
5
6
|
import { createDealsService } from './service.ts'
|
|
@@ -17,6 +18,7 @@ export function createDealsModule(migrationsDirectory: string): KelpieModule {
|
|
|
17
18
|
return {
|
|
18
19
|
id: 'deals',
|
|
19
20
|
requires: ['companies', 'people', 'pipelines', 'activities'],
|
|
21
|
+
events: dealsEvents,
|
|
20
22
|
|
|
21
23
|
register(context) {
|
|
22
24
|
const service = createDealsService({
|
|
@@ -14,8 +14,10 @@ import {
|
|
|
14
14
|
describeUpdate,
|
|
15
15
|
} from '../activities/wording.ts'
|
|
16
16
|
import type { FieldLabels } from '../activities/wording.ts'
|
|
17
|
+
import { toEventActor } from '../../lib/actor.ts'
|
|
17
18
|
import type { Actor } from '../auth/actor.ts'
|
|
18
19
|
import { actorMemberId, requireWorkspaceId } from '../auth/actor.ts'
|
|
20
|
+
import './events.ts'
|
|
19
21
|
import { deleteRecordsAttachedTo } from '../attachedRecords.ts'
|
|
20
22
|
import * as companyRepository from '../companies/repository.ts'
|
|
21
23
|
import * as pipelineRepository from '../pipelines/repository.ts'
|
|
@@ -297,10 +299,10 @@ export function createDealsService(dependencies: DealsDependencies): DealsServic
|
|
|
297
299
|
})
|
|
298
300
|
}
|
|
299
301
|
|
|
300
|
-
events.emit('
|
|
302
|
+
events.emit('deals.deal.created', { type: 'deal', id }, {})
|
|
301
303
|
|
|
302
304
|
return toView(created, personIds)
|
|
303
|
-
})
|
|
305
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
304
306
|
},
|
|
305
307
|
|
|
306
308
|
async update(actor, id, changes) {
|
|
@@ -393,25 +395,22 @@ export function createDealsService(dependencies: DealsDependencies): DealsServic
|
|
|
393
395
|
})
|
|
394
396
|
}
|
|
395
397
|
|
|
396
|
-
events.emit(
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
})
|
|
398
|
+
events.emit(
|
|
399
|
+
'deals.deal.updated',
|
|
400
|
+
{ type: 'deal', id },
|
|
401
|
+
{ changed: linksChanged ? [...changed, 'personIds'] : changed },
|
|
402
|
+
)
|
|
402
403
|
|
|
403
404
|
if (stageMove !== undefined) {
|
|
404
|
-
events.emit(
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
toStageId: stageMove.to.id,
|
|
410
|
-
})
|
|
405
|
+
events.emit(
|
|
406
|
+
'deals.deal.stage_changed',
|
|
407
|
+
{ type: 'deal', id },
|
|
408
|
+
{ fromStageId: stageMove.from.id, toStageId: stageMove.to.id },
|
|
409
|
+
)
|
|
411
410
|
}
|
|
412
411
|
|
|
413
412
|
return toView(updated, nextPeople ?? currentPeople)
|
|
414
|
-
})
|
|
413
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
415
414
|
},
|
|
416
415
|
|
|
417
416
|
async remove(actor, id) {
|
|
@@ -426,8 +425,8 @@ export function createDealsService(dependencies: DealsDependencies): DealsServic
|
|
|
426
425
|
await deleteRecordsAttachedTo(tx, workspaceId, 'deal', id)
|
|
427
426
|
await repository.deleteDeal(tx, workspaceId, id)
|
|
428
427
|
|
|
429
|
-
events.emit('
|
|
430
|
-
})
|
|
428
|
+
events.emit('deals.deal.deleted', { type: 'deal', id }, {})
|
|
429
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
431
430
|
},
|
|
432
431
|
}
|
|
433
432
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { ModuleEventCatalog } from '../../runtime/module.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Domain events published by the decisions module.
|
|
7
|
+
*
|
|
8
|
+
* `target` is the record the decision attaches to; the decision's own id lives
|
|
9
|
+
* in `data`.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const decisionsEvents = {
|
|
13
|
+
'decisions.decision.added': z.object({ decisionId: z.string() }),
|
|
14
|
+
} satisfies ModuleEventCatalog
|
|
15
|
+
|
|
16
|
+
export interface DecisionAddedData {
|
|
17
|
+
readonly decisionId: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare module '../../runtime/events.ts' {
|
|
21
|
+
interface KelpieEventMap {
|
|
22
|
+
'decisions.decision.added': DecisionAddedData
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
2
|
+
import { decisionsEvents } from './events.ts'
|
|
2
3
|
import { mountDecisionsRoutes } from './routes.ts'
|
|
3
4
|
import * as schema from './schema.ts'
|
|
4
5
|
import { createDecisionsService } from './service.ts'
|
|
@@ -17,6 +18,7 @@ export function createDecisionsModule(migrationsDirectory: string): KelpieModule
|
|
|
17
18
|
id: 'decisions',
|
|
18
19
|
requires: ['workspace'],
|
|
19
20
|
structural: true,
|
|
21
|
+
events: decisionsEvents,
|
|
20
22
|
|
|
21
23
|
register(context) {
|
|
22
24
|
const service = createDecisionsService({
|
|
@@ -5,8 +5,10 @@ import type { IdFactory } from '../../lib/ids.ts'
|
|
|
5
5
|
import { mapPage, readListWindow, toPage } from '../../lib/pagination.ts'
|
|
6
6
|
import type { ListQueryParameters, Page } from '../../lib/pagination.ts'
|
|
7
7
|
import type { TransactionScope } from '../../runtime/transaction.ts'
|
|
8
|
+
import { toEventActor } from '../../lib/actor.ts'
|
|
8
9
|
import type { Actor } from '../auth/actor.ts'
|
|
9
10
|
import { actorMemberId, requireWorkspaceId } from '../auth/actor.ts'
|
|
11
|
+
import './events.ts'
|
|
10
12
|
import { targetExists } from '../recordTargets.ts'
|
|
11
13
|
import type { RecordTargetType } from '../recordTargets.ts'
|
|
12
14
|
import * as repository from './repository.ts'
|
|
@@ -158,15 +160,14 @@ export function createDecisionsService(dependencies: DecisionsDependencies): Dec
|
|
|
158
160
|
// decisions their own event, carrying the target, because a consumer
|
|
159
161
|
// watching a record wants the commitment without a second lookup to
|
|
160
162
|
// find out what it is attached to.
|
|
161
|
-
events.emit(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
})
|
|
163
|
+
events.emit(
|
|
164
|
+
'decisions.decision.added',
|
|
165
|
+
{ type: created.targetType, id: created.targetId },
|
|
166
|
+
{ decisionId: created.id },
|
|
167
|
+
)
|
|
167
168
|
|
|
168
169
|
return toView(created)
|
|
169
|
-
})
|
|
170
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
170
171
|
},
|
|
171
172
|
|
|
172
173
|
async update(actor, id, changes) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads every core module's `KelpieEventMap` augmentation at the package entry.
|
|
3
|
+
*
|
|
4
|
+
* Each module declares its event payload types in `<module>/events.ts` through
|
|
5
|
+
* `declare module '../../runtime/events.ts'`. Inside the monorepo those merge
|
|
6
|
+
* because the source graph reaches every file. A consumer that installs
|
|
7
|
+
* `@kelpie/server` from npm typechecks against `dist`, and declaration emit
|
|
8
|
+
* keeps only the imports a file actually references. Nothing in `dist/index.d.ts`
|
|
9
|
+
* referenced the per-module `events.d.ts` files, so `KelpieEventMap` stayed empty
|
|
10
|
+
* for consumers and every `subscribe` handler saw `event.data: unknown`.
|
|
11
|
+
*
|
|
12
|
+
* These side-effect imports give `index.ts` one reference into each catalog. The
|
|
13
|
+
* emitted `index.d.ts` carries them, so a consumer loads the augmentations and
|
|
14
|
+
* gets a typed `event.data` without a cast at the read site.
|
|
15
|
+
*
|
|
16
|
+
* List only modules whose `events.ts` augments `KelpieEventMap`. A module that
|
|
17
|
+
* publishes no events has no `events.ts` and does not belong here. Order mirrors
|
|
18
|
+
* `coreModules` in `core.ts` for readability; it has no runtime effect.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import './workspace/events.ts'
|
|
22
|
+
import './people/events.ts'
|
|
23
|
+
import './companies/events.ts'
|
|
24
|
+
import './positions/events.ts'
|
|
25
|
+
import './notes/events.ts'
|
|
26
|
+
import './deals/events.ts'
|
|
27
|
+
import './opportunities/events.ts'
|
|
28
|
+
import './partnerships/events.ts'
|
|
29
|
+
import './raises/events.ts'
|
|
30
|
+
import './hiring/events.ts'
|
|
31
|
+
import './plans/events.ts'
|
|
32
|
+
import './decisions/events.ts'
|
|
33
|
+
import './handbook/events.ts'
|
|
34
|
+
import './forms/events.ts'
|
|
35
|
+
import './import-export/events.ts'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { ModuleEventCatalog } from '../../runtime/module.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Domain events published by the forms module.
|
|
7
|
+
*
|
|
8
|
+
* `forms.form.*` cover the form definition CRUD. `forms.submission.submitted`
|
|
9
|
+
* fires once per submission; the webhooks bridge translates it to the wire
|
|
10
|
+
* `form.submitted` event (the ids live in `data`).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const formsEvents = {
|
|
14
|
+
'forms.form.created': z.object({}).strict(),
|
|
15
|
+
'forms.form.updated': z.object({ changed: z.array(z.string()).readonly() }),
|
|
16
|
+
'forms.form.deleted': z.object({}).strict(),
|
|
17
|
+
'forms.submission.submitted': z.object({ formId: z.string(), submissionId: z.string() }),
|
|
18
|
+
} satisfies ModuleEventCatalog
|
|
19
|
+
|
|
20
|
+
export type FormCreatedData = Record<string, never>
|
|
21
|
+
export interface FormUpdatedData {
|
|
22
|
+
readonly changed: readonly string[]
|
|
23
|
+
}
|
|
24
|
+
export type FormDeletedData = Record<string, never>
|
|
25
|
+
export interface FormSubmissionData {
|
|
26
|
+
readonly formId: string
|
|
27
|
+
readonly submissionId: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare module '../../runtime/events.ts' {
|
|
31
|
+
interface KelpieEventMap {
|
|
32
|
+
'forms.form.created': FormCreatedData
|
|
33
|
+
'forms.form.updated': FormUpdatedData
|
|
34
|
+
'forms.form.deleted': FormDeletedData
|
|
35
|
+
'forms.submission.submitted': FormSubmissionData
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KelpieModule } from '../../runtime/module.ts'
|
|
2
2
|
import { createActivityRecorder } from '../activities/index.ts'
|
|
3
|
+
import { formsEvents } from './events.ts'
|
|
3
4
|
import { mountPublicFormRoutes } from './publicRoutes.ts'
|
|
4
5
|
import { mountFormsRoutes } from './routes.ts'
|
|
5
6
|
import * as schema from './schema.ts'
|
|
@@ -23,6 +24,7 @@ export function createFormsModule(migrationsDirectory: string): KelpieModule {
|
|
|
23
24
|
return {
|
|
24
25
|
id: 'forms',
|
|
25
26
|
requires: ['people', 'companies', 'positions', 'pipelines', 'deals', 'activities'],
|
|
27
|
+
events: formsEvents,
|
|
26
28
|
|
|
27
29
|
register(context) {
|
|
28
30
|
const service = createFormsService({
|
|
@@ -6,8 +6,10 @@ import { mapPage, readListWindow, toPage } from '../../lib/pagination.ts'
|
|
|
6
6
|
import type { ListQueryParameters, Page } from '../../lib/pagination.ts'
|
|
7
7
|
import { generateToken } from '../../lib/tokens.ts'
|
|
8
8
|
import type { Transaction, TransactionScope } from '../../runtime/transaction.ts'
|
|
9
|
+
import { toEventActor } from '../../lib/actor.ts'
|
|
9
10
|
import type { Actor } from '../auth/actor.ts'
|
|
10
11
|
import { requireWorkspaceId } from '../auth/actor.ts'
|
|
12
|
+
import './events.ts'
|
|
11
13
|
import * as pipelineRepository from '../pipelines/repository.ts'
|
|
12
14
|
import { fieldsDiffer, findFieldProblems, storedOptions } from './fields.ts'
|
|
13
15
|
import type { FieldDraft, FieldShape } from './fields.ts'
|
|
@@ -253,10 +255,10 @@ export function createFormsService(dependencies: FormsDependencies): FormsServic
|
|
|
253
255
|
})
|
|
254
256
|
const fields = await writeFields(tx, workspaceId, id, input.fields)
|
|
255
257
|
|
|
256
|
-
events.emit('
|
|
258
|
+
events.emit('forms.form.created', { type: 'form', id }, {})
|
|
257
259
|
|
|
258
260
|
return toView(created, fields)
|
|
259
|
-
})
|
|
261
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
260
262
|
},
|
|
261
263
|
|
|
262
264
|
async update(actor, id, changes) {
|
|
@@ -310,15 +312,14 @@ export function createFormsService(dependencies: FormsDependencies): FormsServic
|
|
|
310
312
|
return writeFields(tx, workspaceId, id, changes.fields)
|
|
311
313
|
})()
|
|
312
314
|
|
|
313
|
-
events.emit(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
})
|
|
315
|
+
events.emit(
|
|
316
|
+
'forms.form.updated',
|
|
317
|
+
{ type: 'form', id },
|
|
318
|
+
{ changed: rewritesFields ? [...written, 'fields'] : written },
|
|
319
|
+
)
|
|
319
320
|
|
|
320
321
|
return toView(updated, fields)
|
|
321
|
-
})
|
|
322
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
322
323
|
},
|
|
323
324
|
|
|
324
325
|
/**
|
|
@@ -339,8 +340,8 @@ export function createFormsService(dependencies: FormsDependencies): FormsServic
|
|
|
339
340
|
throw AppError.notFound('Form not found')
|
|
340
341
|
}
|
|
341
342
|
|
|
342
|
-
events.emit('
|
|
343
|
-
})
|
|
343
|
+
events.emit('forms.form.deleted', { type: 'form', id }, {})
|
|
344
|
+
}, { workspaceId, actor: toEventActor(actor) })
|
|
344
345
|
},
|
|
345
346
|
|
|
346
347
|
async listSubmissions(actor, formId, query) {
|