spine-framework 0.3.125 → 0.3.127
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/.framework/cli/commands/agents.ts +35 -37
- package/.framework/cli/commands/auth.ts +35 -34
- package/.framework/cli/commands/create-app.ts +104 -40
- package/.framework/cli/commands/dev.ts +104 -69
- package/.framework/cli/commands/doctor.ts +169 -97
- package/.framework/cli/commands/generate.ts +82 -161
- package/.framework/cli/commands/init.ts +72 -34
- package/.framework/cli/commands/install-app.ts +260 -125
- package/.framework/cli/commands/items.ts +33 -44
- package/.framework/cli/commands/migrate.ts +122 -40
- package/.framework/cli/commands/migrations.ts +33 -40
- package/.framework/cli/commands/pipelines.ts +31 -39
- package/.framework/cli/commands/status.ts +47 -23
- package/.framework/cli/commands/system.ts +47 -37
- package/.framework/cli/commands/test.ts +112 -68
- package/.framework/cli/commands/validate-app.ts +215 -121
- package/.framework/cli/context.ts +112 -130
- package/.framework/cli/env-loader.ts +47 -18
- package/.framework/cli/index.ts +81 -42
- package/.framework/docs/runtime-types.md +1024 -0
- package/.framework/functions/_shared/agent-runner.ts +1296 -961
- package/.framework/functions/_shared/app-manifest.ts +82 -68
- package/.framework/functions/_shared/audit.ts +135 -83
- package/.framework/functions/_shared/{cil-state.ts → cil.ts} +147 -54
- package/.framework/functions/_shared/db.ts +80 -126
- package/.framework/functions/_shared/hash-api-key.ts +63 -0
- package/.framework/functions/_shared/index.ts +222 -347
- package/.framework/functions/_shared/kb.ts +319 -0
- package/.framework/functions/_shared/llm.ts +92 -0
- package/.framework/functions/_shared/logging.ts +288 -0
- package/.framework/functions/_shared/middleware.ts +329 -365
- package/.framework/functions/_shared/outcomes.ts +36 -0
- package/.framework/functions/_shared/permissions.ts +359 -643
- package/.framework/functions/_shared/pipeline-runner.ts +243 -316
- package/.framework/functions/_shared/principal.ts +376 -468
- package/.framework/functions/_shared/resolve-credentials.ts +102 -0
- package/.framework/functions/_shared/resolve-ids.ts +162 -14
- package/.framework/functions/_shared/retry-deliveries.ts +104 -0
- package/.framework/functions/_shared/schema-utils.ts +611 -373
- package/.framework/functions/_shared/testing.ts +207 -137
- package/.framework/functions/_shared/tracing.ts +276 -0
- package/.framework/functions/_shared/trigger-engine.ts +159 -211
- package/.framework/functions/_shared/webhook-registration.ts +95 -81
- package/.framework/functions/_shared/webhook-registry.ts +153 -75
- package/.framework/functions/account-nodes.ts +31 -53
- package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
- package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
- package/.framework/functions/adapters/openai-outbound.ts +40 -0
- package/.framework/functions/admin-data.ts +687 -533
- package/.framework/functions/admin-funnel.ts +31 -20
- package/.framework/functions/admin-install-funnel.ts +47 -28
- package/.framework/functions/admin-signals.ts +47 -29
- package/.framework/functions/ai-agents.ts +122 -147
- package/.framework/functions/ai-interactions.ts +180 -90
- package/.framework/functions/api-keys.ts +250 -192
- package/.framework/functions/apps.ts +203 -197
- package/.framework/functions/auth.ts +98 -91
- package/.framework/functions/cil-agent-ingest.ts +773 -0
- package/.framework/functions/cil-agent.ts +592 -0
- package/.framework/functions/cil-callmap.ts +1227 -0
- package/.framework/functions/cil-config.ts +583 -0
- package/.framework/functions/cil-context.ts +445 -0
- package/.framework/functions/cil-doc.ts +1752 -0
- package/.framework/functions/cil-embeddings.ts +1202 -0
- package/.framework/functions/cil-graph.ts +585 -0
- package/.framework/functions/cil-ingest.ts +2416 -0
- package/.framework/functions/cil-pipeline.ts +318 -0
- package/.framework/functions/cil-project.ts +499 -0
- package/.framework/functions/cil-validate.ts +469 -0
- package/.framework/functions/debug-auth.ts +73 -53
- package/.framework/functions/deliveries.ts +117 -0
- package/.framework/functions/embeddings.ts +528 -516
- package/.framework/functions/eval-harness.ts +158 -106
- package/.framework/functions/integration-outbound.ts +311 -0
- package/.framework/functions/integration-routes.ts +240 -466
- package/.framework/functions/integrations.ts +132 -140
- package/.framework/functions/invites.ts +401 -201
- package/.framework/functions/item-progress.ts +113 -53
- package/.framework/functions/kb.ts +28 -0
- package/.framework/functions/logs.ts +239 -222
- package/.framework/functions/observability.ts +308 -259
- package/.framework/functions/pipeline-executions.ts +179 -235
- package/.framework/functions/pipelines.ts +163 -205
- package/.framework/functions/prompt-configs.ts +109 -156
- package/.framework/functions/roles.ts +97 -147
- package/.framework/functions/system-cron.ts +132 -218
- package/.framework/functions/system.ts +112 -52
- package/.framework/functions/tests.ts +32 -28
- package/.framework/functions/timers.ts +162 -210
- package/.framework/functions/triggers.ts +282 -346
- package/.framework/functions/types.ts +283 -400
- package/.framework/migrations/001_core_schema.sql +630 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
- package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
- package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
- package/.framework/migrations/005_core_observability.sql +598 -0
- package/.framework/migrations/006_security_hardening_rls.sql +97 -0
- package/.framework/migrations/007_kb_article_list.sql +237 -0
- package/.framework/migrations/008_items_target.sql +8 -0
- package/.framework/migrations/009_roles_slug_unique.sql +11 -0
- package/.framework/public/spine.config.json +91 -0
- package/.framework/scripts/app-install-cli.ts +112 -98
- package/.framework/src/App.tsx +67 -20
- package/.framework/src/apps/admin/index.tsx +97 -27
- package/.framework/src/components/AppWrapper.tsx +50 -11
- package/.framework/src/components/CustomAppLoader.tsx +131 -22
- package/.framework/src/components/admin/AdminListPage.tsx +75 -8
- package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
- package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
- package/.framework/src/components/admin/PageInstructions.tsx +49 -0
- package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
- package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
- package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
- package/.framework/src/components/app-sidebar.tsx +50 -3
- package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
- package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
- package/.framework/src/components/kb/KBArticleList.tsx +557 -0
- package/.framework/src/components/layout/AppShell.tsx +54 -16
- package/.framework/src/components/layout/Header.tsx +50 -38
- package/.framework/src/components/layout/Layout.tsx +48 -32
- package/.framework/src/components/layout/Sidebar.tsx +167 -16
- package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
- package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
- package/.framework/src/components/runtime/DataFilters.tsx +78 -1
- package/.framework/src/components/runtime/DataHeader.tsx +32 -29
- package/.framework/src/components/runtime/DataListPage.tsx +161 -2
- package/.framework/src/components/runtime/DataStats.tsx +48 -1
- package/.framework/src/components/runtime/DataTable.tsx +153 -1
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
- package/.framework/src/components/runtime/index.ts +16 -9
- package/.framework/src/components/search-form.tsx +33 -1
- package/.framework/src/components/shared/AgentView.tsx +48 -51
- package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
- package/.framework/src/components/shared/InviteManager.tsx +113 -52
- package/.framework/src/components/shared/MemberList.tsx +182 -0
- package/.framework/src/components/shared/SchemaFields.tsx +96 -78
- package/.framework/src/components/ui/DataTable.tsx +86 -56
- package/.framework/src/components/ui/Form.tsx +188 -109
- package/.framework/src/components/ui/ItemCard.tsx +86 -58
- package/.framework/src/components/ui/ItemListView.tsx +88 -61
- package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
- package/.framework/src/components/ui/Modal.tsx +81 -4
- package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
- package/.framework/src/components/ui/accordion.tsx +97 -5
- package/.framework/src/components/ui/alert-dialog.tsx +225 -13
- package/.framework/src/components/ui/alert.tsx +113 -6
- package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
- package/.framework/src/components/ui/avatar.tsx +129 -7
- package/.framework/src/components/ui/badge.tsx +65 -3
- package/.framework/src/components/ui/breadcrumb.tsx +145 -8
- package/.framework/src/components/ui/button-group.tsx +81 -4
- package/.framework/src/components/ui/button.tsx +49 -2
- package/.framework/src/components/ui/calendar.tsx +65 -3
- package/.framework/src/components/ui/card.tsx +145 -8
- package/.framework/src/components/ui/carousel.tsx +129 -7
- package/.framework/src/components/ui/chart.tsx +161 -10
- package/.framework/src/components/ui/checkbox.tsx +49 -2
- package/.framework/src/components/ui/collapsible.tsx +81 -5
- package/.framework/src/components/ui/combobox.tsx +305 -20
- package/.framework/src/components/ui/command.tsx +177 -11
- package/.framework/src/components/ui/context-menu.tsx +273 -17
- package/.framework/src/components/ui/dialog.tsx +209 -27
- package/.framework/src/components/ui/direction.tsx +64 -4
- package/.framework/src/components/ui/drawer.tsx +193 -12
- package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
- package/.framework/src/components/ui/empty.tsx +145 -9
- package/.framework/src/components/ui/field.tsx +209 -14
- package/.framework/src/components/ui/hover-card.tsx +81 -4
- package/.framework/src/components/ui/input-group.tsx +162 -10
- package/.framework/src/components/ui/input-otp.tsx +98 -5
- package/.framework/src/components/ui/input.tsx +49 -2
- package/.framework/src/components/ui/item.tsx +225 -13
- package/.framework/src/components/ui/kbd.tsx +65 -3
- package/.framework/src/components/ui/label.tsx +49 -2
- package/.framework/src/components/ui/menubar.tsx +289 -17
- package/.framework/src/components/ui/native-select.tsx +97 -5
- package/.framework/src/components/ui/navigation-menu.tsx +177 -10
- package/.framework/src/components/ui/pagination.tsx +161 -9
- package/.framework/src/components/ui/popover.tsx +145 -8
- package/.framework/src/components/ui/progress.tsx +49 -2
- package/.framework/src/components/ui/radio-group.tsx +65 -3
- package/.framework/src/components/ui/resizable.tsx +82 -4
- package/.framework/src/components/ui/scroll-area.tsx +65 -3
- package/.framework/src/components/ui/select.tsx +193 -11
- package/.framework/src/components/ui/separator.tsx +49 -2
- package/.framework/src/components/ui/sheet.tsx +193 -11
- package/.framework/src/components/ui/sidebar.tsx +481 -38
- package/.framework/src/components/ui/skeleton.tsx +49 -2
- package/.framework/src/components/ui/slider.tsx +49 -2
- package/.framework/src/components/ui/sonner.tsx +49 -2
- package/.framework/src/components/ui/spinner.tsx +49 -2
- package/.framework/src/components/ui/switch.tsx +49 -2
- package/.framework/src/components/ui/table-primitives.tsx +160 -33
- package/.framework/src/components/ui/table.tsx +161 -9
- package/.framework/src/components/ui/tabs.tsx +113 -6
- package/.framework/src/components/ui/textarea.tsx +49 -2
- package/.framework/src/components/ui/toggle-group.tsx +81 -4
- package/.framework/src/components/ui/toggle.tsx +65 -3
- package/.framework/src/components/ui/tooltip.tsx +97 -5
- package/.framework/src/contexts/AppContext.tsx +129 -45
- package/.framework/src/contexts/AuthContext.tsx +173 -145
- package/.framework/src/hooks/use-mobile.ts +48 -2
- package/.framework/src/hooks/useApi.ts +208 -159
- package/.framework/src/hooks/useAppPath.ts +32 -23
- package/.framework/src/hooks/useApps.ts +51 -20
- package/.framework/src/hooks/useEntityList.ts +32 -78
- package/.framework/src/hooks/useEntityRecord.ts +35 -96
- package/.framework/src/hooks/useForm.ts +32 -92
- package/.framework/src/hooks/useListSchema.ts +49 -78
- package/.framework/src/hooks/useSchemaRecord.ts +114 -105
- package/.framework/src/lib/api.ts +192 -115
- package/.framework/src/lib/supabase.ts +98 -64
- package/.framework/src/lib/utils.ts +287 -151
- package/.framework/src/main.tsx +49 -3
- package/.framework/src/pages/DashboardPage.tsx +52 -29
- package/.framework/src/pages/NotFoundPage.tsx +32 -10
- package/.framework/src/pages/SetupPage.tsx +32 -12
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
- package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
- package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
- package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
- package/.framework/src/pages/admin/AppsPage.tsx +49 -2
- package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
- package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
- package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
- package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
- package/.framework/src/pages/admin/LogsPage.tsx +422 -75
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
- package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
- package/.framework/src/pages/admin/RolesPage.tsx +171 -18
- package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
- package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
- package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
- package/.framework/src/pages/admin/TimersPage.tsx +48 -20
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
- package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
- package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
- package/.framework/src/pages/admin/TypesPage.tsx +48 -20
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
- package/.framework/src/pages/auth/LoginPage.tsx +50 -23
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
- package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
- package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
- package/.framework/src/types/auth.ts +128 -71
- package/.framework/src/types/types.ts +373 -157
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
- package/docs/README.md +9 -130
- package/netlify.toml +3 -3
- package/package.json +13 -25
- package/scripts/kb-ingest-docs.ts +203 -0
- package/spine.config.json +65 -4
- package/.framework/migrations/001_schema.sql +0 -425
- package/.framework/migrations/002_rls_and_functions.sql +0 -763
- package/.framework/migrations/004_enhancements.sql +0 -43
- package/.framework/migrations/005_auth_user_trigger.sql +0 -105
- package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
- package/.framework/migrations/016_invites.sql +0 -27
- package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
- package/.framework/migrations/018_apps_required_roles.sql +0 -17
- package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
- package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
- package/.framework/migrations/021_app_domains.sql +0 -112
- package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
- package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
- package/.framework/migrations/024_messages_account_id.sql +0 -9
- package/.framework/migrations/025_retype_threads_messages.sql +0 -240
- package/.framework/migrations/026_fix_rls_policies.sql +0 -47
- package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
- package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
- package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
- package/.framework/migrations/030_messages_updated_by.sql +0 -6
- package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
- package/docs/APPS.md +0 -232
- package/docs/ARCHITECTURE.md +0 -246
- package/docs/INSTALL.md +0 -155
- package/docs/design-schema-spec.md +0 -1837
- package/docs/dev-guides/01-create-an-app.md +0 -183
- package/docs/dev-guides/02-create-a-function.md +0 -178
- package/docs/dev-guides/03-create-a-component.md +0 -178
- package/docs/dev-guides/04-webhook-handlers.md +0 -129
- package/docs/dev-guides/05-testing.md +0 -168
- package/docs/dev-guides/README.md +0 -40
- package/docs/npm-packages-plan.md +0 -288
- package/docs/spine-core--api-reference.md +0 -822
|
@@ -0,0 +1,1752 @@
|
|
|
1
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_module_header_1784235266" type="module_header" identity="module_header" parent="none"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Module header and top-level exports for cortex.functions.custom_cil-doc"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Own module-level imports, exports, and configuration for cortex.functions.custom_cil-doc"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="module exports and side effects" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Declares module scope, imports dependencies, and exports public surface of cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
10
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, \."]
|
|
11
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
12
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
13
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
14
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
15
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
import { createHandler } from './_shared/middleware'
|
|
22
|
+
import { adminDb } from './_shared/db'
|
|
23
|
+
import { update as adminUpdate } from './admin-data'
|
|
24
|
+
import { callOpenAIChat } from './_shared/llm'
|
|
25
|
+
import { FileStatus, FileTreeNode, isSelectedPath, getFileStatus, updateTreeNodeStatus, saveProjectTree } from './_shared/cil'
|
|
26
|
+
import * as fs from 'fs'
|
|
27
|
+
import * as path from 'path'
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_module_header_1784235266"]
|
|
38
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_default_model_1784235266" type="variable" identity="default_model" parent="none"]
|
|
39
|
+
// CIL[DOC-MACRO purpose="Defines default_model configuration or state in cortex.functions.custom_cil-doc"]
|
|
40
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for default_model"]
|
|
41
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
|
|
42
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of default_model" errors="none" side_effects="none"]
|
|
43
|
+
// CIL[DOC-MICRO logic_summary="Declares default_model with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
44
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
45
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
46
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
|
|
47
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
48
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
49
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
50
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
51
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
52
|
+
const DEFAULT_MODEL = 'gpt-4o-mini'
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_default_model_1784235266"]
|
|
63
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_model_prices_1784235266" type="variable" identity="model_prices" parent="none"]
|
|
64
|
+
// CIL[DOC-MACRO purpose="Defines model_prices configuration or state in cortex.functions.custom_cil-doc"]
|
|
65
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for model_prices"]
|
|
66
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
|
|
67
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of model_prices" errors="none" side_effects="none"]
|
|
68
|
+
// CIL[DOC-MICRO logic_summary="Declares model_prices with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
69
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
70
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
71
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
|
|
72
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
73
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
74
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
75
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
76
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
77
|
+
const MODEL_PRICES: Record<string, { input_per_1m: number; output_per_1m: number }> = {
|
|
78
|
+
'gpt-4o-mini': { input_per_1m: 0.15, output_per_1m: 0.60 },
|
|
79
|
+
'gpt-4o': { input_per_1m: 2.50, output_per_1m: 10.00 },
|
|
80
|
+
'gpt-4-turbo': { input_per_1m: 10.00, output_per_1m: 30.00 },
|
|
81
|
+
'gpt-3.5-turbo': { input_per_1m: 0.50, output_per_1m: 1.50 },
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_model_prices_1784235266"]
|
|
92
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_estimated_output_tokens_per_chunk_1784235266" type="variable" identity="estimated_output_tokens_per_chunk" parent="none"]
|
|
93
|
+
// CIL[DOC-MACRO purpose="Defines estimated_output_tokens_per_chunk configuration or state in cortex.functions.custom_cil-doc"]
|
|
94
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for estimated_output_tokens_per_chunk"]
|
|
95
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
|
|
96
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of estimated_output_tokens_per_chunk" errors="none" side_effects="none"]
|
|
97
|
+
// CIL[DOC-MICRO logic_summary="Declares estimated_output_tokens_per_chunk with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
98
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
99
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
100
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
|
|
101
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
102
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
103
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
104
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
105
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
106
|
+
const ESTIMATED_OUTPUT_TOKENS_PER_CHUNK = 200
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_estimated_output_tokens_per_chunk_1784235266"]
|
|
115
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_system_prompt_overhead_tokens_1784235266" type="variable" identity="system_prompt_overhead_tokens" parent="none"]
|
|
116
|
+
// CIL[DOC-MACRO purpose="Defines system_prompt_overhead_tokens configuration or state in cortex.functions.custom_cil-doc"]
|
|
117
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for system_prompt_overhead_tokens"]
|
|
118
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"\\\"]"]
|
|
119
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of system_prompt_overhead_tokens" errors="none" side_effects="none"]
|
|
120
|
+
// CIL[DOC-MICRO logic_summary="Declares system_prompt_overhead_tokens with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
121
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
122
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
123
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/IntegrationsPage.tsx, \."]
|
|
124
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
125
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
126
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
127
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
128
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
129
|
+
const SYSTEM_PROMPT_OVERHEAD_TOKENS = 350
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_system_prompt_overhead_tokens_1784235266"]
|
|
140
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_estimatetokens_1784235266" type="function" identity="estimatetokens" parent="none"]
|
|
141
|
+
// CIL[DOC-MACRO purpose="Implements estimatetokens logic in cortex.functions.custom_cil-doc"]
|
|
142
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute estimatetokens and return its computed result"]
|
|
143
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
144
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
145
|
+
// CIL[DOC-MICRO logic_summary="Provides estimatetokens with estimateTokens(text: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
146
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
147
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
148
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
149
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
150
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
151
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
152
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
153
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
154
|
+
function estimateTokens(text: string): number {
|
|
155
|
+
return Math.ceil(text.length / 4)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_estimatetokens_1784235266"]
|
|
165
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_needsdocumentation_1784235266" type="function" identity="needsdocumentation" parent="none"]
|
|
166
|
+
// CIL[DOC-MACRO purpose="Implements needsdocumentation logic in cortex.functions.custom_cil-doc"]
|
|
167
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute needsdocumentation and return its computed result"]
|
|
168
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
169
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
170
|
+
// CIL[DOC-MICRO logic_summary="Provides needsdocumentation with needsDocumentation(chunk: any inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
171
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
172
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
173
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
174
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
175
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
176
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
177
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
178
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
179
|
+
function needsDocumentation(chunk: any): boolean {
|
|
180
|
+
const d = chunk.data || {}
|
|
181
|
+
|
|
182
|
+
if (d.doc_validation_errors && d.doc_validation_errors.length > 0) return true
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
const required = d.chunk_type === 'module_header'
|
|
187
|
+
? REQUIRED_MODULE_FIELDS
|
|
188
|
+
: REQUIRED_CHUNK_FIELDS
|
|
189
|
+
return required.some(f => !d[f] || String(d[f]).trim() === '')
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_needsdocumentation_1784235266"]
|
|
200
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_loadallchunks_1784235266" type="function" identity="loadallchunks" parent="none"]
|
|
201
|
+
// CIL[DOC-MACRO purpose="Implements loadallchunks logic in cortex.functions.custom_cil-doc"]
|
|
202
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute loadallchunks and return its computed result"]
|
|
203
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
204
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
205
|
+
// CIL[DOC-MICRO logic_summary="Provides loadallchunks with loadAllChunks(projectId: string, filePath?: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
206
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
207
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
208
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
209
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
210
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
211
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
212
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
213
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
214
|
+
async function loadAllChunks(projectId: string, filePath?: string): Promise<any[]> {
|
|
215
|
+
const PAGE = 1000
|
|
216
|
+
const all: any[] = []
|
|
217
|
+
for (let offset = 0; ; offset += PAGE) {
|
|
218
|
+
let q = adminDb
|
|
219
|
+
.from('items')
|
|
220
|
+
.select('id, title, data')
|
|
221
|
+
.filter('data->>kb_type', 'eq', 'cil_chunk')
|
|
222
|
+
.filter('data->>project_id', 'eq', projectId)
|
|
223
|
+
.eq('is_active', true)
|
|
224
|
+
.order('id')
|
|
225
|
+
.range(offset, offset + PAGE - 1)
|
|
226
|
+
if (filePath) q = q.filter('data->>file_path', 'eq', filePath)
|
|
227
|
+
const { data, error } = await q
|
|
228
|
+
if (error) throw new Error(`Failed to load chunks: ${error.message}`)
|
|
229
|
+
if (!data || data.length === 0) break
|
|
230
|
+
all.push(...data)
|
|
231
|
+
if (data.length < PAGE) break
|
|
232
|
+
}
|
|
233
|
+
return all
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_loadallchunks_1784235266"]
|
|
240
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_loadpendingchunks_1784235266" type="function" identity="loadpendingchunks" parent="none"]
|
|
241
|
+
// CIL[DOC-MACRO purpose="Implements loadpendingchunks logic in cortex.functions.custom_cil-doc"]
|
|
242
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute loadpendingchunks and return its computed result"]
|
|
243
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
244
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
245
|
+
// CIL[DOC-MICRO logic_summary="Provides loadpendingchunks with loadPendingChunks(projectId: string, selectedPaths: string[], requiredStatus: FileStatus inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
246
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
247
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
248
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
249
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
250
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
251
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
252
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
253
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
254
|
+
async function loadPendingChunks(projectId: string, selectedPaths: string[], requiredStatus: FileStatus): Promise<any[]> {
|
|
255
|
+
const { data: fileItems } = await adminDb
|
|
256
|
+
.from('items')
|
|
257
|
+
.select('id, data')
|
|
258
|
+
.filter('data->>kb_type', 'eq', 'cil_file')
|
|
259
|
+
.filter('data->>project_id', 'eq', projectId)
|
|
260
|
+
.eq('is_active', true)
|
|
261
|
+
|
|
262
|
+
const selectedFileIds = (fileItems || [])
|
|
263
|
+
.filter((f: any) => getFileStatus(f) === requiredStatus && isSelectedPath(f.data?.file_path || f.title, selectedPaths))
|
|
264
|
+
.map((f: any) => f.id)
|
|
265
|
+
|
|
266
|
+
if (selectedFileIds.length === 0) return []
|
|
267
|
+
|
|
268
|
+
const { data: allChunks } = await adminDb
|
|
269
|
+
.from('items')
|
|
270
|
+
.select('id, title, data')
|
|
271
|
+
.filter('data->>kb_type', 'eq', 'cil_chunk')
|
|
272
|
+
.filter('data->>project_id', 'eq', projectId)
|
|
273
|
+
.eq('is_active', true)
|
|
274
|
+
|
|
275
|
+
return (allChunks || []).filter((c: any) => selectedFileIds.includes(c.data?.file_id))
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_loadpendingchunks_1784235266"]
|
|
282
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_maybeadvancefiletopass3_1784235266" type="function" identity="maybeadvancefiletopass3" parent="none"]
|
|
283
|
+
// CIL[DOC-MACRO purpose="Implements maybeadvancefiletopass3 logic in cortex.functions.custom_cil-doc"]
|
|
284
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute maybeadvancefiletopass3 and return its computed result"]
|
|
285
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
286
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
287
|
+
// CIL[DOC-MICRO logic_summary="Provides maybeadvancefiletopass3 with maybeAdvanceFileToPass3(ctx: any, fileId: string, tree: FileTreeNode | null inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
288
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
289
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
290
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
291
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
292
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
293
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
294
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
295
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
296
|
+
async function maybeAdvanceFileToPass3(ctx: any, fileId: string, tree: FileTreeNode | null): Promise<void> {
|
|
297
|
+
const { data: fileChunks } = await adminDb
|
|
298
|
+
.from('items')
|
|
299
|
+
.select('id, title, data')
|
|
300
|
+
.filter('data->>kb_type', 'eq', 'cil_chunk')
|
|
301
|
+
.filter('data->>file_id', 'eq', fileId)
|
|
302
|
+
.eq('is_active', true)
|
|
303
|
+
|
|
304
|
+
const allDocumented = (fileChunks || []).every(c => !needsDocumentation(c))
|
|
305
|
+
if (!allDocumented) return
|
|
306
|
+
|
|
307
|
+
const { data: fileItem } = await adminDb
|
|
308
|
+
.from('items')
|
|
309
|
+
.select('id, data')
|
|
310
|
+
.eq('id', fileId)
|
|
311
|
+
.maybeSingle()
|
|
312
|
+
|
|
313
|
+
if (!fileItem) return
|
|
314
|
+
|
|
315
|
+
const updateCtx = { ...ctx, query: { ...(ctx.query || {}), entity: 'items', id: fileId } }
|
|
316
|
+
await adminUpdate(updateCtx, {
|
|
317
|
+
data: {
|
|
318
|
+
...fileItem.data,
|
|
319
|
+
status: 'pass3_complete',
|
|
320
|
+
last_status_at: new Date().toISOString(),
|
|
321
|
+
},
|
|
322
|
+
}).catch((e: any) => console.error('advance to pass3 failed:', e.message))
|
|
323
|
+
|
|
324
|
+
if (tree) updateTreeNodeStatus(tree, fileId, 'pass3_complete')
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_maybeadvancefiletopass3_1784235266"]
|
|
381
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_required_module_fields_1784235266" type="variable" identity="required_module_fields" parent="none"]
|
|
382
|
+
// CIL[DOC-MACRO purpose="Defines required_module_fields configuration or state in cortex.functions.custom_cil-doc"]
|
|
383
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for required_module_fields"]
|
|
384
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
385
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of required_module_fields" errors="none" side_effects="none"]
|
|
386
|
+
// CIL[DOC-MICRO logic_summary="Declares required_module_fields with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
387
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
388
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
389
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
390
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
391
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
392
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
393
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
394
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
395
|
+
const REQUIRED_MODULE_FIELDS = ['module', 'audience', 'layer', 'stability', 'description']
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_required_module_fields_1784235266"]
|
|
399
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_required_chunk_fields_1784235266" type="variable" identity="required_chunk_fields" parent="none"]
|
|
400
|
+
// CIL[DOC-MACRO purpose="Defines required_chunk_fields configuration or state in cortex.functions.custom_cil-doc"]
|
|
401
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for required_chunk_fields"]
|
|
402
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
403
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of required_chunk_fields" errors="none" side_effects="none"]
|
|
404
|
+
// CIL[DOC-MICRO logic_summary="Declares required_chunk_fields with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
405
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
406
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
407
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
408
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
409
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
410
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
411
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
412
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
413
|
+
const REQUIRED_CHUNK_FIELDS = ['description', 'input_spec', 'output_spec', 'side_effects', 'stability']
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_required_chunk_fields_1784235266"]
|
|
419
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_modulenamefrompath_1784235266" type="function" identity="modulenamefrompath" parent="none"]
|
|
420
|
+
// CIL[DOC-MACRO purpose="Implements modulenamefrompath logic in cortex.functions.custom_cil-doc"]
|
|
421
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute modulenamefrompath and return its computed result"]
|
|
422
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
423
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
424
|
+
// CIL[DOC-MICRO logic_summary="Provides modulenamefrompath with moduleNameFromPath(relPath: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
425
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
426
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
427
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
428
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
429
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
430
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
431
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
432
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
433
|
+
function moduleNameFromPath(relPath: string): string {
|
|
434
|
+
return path.basename(relPath, path.extname(relPath))
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_modulenamefrompath_1784235266"]
|
|
443
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_buildjsdoc_1784235266" type="function" identity="buildjsdoc" parent="none"]
|
|
444
|
+
// CIL[DOC-MACRO purpose="Implements buildjsdoc logic in cortex.functions.custom_cil-doc"]
|
|
445
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute buildjsdoc and return its computed result"]
|
|
446
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
447
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
448
|
+
// CIL[DOC-MICRO logic_summary="Provides buildjsdoc with buildJsDoc(chunk: any inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
449
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
450
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
451
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
452
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
453
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
454
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
455
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
456
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
457
|
+
function buildJsDoc(chunk: any): string {
|
|
458
|
+
const d = chunk.data || {}
|
|
459
|
+
const isModuleHeader = d.chunk_type === 'module_header'
|
|
460
|
+
const description = (d.description || d.macro || '').trim()
|
|
461
|
+
if (!description) return ''
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
if (isModuleHeader) {
|
|
465
|
+
const body: string[] = []
|
|
466
|
+
if (d.module) body.push(`@module ${d.module}`)
|
|
467
|
+
if (d.audience) body.push(`@audience ${d.audience}`)
|
|
468
|
+
if (d.layer) body.push(`@layer ${d.layer}`)
|
|
469
|
+
if (d.stability)body.push(`@stability ${d.stability}`)
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
const descLines = description.split('\n')
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
const seeAlsoRefs = d.see_also
|
|
477
|
+
? d.see_also.split(/\n/).map((s: string) => s.trim()).filter(Boolean)
|
|
478
|
+
: []
|
|
479
|
+
|
|
480
|
+
const docLines = [
|
|
481
|
+
'/**',
|
|
482
|
+
...body.map(l => ` * ${l}`),
|
|
483
|
+
' *',
|
|
484
|
+
...descLines.map(l => ` * ${l}`),
|
|
485
|
+
...(seeAlsoRefs.length > 0 ? [' *'] : []),
|
|
486
|
+
...seeAlsoRefs.map(ref => ` * @seeAlso ${ref}`),
|
|
487
|
+
' *',
|
|
488
|
+
' * @cil-generated',
|
|
489
|
+
' */',
|
|
490
|
+
]
|
|
491
|
+
return docLines.join('\n')
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
const body: string[] = []
|
|
496
|
+
|
|
497
|
+
const chunkKind = d.chunk_type || ''
|
|
498
|
+
const isTypeDecl = ['interface', 'type', 'enum'].includes(chunkKind)
|
|
499
|
+
const isConstant = chunkKind === 'constant'
|
|
500
|
+
const isCallableChunk = !isTypeDecl && !isConstant
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
const macro = (d.macro || '').trim()
|
|
506
|
+
const micro = (d.micro || '').trim()
|
|
507
|
+
if (!isTypeDecl && !isConstant) {
|
|
508
|
+
const descNorm = description.toLowerCase().replace(/\s+/g, ' ')
|
|
509
|
+
const macroNorm = macro.toLowerCase().replace(/\s+/g, ' ')
|
|
510
|
+
const macroDistinct = macro && macroNorm !== descNorm && !descNorm.includes(macroNorm.slice(0, 40))
|
|
511
|
+
const microDistinct = micro && micro !== description && micro !== macro
|
|
512
|
+
if (macroDistinct) body.push(`@macro ${macro}`)
|
|
513
|
+
if (macroDistinct && microDistinct) body.push(`@micro ${micro}`)
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
if (isCallableChunk && d.input_spec) {
|
|
518
|
+
const entries = d.input_spec.split(/\n/).map((s: string) => s.trim()).filter(Boolean)
|
|
519
|
+
if (entries.length === 1 && entries[0].toLowerCase() === 'none') {
|
|
520
|
+
} else {
|
|
521
|
+
body.push('@inputSpec')
|
|
522
|
+
for (const entry of entries) body.push(` ${entry}`)
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
if (isCallableChunk && d.output_spec) body.push(`@outputSpec ${d.output_spec}`)
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
const throwsVal = (d.throws || '').trim()
|
|
532
|
+
if (throwsVal && throwsVal.toLowerCase() !== 'none') body.push(`@throws ${throwsVal}`)
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
if (d.side_effects) body.push(`@sideEffects ${d.side_effects}`)
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
if (d.stability) body.push(`@stability ${d.stability}`)
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
const callsVal = (d.calls || '').trim()
|
|
543
|
+
if (callsVal && callsVal.toLowerCase() !== 'unknown' && callsVal.toLowerCase() !== 'none') {
|
|
544
|
+
body.push(`@calls ${callsVal}`)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
const ehVal = (d.error_handling || '').trim()
|
|
551
|
+
const ehNoise = /^throws( on (unhandled|unexpected) errors?)?$/i.test(ehVal)
|
|
552
|
+
if (ehVal && !ehNoise) body.push(`@errorHandling ${ehVal}`)
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
body.push('@cil-generated')
|
|
558
|
+
|
|
559
|
+
const docLines = [
|
|
560
|
+
'/**',
|
|
561
|
+
` * ${description}`,
|
|
562
|
+
...(body.length > 0 ? [' *'] : []),
|
|
563
|
+
...body.map(l => ` * ${l}`),
|
|
564
|
+
' */',
|
|
565
|
+
]
|
|
566
|
+
return docLines.join('\n')
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_buildjsdoc_1784235266"]
|
|
574
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_validatechunkdocs_1784235266" type="function" identity="validatechunkdocs" parent="none"]
|
|
575
|
+
// CIL[DOC-MACRO purpose="Implements validatechunkdocs logic in cortex.functions.custom_cil-doc"]
|
|
576
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute validatechunkdocs and return its computed result"]
|
|
577
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
578
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
579
|
+
// CIL[DOC-MICRO logic_summary="Provides validatechunkdocs with validateChunkDocs(chunk: any inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
580
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
581
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
582
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
583
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
584
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
585
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
586
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
587
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
588
|
+
function validateChunkDocs(chunk: any): string[] {
|
|
589
|
+
const d = chunk.data || {}
|
|
590
|
+
const errors: string[] = []
|
|
591
|
+
const isModuleHeader = d.chunk_type === 'module_header'
|
|
592
|
+
|
|
593
|
+
const required = isModuleHeader ? REQUIRED_MODULE_FIELDS : REQUIRED_CHUNK_FIELDS
|
|
594
|
+
for (const field of required) {
|
|
595
|
+
if (!d[field] || String(d[field]).trim() === '') {
|
|
596
|
+
errors.push(`missing ${field}`)
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (!isModuleHeader && d.input_spec && d.input_spec !== 'none') {
|
|
601
|
+
const params = d.input_spec.split(/\n/).map((s: string) => s.trim()).filter(Boolean)
|
|
602
|
+
const paramNames = params.map(p => {
|
|
603
|
+
const m = p.match(/^[-\s]*([a-zA-Z0-9_]+)/)
|
|
604
|
+
return m ? m[1] : ''
|
|
605
|
+
}).filter(Boolean)
|
|
606
|
+
|
|
607
|
+
const code = d.code_content || ''
|
|
608
|
+
const signatureMatch = code.match(/(?:function|const|let|var)\s+\w+\s*\(([^)]*)\)/)
|
|
609
|
+
if (signatureMatch) {
|
|
610
|
+
const rawParams = signatureMatch[1]
|
|
611
|
+
const declaredNames = rawParams
|
|
612
|
+
.split(',')
|
|
613
|
+
.map(s => s.trim())
|
|
614
|
+
.filter(s => s)
|
|
615
|
+
.map(s => s.split(/[:=]/)[0].trim().replace(/\?/, ''))
|
|
616
|
+
.filter(Boolean)
|
|
617
|
+
for (const declared of declaredNames) {
|
|
618
|
+
if (!paramNames.includes(declared)) {
|
|
619
|
+
errors.push(`undocumented parameter: ${declared}`)
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return errors
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_validatechunkdocs_1784235266"]
|
|
633
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_findexistingciljsdoc_1784235266" type="function" identity="findexistingciljsdoc" parent="none"]
|
|
634
|
+
// CIL[DOC-MACRO purpose="Implements findexistingciljsdoc logic in cortex.functions.custom_cil-doc"]
|
|
635
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute findexistingciljsdoc and return its computed result"]
|
|
636
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
637
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
638
|
+
// CIL[DOC-MICRO logic_summary="Provides findexistingciljsdoc with findExistingCilJsDoc(lines: string[], markerIdx: number inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
639
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
640
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
641
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
642
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
643
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
644
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
645
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
646
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
647
|
+
function findExistingCilJsDoc(lines: string[], markerIdx: number): { start: number; end: number } | null {
|
|
648
|
+
let startIdx = -1
|
|
649
|
+
for (let i = markerIdx + 1; i < lines.length; i++) {
|
|
650
|
+
const trimmed = lines[i].trim()
|
|
651
|
+
if (trimmed === '') continue
|
|
652
|
+
if (trimmed.startsWith('/**')) { startIdx = i; break }
|
|
653
|
+
break
|
|
654
|
+
}
|
|
655
|
+
if (startIdx === -1) return null
|
|
656
|
+
|
|
657
|
+
let endIdx = -1
|
|
658
|
+
let hasCilTag = false
|
|
659
|
+
for (let i = startIdx; i < lines.length; i++) {
|
|
660
|
+
const trimmed = lines[i].trim()
|
|
661
|
+
if (trimmed.includes('@cil-generated')) hasCilTag = true
|
|
662
|
+
if (trimmed === '*/' || trimmed.endsWith('*/')) { endIdx = i; break }
|
|
663
|
+
}
|
|
664
|
+
if (endIdx === -1 || !hasCilTag) return null
|
|
665
|
+
return { start: startIdx, end: endIdx }
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_findexistingciljsdoc_1784235266"]
|
|
673
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_findlegacyciljsdocabove_1784235266" type="function" identity="findlegacyciljsdocabove" parent="none"]
|
|
674
|
+
// CIL[DOC-MACRO purpose="Implements findlegacyciljsdocabove logic in cortex.functions.custom_cil-doc"]
|
|
675
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute findlegacyciljsdocabove and return its computed result"]
|
|
676
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
677
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
678
|
+
// CIL[DOC-MICRO logic_summary="Provides findlegacyciljsdocabove with findLegacyCilJsDocAbove(lines: string[], markerIdx: number inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
679
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
680
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
681
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
682
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
683
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
684
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
685
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
686
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
687
|
+
function findLegacyCilJsDocAbove(lines: string[], markerIdx: number): { start: number; end: number } | null {
|
|
688
|
+
let endIdx = -1
|
|
689
|
+
for (let i = markerIdx - 1; i >= 0; i--) {
|
|
690
|
+
const trimmed = lines[i].trim()
|
|
691
|
+
if (trimmed === '') continue
|
|
692
|
+
if (trimmed === '*/' || trimmed.endsWith('*/')) { endIdx = i; break }
|
|
693
|
+
break
|
|
694
|
+
}
|
|
695
|
+
if (endIdx === -1) return null
|
|
696
|
+
|
|
697
|
+
let startIdx = -1
|
|
698
|
+
let hasCilTag = false
|
|
699
|
+
for (let i = endIdx; i >= 0; i--) {
|
|
700
|
+
const trimmed = lines[i].trim()
|
|
701
|
+
if (trimmed.includes('@cil-generated')) hasCilTag = true
|
|
702
|
+
if (trimmed.startsWith('/**')) { startIdx = i; break }
|
|
703
|
+
}
|
|
704
|
+
if (startIdx === -1 || !hasCilTag) return null
|
|
705
|
+
|
|
706
|
+
return { start: startIdx, end: endIdx }
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_findlegacyciljsdocabove_1784235266"]
|
|
714
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_writejsdoctosource_1784235266" type="function" identity="writejsdoctosource" parent="none"]
|
|
715
|
+
// CIL[DOC-MACRO purpose="Implements writejsdoctosource logic in cortex.functions.custom_cil-doc"]
|
|
716
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute writejsdoctosource and return its computed result"]
|
|
717
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
718
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
719
|
+
// CIL[DOC-MICRO logic_summary="Provides writejsdoctosource with writeJsDocToSource(chunk: any, repoPath: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
720
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
721
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
722
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
723
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
724
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
725
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
726
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
727
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
728
|
+
function writeJsDocToSource(chunk: any, repoPath: string): void {
|
|
729
|
+
const d = chunk.data || {}
|
|
730
|
+
const relPath = d.file_path
|
|
731
|
+
if (!repoPath || !relPath) return
|
|
732
|
+
|
|
733
|
+
const ext = path.extname(relPath).toLowerCase()
|
|
734
|
+
if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) return
|
|
735
|
+
|
|
736
|
+
const jsDoc = buildJsDoc(chunk)
|
|
737
|
+
if (!jsDoc) return
|
|
738
|
+
|
|
739
|
+
const absPath = path.join(repoPath, relPath)
|
|
740
|
+
if (!fs.existsSync(absPath)) return
|
|
741
|
+
|
|
742
|
+
const content = fs.readFileSync(absPath, 'utf-8')
|
|
743
|
+
const lines = content.split('\n')
|
|
744
|
+
|
|
745
|
+
const markerMap = findChunkStartMarkers(lines)
|
|
746
|
+
let markerIdx = markerMap.get((d.chunk_name || chunk.title).trim().toLowerCase())
|
|
747
|
+
if (markerIdx === undefined) return
|
|
748
|
+
|
|
749
|
+
const newLines = [...lines]
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
const legacyAbove = findLegacyCilJsDocAbove(newLines, markerIdx)
|
|
753
|
+
if (legacyAbove) {
|
|
754
|
+
newLines.splice(legacyAbove.start, legacyAbove.end - legacyAbove.start + 1)
|
|
755
|
+
|
|
756
|
+
markerIdx -= (legacyAbove.end - legacyAbove.start + 1)
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const existing = findExistingCilJsDoc(newLines, markerIdx)
|
|
760
|
+
if (existing) {
|
|
761
|
+
newLines.splice(existing.start, existing.end - existing.start + 1, jsDoc)
|
|
762
|
+
} else {
|
|
763
|
+
newLines.splice(markerIdx + 1, 0, jsDoc)
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
fs.writeFileSync(absPath, newLines.join('\n'), 'utf-8')
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_writejsdoctosource_1784235266"]
|
|
772
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_escaperegexp_1784235266" type="function" identity="escaperegexp" parent="none"]
|
|
773
|
+
// CIL[DOC-MACRO purpose="Implements escaperegexp logic in cortex.functions.custom_cil-doc"]
|
|
774
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute escaperegexp and return its computed result"]
|
|
775
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
776
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
777
|
+
// CIL[DOC-MICRO logic_summary="Provides escaperegexp with escapeRegExp(s: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
778
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
779
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
780
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
781
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
782
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
783
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
784
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
785
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
786
|
+
function escapeRegExp(s: string): string {
|
|
787
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_escaperegexp_1784235266"]
|
|
800
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_chunk_start_marker_re_1784235266" type="variable" identity="chunk_start_marker_re" parent="none"]
|
|
801
|
+
// CIL[DOC-MACRO purpose="Defines chunk_start_marker_re configuration or state in cortex.functions.custom_cil-doc"]
|
|
802
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for chunk_start_marker_re"]
|
|
803
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
804
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of chunk_start_marker_re" errors="none" side_effects="none"]
|
|
805
|
+
// CIL[DOC-MICRO logic_summary="Declares chunk_start_marker_re with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
806
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
807
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
808
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
809
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
810
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
811
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
812
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
813
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
814
|
+
const CHUNK_START_MARKER_RE = /^\s*\/\*\*\s*[─\-]+\s*CHUNK_START:\s*(?:PROPOSAL\s+|REJECTED\s+)?(.+?)\s*[─\-]*\s*\*\/\s*$/
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_chunk_start_marker_re_1784235266"]
|
|
826
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_findchunkstartmarkers_1784235266" type="function" identity="findchunkstartmarkers" parent="none"]
|
|
827
|
+
// CIL[DOC-MACRO purpose="Implements findchunkstartmarkers logic in cortex.functions.custom_cil-doc"]
|
|
828
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute findchunkstartmarkers and return its computed result"]
|
|
829
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
830
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
831
|
+
// CIL[DOC-MICRO logic_summary="Provides findchunkstartmarkers with findChunkStartMarkers(lines: string[] inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
832
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
833
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
834
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
835
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
836
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
837
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
838
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
839
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
840
|
+
function findChunkStartMarkers(lines: string[]): Map<string, number> {
|
|
841
|
+
const map = new Map<string, number>()
|
|
842
|
+
for (let i = 0; i < lines.length; i++) {
|
|
843
|
+
const m = lines[i].match(CHUNK_START_MARKER_RE)
|
|
844
|
+
if (m) {
|
|
845
|
+
const name = m[1].trim().toLowerCase()
|
|
846
|
+
if (!map.has(name)) map.set(name, i)
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return map
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_findchunkstartmarkers_1784235266"]
|
|
859
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_builddocprompt_1784235266" type="function" identity="builddocprompt" parent="none"]
|
|
860
|
+
// CIL[DOC-MACRO purpose="Implements builddocprompt logic in cortex.functions.custom_cil-doc"]
|
|
861
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute builddocprompt and return its computed result"]
|
|
862
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
863
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
864
|
+
// CIL[DOC-MICRO logic_summary="Provides builddocprompt with buildDocPrompt(chunk: any inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
865
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
866
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
867
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
868
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
869
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
870
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
871
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
872
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
873
|
+
function buildDocPrompt(chunk: any): string {
|
|
874
|
+
const d = chunk.data || {}
|
|
875
|
+
const code = (d.code_content || '').slice(0, 3000)
|
|
876
|
+
const isModuleHeader = d.chunk_type === 'module_header'
|
|
877
|
+
return isModuleHeader ? buildModuleHeaderPrompt(d, code) : buildChunkPrompt(d, code)
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_builddocprompt_1784235266"]
|
|
890
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_buildmoduleheaderprompt_1784235266" type="function" identity="buildmoduleheaderprompt" parent="none"]
|
|
891
|
+
// CIL[DOC-MACRO purpose="Implements buildmoduleheaderprompt logic in cortex.functions.custom_cil-doc"]
|
|
892
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute buildmoduleheaderprompt and return its computed result"]
|
|
893
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
894
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
895
|
+
// CIL[DOC-MICRO logic_summary="Provides buildmoduleheaderprompt with buildModuleHeaderPrompt(d: any, code: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
896
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
897
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
898
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
899
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
900
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
901
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
902
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
903
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
904
|
+
function buildModuleHeaderPrompt(d: any, code: string): string {
|
|
905
|
+
const filePath = d.file_path || 'unknown'
|
|
906
|
+
return `You are documenting the MODULE HEADER for file: ${filePath}
|
|
907
|
+
|
|
908
|
+
This is the top of the file — imports, constants, and module-level setup.
|
|
909
|
+
|
|
910
|
+
\`\`\`typescript
|
|
911
|
+
${code}
|
|
912
|
+
\`\`\`
|
|
913
|
+
|
|
914
|
+
Generate a file-level JSDoc block. Your job is to orient a developer to this module
|
|
915
|
+
in 10 seconds — what it does, how it is entered, and what depends on it.
|
|
916
|
+
|
|
917
|
+
Rules:
|
|
918
|
+
- description: 2–4 sentences covering what the module does, its role in the system,
|
|
919
|
+
and any key architectural constraints. If this is an API handler, include the
|
|
920
|
+
route pattern(s). If it has a multi-step pipeline (auth → validate → execute),
|
|
921
|
+
number the steps. If there are non-obvious invariants (things that must always be
|
|
922
|
+
true for callers), prefix them with INVARIANT:.
|
|
923
|
+
- seeAlso: 2–4 direct dependencies a reader needs to understand this module.
|
|
924
|
+
Format each as: filename (reason it matters). Omit obvious/trivial imports.
|
|
925
|
+
- Do NOT list every import. Do NOT describe individual functions (those get their own docs).
|
|
926
|
+
|
|
927
|
+
Respond ONLY with a JSON object (no markdown, no commentary):
|
|
928
|
+
{
|
|
929
|
+
"description": "<2-4 sentences + optional route table + optional numbered flow + optional INVARIANT lines, all as a single string with \\n between paragraphs>",
|
|
930
|
+
"module": "<filename without extension>",
|
|
931
|
+
"audience": "<internal | external | both>",
|
|
932
|
+
"layer": "<shared-core | app-specific | infrastructure | test>",
|
|
933
|
+
"stability": "<stable | experimental | deprecated>",
|
|
934
|
+
"seeAlso": "<newline-separated list: filename (reason). 2-4 entries max. Empty string if no meaningful cross-references.>",
|
|
935
|
+
"tags": "<comma-separated relevant tags>"
|
|
936
|
+
}`
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_buildmoduleheaderprompt_1784235266"]
|
|
949
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_buildchunkprompt_1784235266" type="function" identity="buildchunkprompt" parent="none"]
|
|
950
|
+
// CIL[DOC-MACRO purpose="Implements buildchunkprompt logic in cortex.functions.custom_cil-doc"]
|
|
951
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute buildchunkprompt and return its computed result"]
|
|
952
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
953
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
954
|
+
// CIL[DOC-MICRO logic_summary="Provides buildchunkprompt with buildChunkPrompt(d: any, code: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
955
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
956
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
957
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
958
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
959
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
960
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
961
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
962
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
963
|
+
function buildChunkPrompt(d: any, code: string): string {
|
|
964
|
+
const chunkType = d.chunk_type || 'function'
|
|
965
|
+
const chunkName = d.chunk_name || 'unknown'
|
|
966
|
+
const location = `${d.file_path || 'unknown'}:${d.line_start || 0}-${d.line_end || 0}`
|
|
967
|
+
|
|
968
|
+
return `You are documenting a ${chunkType} named "${chunkName}" at ${location}.
|
|
969
|
+
|
|
970
|
+
\`\`\`typescript
|
|
971
|
+
${code}
|
|
972
|
+
\`\`\`
|
|
973
|
+
|
|
974
|
+
Rules:
|
|
975
|
+
- description: 1–2 sentences — what it does and why it exists in this module.
|
|
976
|
+
Do NOT start with "It achieves this by". Write it as a direct statement.
|
|
977
|
+
- macro: one sentence classifying WHAT this chunk IS and its primary responsibility.
|
|
978
|
+
Only write this if it adds information that description does not already convey.
|
|
979
|
+
Example: "Async resolver that maps an HTTP request to a typed Principal object."
|
|
980
|
+
If it would be the same sentence as description, return "".
|
|
981
|
+
- micro: one sentence on the SPECIFIC implementation mechanism — the algorithm,
|
|
982
|
+
branching strategy, data structure, or key external call pattern used.
|
|
983
|
+
Must be distinct from macro. If not meaningfully distinct, return "".
|
|
984
|
+
Example: "Checks headers in priority order (API key → cron → trigger → JWT),
|
|
985
|
+
delegating to a type-specific sub-resolver for each."
|
|
986
|
+
- inputSpec: one line per parameter: - name: Type (required|optional[|nullable]) — description.
|
|
987
|
+
Be precise about types (string, UUID, timestamp, not just "string").
|
|
988
|
+
Note enums if the field has a fixed value set.
|
|
989
|
+
Write "none" if the function takes no parameters.
|
|
990
|
+
- outputSpec: exact return type including Promise<T> if async. Add a brief shape
|
|
991
|
+
description if the return value is non-obvious.
|
|
992
|
+
- throws: only list errors the function explicitly throws that callers must handle.
|
|
993
|
+
Write "none" if the function never throws.
|
|
994
|
+
- side_effects: concrete observable effects (DB writes, RPC calls, file I/O,
|
|
995
|
+
external API calls). Write "none" if the function is pure.
|
|
996
|
+
- stability: stable | experimental | deprecated
|
|
997
|
+
- calls: comma-separated list of KEY named functions or external services this chunk
|
|
998
|
+
calls. Write the function name or service name only — not method chains.
|
|
999
|
+
BAD: "adminDb.from, adminDb.select, adminDb.eq, adminDb.single" (these are chained
|
|
1000
|
+
builder methods on one call — write "adminDb.from('schedules')" instead)
|
|
1001
|
+
GOOD: "adminDb.rpc('validate_machine_principal'), getClientIp"
|
|
1002
|
+
GOOD: "supabase.auth.getUser, adminDb.from('people')"
|
|
1003
|
+
Omit: String methods, Array methods, standard library, trivial getters.
|
|
1004
|
+
Write "none" if no significant external callees.
|
|
1005
|
+
- errorHandling: only write this if the error handling strategy is non-obvious —
|
|
1006
|
+
e.g. "returns ANONYMOUS_PRINCIPAL on auth failure rather than throwing".
|
|
1007
|
+
Write "" if it simply throws or returns null on error.
|
|
1008
|
+
- calledBy: your best guess at likely callers or entry points. For RAG use only.
|
|
1009
|
+
- complexity: simple | moderate | complex
|
|
1010
|
+
- tags: comma-separated relevant tags
|
|
1011
|
+
|
|
1012
|
+
Respond ONLY with a JSON object (no markdown, no commentary):
|
|
1013
|
+
{
|
|
1014
|
+
"description": "<1-2 direct sentences>",
|
|
1015
|
+
"macro": "<classification sentence, or empty string>",
|
|
1016
|
+
"micro": "<mechanism sentence distinct from macro, or empty string>",
|
|
1017
|
+
"inputSpec": "<newline-separated param lines, or 'none'>",
|
|
1018
|
+
"outputSpec": "<return type and shape>",
|
|
1019
|
+
"throws": "<ErrorType — condition, or 'none'>",
|
|
1020
|
+
"side_effects": "<effects or 'none'>",
|
|
1021
|
+
"stability": "<stable | experimental | deprecated>",
|
|
1022
|
+
"calls": "<key callees or 'none'>",
|
|
1023
|
+
"errorHandling": "<non-obvious strategy or empty string>",
|
|
1024
|
+
"calledBy": "<likely callers or 'unknown'>",
|
|
1025
|
+
"complexity": "<simple | moderate | complex>",
|
|
1026
|
+
"tags": "<comma-separated tags>"
|
|
1027
|
+
}`
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_buildchunkprompt_1784235266"]
|
|
1039
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_callllm_1784235266" type="function" identity="callllm" parent="none"]
|
|
1040
|
+
// CIL[DOC-MACRO purpose="Implements callllm logic in cortex.functions.custom_cil-doc"]
|
|
1041
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute callllm and return its computed result"]
|
|
1042
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
1043
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
1044
|
+
// CIL[DOC-MICRO logic_summary="Provides callllm with callLLM(prompt: string, model: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
1045
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
1046
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
1047
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
1048
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
1049
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
1050
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
1051
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
1052
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
1053
|
+
async function callLLM(prompt: string, model: string): Promise<string> {
|
|
1054
|
+
const j = await callOpenAIChat(undefined, [
|
|
1055
|
+
{
|
|
1056
|
+
role: 'system',
|
|
1057
|
+
content: 'You are a code documentation assistant. You extract structured contracts from source code. Always respond with valid JSON only.',
|
|
1058
|
+
},
|
|
1059
|
+
{ role: 'user', content: prompt },
|
|
1060
|
+
], model, {
|
|
1061
|
+
temperature: 0.2,
|
|
1062
|
+
max_tokens: 800,
|
|
1063
|
+
response_format: { type: 'json_object' }
|
|
1064
|
+
})
|
|
1065
|
+
return j.choices?.[0]?.message?.content?.trim() || '{}'
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_callllm_1784235266"]
|
|
1073
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_parsedocresponse_1784235266" type="function" identity="parsedocresponse" parent="none"]
|
|
1074
|
+
// CIL[DOC-MACRO purpose="Implements parsedocresponse logic in cortex.functions.custom_cil-doc"]
|
|
1075
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute parsedocresponse and return its computed result"]
|
|
1076
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
1077
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
1078
|
+
// CIL[DOC-MICRO logic_summary="Provides parsedocresponse with parseDocResponse(raw: string inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
1079
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
1080
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
1081
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
1082
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
1083
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
1084
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
1085
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
1086
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
1087
|
+
function parseDocResponse(raw: string): Record<string, string> {
|
|
1088
|
+
try {
|
|
1089
|
+
|
|
1090
|
+
let cleaned = raw.trim()
|
|
1091
|
+
if (cleaned.startsWith('```')) {
|
|
1092
|
+
cleaned = cleaned.replace(/^```[a-zA-Z0-9]*\n?/, '').replace(/\n?```$/, '').trim()
|
|
1093
|
+
}
|
|
1094
|
+
const parsed = JSON.parse(cleaned)
|
|
1095
|
+
return {
|
|
1096
|
+
description: String(parsed.description || parsed.macro || '').slice(0, 1000),
|
|
1097
|
+
macro: String(parsed.macro || '').slice(0, 500),
|
|
1098
|
+
micro: String(parsed.micro || '').slice(0, 500),
|
|
1099
|
+
input_spec: String(parsed.inputSpec || parsed.input_spec || '').slice(0, 2000),
|
|
1100
|
+
output_spec: String(parsed.outputSpec || parsed.output_spec || '').slice(0, 500),
|
|
1101
|
+
throws: String(parsed.throws || '').slice(0, 500),
|
|
1102
|
+
side_effects:String(parsed.sideEffects || parsed.side_effects|| '').slice(0, 500),
|
|
1103
|
+
stability: ['stable', 'internal', 'experimental', 'deprecated'].includes(parsed.stability)
|
|
1104
|
+
? parsed.stability : 'internal',
|
|
1105
|
+
called_by: String(parsed.calledBy || parsed.called_by || '').slice(0, 500),
|
|
1106
|
+
calls: String(parsed.calls || '').slice(0, 500),
|
|
1107
|
+
tags: String(parsed.tags || '').slice(0, 500),
|
|
1108
|
+
complexity: ['simple', 'moderate', 'complex'].includes(parsed.complexity)
|
|
1109
|
+
? parsed.complexity : 'moderate',
|
|
1110
|
+
error_handling: String(parsed.errorHandling || parsed.error_handling || '').slice(0, 500),
|
|
1111
|
+
module: String(parsed.module || '').slice(0, 100),
|
|
1112
|
+
audience: ['internal', 'external', 'both'].includes(parsed.audience)
|
|
1113
|
+
? parsed.audience : 'both',
|
|
1114
|
+
layer: ['shared-core', 'app-specific', 'infrastructure', 'test'].includes(parsed.layer)
|
|
1115
|
+
? parsed.layer : 'app-specific',
|
|
1116
|
+
see_also: String(parsed.seeAlso || parsed.see_also || '').slice(0, 1000),
|
|
1117
|
+
}
|
|
1118
|
+
} catch {
|
|
1119
|
+
return {}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_parsedocresponse_1784235266"]
|
|
1132
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_hasmeaningfulllmfields_1784235266" type="function" identity="hasmeaningfulllmfields" parent="none"]
|
|
1133
|
+
// CIL[DOC-MACRO purpose="Implements hasmeaningfulllmfields logic in cortex.functions.custom_cil-doc"]
|
|
1134
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute hasmeaningfulllmfields and return its computed result"]
|
|
1135
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
1136
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
1137
|
+
// CIL[DOC-MICRO logic_summary="Provides hasmeaningfulllmfields with hasMeaningfulLlmFields(fields: Record<string, string> inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
1138
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
1139
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
1140
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
1141
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
1142
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
1143
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
1144
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
1145
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
1146
|
+
function hasMeaningfulLlmFields(fields: Record<string, string>): boolean {
|
|
1147
|
+
const meaningfulKeys = ['description', 'macro', 'micro', 'input_spec', 'output_spec']
|
|
1148
|
+
return meaningfulKeys.some(k => (fields[k] || '').trim() !== '')
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_hasmeaningfulllmfields_1784235266"]
|
|
1158
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_normalizedocfields_1784235266" type="function" identity="normalizedocfields" parent="none"]
|
|
1159
|
+
// CIL[DOC-MACRO purpose="Implements normalizedocfields logic in cortex.functions.custom_cil-doc"]
|
|
1160
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute normalizedocfields and return its computed result"]
|
|
1161
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
1162
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
1163
|
+
// CIL[DOC-MICRO logic_summary="Provides normalizedocfields with normalizeDocFields(fields: Record<string, string>, chunk: any inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
1164
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
1165
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
1166
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
1167
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
1168
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
1169
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
1170
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
1171
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
1172
|
+
function normalizeDocFields(fields: Record<string, string>, chunk: any): Record<string, string> {
|
|
1173
|
+
const d = chunk.data || {}
|
|
1174
|
+
const isModuleHeader = d.chunk_type === 'module_header'
|
|
1175
|
+
const code = d.code_content || ''
|
|
1176
|
+
const chunkName = d.chunk_name || chunk.title || ''
|
|
1177
|
+
const layer = d.layer || (isModuleHeader ? 'shared-core' : 'app-specific')
|
|
1178
|
+
|
|
1179
|
+
const normalized = { ...fields }
|
|
1180
|
+
|
|
1181
|
+
if (isModuleHeader) {
|
|
1182
|
+
if (!normalized.module) normalized.module = moduleNameFromPath(d.file_path || chunkName)
|
|
1183
|
+
if (!normalized.audience) normalized.audience = 'both'
|
|
1184
|
+
if (!normalized.layer) normalized.layer = layer
|
|
1185
|
+
if (!normalized.description) normalized.description = normalized.macro || `${chunkName} module setup and imports.`
|
|
1186
|
+
if (!normalized.stability) normalized.stability = 'stable'
|
|
1187
|
+
if (!normalized.see_also) normalized.see_also = ''
|
|
1188
|
+
} else {
|
|
1189
|
+
const chunkType = d.chunk_type || 'symbol'
|
|
1190
|
+
const isCallable = !['interface', 'type', 'enum', 'constant'].includes(chunkType)
|
|
1191
|
+
|
|
1192
|
+
if (!normalized.description) normalized.description = normalized.macro || `${chunkName} ${chunkType}.`
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
const macroFromLlm = fields.macro
|
|
1198
|
+
const microFromLlm = fields.micro
|
|
1199
|
+
if (macroFromLlm === undefined || macroFromLlm === null) {
|
|
1200
|
+
normalized.macro = normalized.description.split(/(?<=[.!?])\s+/)[0] || normalized.description
|
|
1201
|
+
}
|
|
1202
|
+
if (microFromLlm === undefined || microFromLlm === null) {
|
|
1203
|
+
normalized.micro = ''
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
if (!normalized.input_spec) {
|
|
1209
|
+
if (isCallable) {
|
|
1210
|
+
const sigMatch = code.match(/(?:function|const|let|var)\s+\w+\s*\(([^)]*)\)|(?:async\s+)?function\s*\(([^)]*)\)/)
|
|
1211
|
+
const paramStr = sigMatch?.[1] || sigMatch?.[2] || ''
|
|
1212
|
+
const params = paramStr.split(',').map(s => s.trim()).filter(Boolean).map(p => {
|
|
1213
|
+
const [name, type] = p.split(/[:=]/).map(s => s.trim())
|
|
1214
|
+
const optional = p.includes('?')
|
|
1215
|
+
return `- ${name.replace(/\?$/, '')}: ${type || 'any'} (${optional ? 'optional' : 'required'})`
|
|
1216
|
+
})
|
|
1217
|
+
normalized.input_spec = params.length ? params.join('\n') : 'none'
|
|
1218
|
+
} else {
|
|
1219
|
+
normalized.input_spec = 'none'
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
if (!normalized.output_spec) {
|
|
1225
|
+
if (!isCallable) {
|
|
1226
|
+
normalized.output_spec = chunkName
|
|
1227
|
+
} else {
|
|
1228
|
+
|
|
1229
|
+
const returnMatch = code.match(/\)\s*:\s*(Promise<[^>]+>|[A-Za-z0-9_<>|[\]{}?\s]+)\s*(?:\{|=>)/)
|
|
1230
|
+
normalized.output_spec = returnMatch ? returnMatch[1].trim() : 'void'
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
if (!normalized.side_effects) normalized.side_effects = 'none'
|
|
1235
|
+
if (!normalized.stability) normalized.stability = 'stable'
|
|
1236
|
+
if (!normalized.tags) normalized.tags = chunkType
|
|
1237
|
+
if (!normalized.complexity) normalized.complexity = 'moderate'
|
|
1238
|
+
if (!normalized.error_handling) normalized.error_handling = ''
|
|
1239
|
+
if (!normalized.called_by) normalized.called_by = 'unknown'
|
|
1240
|
+
if (!normalized.calls) normalized.calls = 'unknown'
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
return normalized
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_normalizedocfields_1784235266"]
|
|
1251
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_documentchunk_1784235266" type="function" identity="documentchunk" parent="none"]
|
|
1252
|
+
// CIL[DOC-MACRO purpose="Implements documentchunk logic in cortex.functions.custom_cil-doc"]
|
|
1253
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Execute documentchunk and return its computed result"]
|
|
1254
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
1255
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="return value from function execution" errors="throws on invalid input or runtime failure" side_effects="none"]
|
|
1256
|
+
// CIL[DOC-MICRO logic_summary="Provides documentchunk with documentChunk( inputs, handling internal flow and returning a result" notable_decisions="[]"]
|
|
1257
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
1258
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
1259
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
1260
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
1261
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
1262
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
1263
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
1264
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
1265
|
+
async function documentChunk(
|
|
1266
|
+
ctx: any,
|
|
1267
|
+
chunk: any,
|
|
1268
|
+
model: string,
|
|
1269
|
+
force: boolean,
|
|
1270
|
+
repoPath?: string
|
|
1271
|
+
): Promise<{ success: boolean; fields_set: string[]; error?: string; skipped?: boolean; updatedChunk?: any; validation_errors?: string[] }> {
|
|
1272
|
+
if (!force && !needsDocumentation(chunk)) {
|
|
1273
|
+
return { success: true, fields_set: [], skipped: true, updatedChunk: chunk }
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
const d = chunk.data || {}
|
|
1277
|
+
if (!d.code_content && !d.chunk_name) {
|
|
1278
|
+
return { success: false, fields_set: [], error: 'No code content to document' }
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
const prompt = buildDocPrompt(chunk)
|
|
1282
|
+
|
|
1283
|
+
let raw: string
|
|
1284
|
+
try {
|
|
1285
|
+
raw = await callLLM(prompt, model)
|
|
1286
|
+
} catch (err) {
|
|
1287
|
+
return { success: false, fields_set: [], error: err instanceof Error ? err.message : String(err) }
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
const rawFields = parseDocResponse(raw)
|
|
1291
|
+
const hadLlmFields = hasMeaningfulLlmFields(rawFields)
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
const fields = normalizeDocFields(rawFields, chunk)
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
const toWrite: Record<string, string> = {}
|
|
1300
|
+
for (const [k, v] of Object.entries(fields)) {
|
|
1301
|
+
if (force || !d[k]) toWrite[k] = v
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
if (!Object.keys(toWrite).length) {
|
|
1305
|
+
return { success: true, fields_set: [], skipped: true, updatedChunk: chunk }
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
const updatedData = { ...d, ...toWrite, doc_confidence: 'ai_generated', doc_fallback: !hadLlmFields }
|
|
1309
|
+
const updatedChunk = { ...chunk, data: updatedData }
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
const validationErrors = validateChunkDocs(updatedChunk)
|
|
1313
|
+
if (validationErrors.length > 0) {
|
|
1314
|
+
return { success: false, fields_set: [], error: `Validation failed: ${validationErrors.join(', ')}`, validation_errors: validationErrors, updatedChunk }
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
const updateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: chunk.id } }
|
|
1318
|
+
try {
|
|
1319
|
+
await adminUpdate(updateCtx, { data: updatedData })
|
|
1320
|
+
} catch (updateError: any) {
|
|
1321
|
+
return { success: false, fields_set: [], error: updateError.message }
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
if (repoPath) {
|
|
1326
|
+
writeJsDocToSource(updatedChunk, repoPath)
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
return { success: true, fields_set: Object.keys(toWrite), updatedChunk }
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_documentchunk_1784235266"]
|
|
1337
|
+
// CIL[BEGIN chunk_id="custom_apps_cortex_functions_custom_cil_doc_handler_1784235266" type="variable" identity="handler" parent="none"]
|
|
1338
|
+
// CIL[DOC-MACRO purpose="Defines handler configuration or state in cortex.functions.custom_cil-doc"]
|
|
1339
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Hold the value and default configuration for handler"]
|
|
1340
|
+
// CIL[DOC-CONTEXT module="cortex.functions.custom_cil-doc" layer="function" related_files="[]"]
|
|
1341
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="value of handler" errors="none" side_effects="none"]
|
|
1342
|
+
// CIL[DOC-MICRO logic_summary="Declares handler with initial value or constant binding used by cortex.functions.custom_cil-doc" notable_decisions="[]"]
|
|
1343
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
1344
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
1345
|
+
// CIL[DOC-VECTOR type="context" content="Layer: function. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
1346
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
1347
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
1348
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
1349
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
1350
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
1351
|
+
export const handler = createHandler(async (ctx, body) => {
|
|
1352
|
+
const action = ctx.query?.action
|
|
1353
|
+
|
|
1354
|
+
|
|
1355
|
+
if (action === 'gap_report') {
|
|
1356
|
+
const projectId = ctx.query?.project_id || body?.project_id
|
|
1357
|
+
if (!projectId) throw new Error('project_id is required')
|
|
1358
|
+
|
|
1359
|
+
const chunks = await loadAllChunks(projectId)
|
|
1360
|
+
|
|
1361
|
+
const undocumented = chunks.filter(needsDocumentation)
|
|
1362
|
+
const documented = chunks.filter(c => !needsDocumentation(c))
|
|
1363
|
+
const aiGenerated = documented.filter(c => c.data?.doc_confidence === 'ai_generated')
|
|
1364
|
+
const humanVerified= documented.filter(c => c.data?.doc_confidence === 'human_verified')
|
|
1365
|
+
|
|
1366
|
+
return {
|
|
1367
|
+
project_id: projectId,
|
|
1368
|
+
total_chunks: chunks.length,
|
|
1369
|
+
undocumented_count: undocumented.length,
|
|
1370
|
+
documented_count: documented.length,
|
|
1371
|
+
ai_generated_count: aiGenerated.length,
|
|
1372
|
+
human_verified_count: humanVerified.length,
|
|
1373
|
+
coverage_pct: chunks.length
|
|
1374
|
+
? Math.round((documented.length / chunks.length) * 100) : 0,
|
|
1375
|
+
undocumented: undocumented.slice(0, 100).map(c => ({
|
|
1376
|
+
id: c.id,
|
|
1377
|
+
chunk_name: c.data?.chunk_name || c.title,
|
|
1378
|
+
file_path: c.data?.file_path || '',
|
|
1379
|
+
chunk_type: c.data?.chunk_type || '',
|
|
1380
|
+
line_count: (c.data?.line_end || 0) - (c.data?.line_start || 0) + 1,
|
|
1381
|
+
token_count: c.data?.token_count || 0,
|
|
1382
|
+
})),
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
if (action === 'estimate') {
|
|
1388
|
+
const projectId = ctx.query?.project_id || body?.project_id
|
|
1389
|
+
const model = ctx.query?.model || body?.model || DEFAULT_MODEL
|
|
1390
|
+
const modelPrices = body?.model_prices || MODEL_PRICES[model] || MODEL_PRICES[DEFAULT_MODEL]
|
|
1391
|
+
const filePath = ctx.query?.file_path || body?.file_path
|
|
1392
|
+
|
|
1393
|
+
if (!projectId) throw new Error('project_id is required')
|
|
1394
|
+
|
|
1395
|
+
const chunks = await loadAllChunks(projectId, filePath)
|
|
1396
|
+
const toDocument = chunks.filter(needsDocumentation)
|
|
1397
|
+
|
|
1398
|
+
let totalInputTokens = 0
|
|
1399
|
+
const breakdown: any[] = []
|
|
1400
|
+
|
|
1401
|
+
for (const chunk of toDocument) {
|
|
1402
|
+
const prompt = buildDocPrompt(chunk)
|
|
1403
|
+
const inputTokens = estimateTokens(prompt) + SYSTEM_PROMPT_OVERHEAD_TOKENS
|
|
1404
|
+
totalInputTokens += inputTokens
|
|
1405
|
+
breakdown.push({
|
|
1406
|
+
chunk_name: chunk.data?.chunk_name || chunk.title,
|
|
1407
|
+
file_path: chunk.data?.file_path || '',
|
|
1408
|
+
input_tokens: inputTokens,
|
|
1409
|
+
})
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
const totalOutputTokens = toDocument.length * ESTIMATED_OUTPUT_TOKENS_PER_CHUNK
|
|
1413
|
+
const totalTokens = totalInputTokens + totalOutputTokens
|
|
1414
|
+
|
|
1415
|
+
const inputCostUsd = (totalInputTokens / 1_000_000) * modelPrices.input_per_1m
|
|
1416
|
+
const outputCostUsd = (totalOutputTokens / 1_000_000) * modelPrices.output_per_1m
|
|
1417
|
+
const totalCostUsd = inputCostUsd + outputCostUsd
|
|
1418
|
+
|
|
1419
|
+
return {
|
|
1420
|
+
project_id: projectId,
|
|
1421
|
+
model,
|
|
1422
|
+
file_path: filePath || null,
|
|
1423
|
+
model_prices: modelPrices,
|
|
1424
|
+
chunks_to_document: toDocument.length,
|
|
1425
|
+
total_chunks: chunks.length,
|
|
1426
|
+
already_documented: chunks.length - toDocument.length,
|
|
1427
|
+
estimated_input_tokens: totalInputTokens,
|
|
1428
|
+
estimated_output_tokens: totalOutputTokens,
|
|
1429
|
+
estimated_total_tokens: totalTokens,
|
|
1430
|
+
estimated_cost_usd: parseFloat(totalCostUsd.toFixed(4)),
|
|
1431
|
+
estimated_cost_usd_breakdown: {
|
|
1432
|
+
input: parseFloat(inputCostUsd.toFixed(4)),
|
|
1433
|
+
output: parseFloat(outputCostUsd.toFixed(4)),
|
|
1434
|
+
},
|
|
1435
|
+
|
|
1436
|
+
top_chunks_by_cost: breakdown
|
|
1437
|
+
.sort((a, b) => b.input_tokens - a.input_tokens)
|
|
1438
|
+
.slice(0, 20),
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
if (action === 'doc_chunk') {
|
|
1444
|
+
const chunkId = body?.chunk_id || ctx.query?.chunk_id
|
|
1445
|
+
const model = body?.model || ctx.query?.model || DEFAULT_MODEL
|
|
1446
|
+
const force = body?.force ?? false
|
|
1447
|
+
if (!chunkId) throw new Error('chunk_id is required')
|
|
1448
|
+
|
|
1449
|
+
const { data: chunk, error } = await adminDb
|
|
1450
|
+
.from('items')
|
|
1451
|
+
.select('id, title, data')
|
|
1452
|
+
.eq('id', chunkId)
|
|
1453
|
+
.maybeSingle()
|
|
1454
|
+
|
|
1455
|
+
if (error || !chunk) throw new Error(`Chunk not found: ${chunkId}`)
|
|
1456
|
+
|
|
1457
|
+
const projectId = chunk.data?.project_id
|
|
1458
|
+
let repoPath = ''
|
|
1459
|
+
if (projectId) {
|
|
1460
|
+
const { data: projectItem } = await adminDb.from('items').select('data').eq('id', projectId).maybeSingle()
|
|
1461
|
+
repoPath = projectItem?.data?.repo_path || ''
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
const result = await documentChunk(ctx, chunk, model, force, repoPath)
|
|
1465
|
+
return { chunk_id: chunkId, chunk_name: chunk.data?.chunk_name || chunk.title, ...result }
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
|
|
1471
|
+
if (action === 'validate') {
|
|
1472
|
+
const projectId = ctx.query?.project_id || body?.project_id
|
|
1473
|
+
const filePath = ctx.query?.file_path || body?.file_path
|
|
1474
|
+
if (!projectId) throw new Error('project_id is required')
|
|
1475
|
+
|
|
1476
|
+
const chunks = await loadAllChunks(projectId, filePath)
|
|
1477
|
+
const invalid: any[] = []
|
|
1478
|
+
for (const chunk of chunks) {
|
|
1479
|
+
const errors = validateChunkDocs(chunk)
|
|
1480
|
+
if (errors.length > 0) {
|
|
1481
|
+
invalid.push({
|
|
1482
|
+
chunk_id: chunk.id,
|
|
1483
|
+
chunk_name: chunk.data?.chunk_name || chunk.title,
|
|
1484
|
+
file_path: chunk.data?.file_path || '',
|
|
1485
|
+
chunk_type: chunk.data?.chunk_type || '',
|
|
1486
|
+
errors,
|
|
1487
|
+
})
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
return {
|
|
1492
|
+
project_id: projectId,
|
|
1493
|
+
file_path: filePath || null,
|
|
1494
|
+
total_chunks: chunks.length,
|
|
1495
|
+
valid_chunks: chunks.length - invalid.length,
|
|
1496
|
+
invalid_chunks: invalid.length,
|
|
1497
|
+
invalid,
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
|
|
1507
|
+
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
if (action === 'document') {
|
|
1514
|
+
const projectId = body?.project_id
|
|
1515
|
+
if (!projectId) throw new Error('project_id is required')
|
|
1516
|
+
|
|
1517
|
+
const model = body?.model || DEFAULT_MODEL
|
|
1518
|
+
const dryRun = body?.dry_run ?? false
|
|
1519
|
+
const force = body?.force ?? false
|
|
1520
|
+
const chunkIds: string[] | undefined = body?.chunk_ids
|
|
1521
|
+
const filePath: string | undefined = body?.file_path
|
|
1522
|
+
const pageLimit = Math.min(parseInt(body?.limit || '5', 10), 100)
|
|
1523
|
+
const pageOffset= parseInt(body?.offset || '0', 10)
|
|
1524
|
+
const concurrency = Math.min(parseInt(body?.concurrency || '20', 10), 30)
|
|
1525
|
+
|
|
1526
|
+
|
|
1527
|
+
const { data: projectItem } = await adminDb.from('items').select('id, data').eq('id', projectId).maybeSingle()
|
|
1528
|
+
const selectedPaths: string[] = body?.selected_paths || projectItem?.data?.selected_paths || []
|
|
1529
|
+
const fileTree = (projectItem?.data?.file_tree as FileTreeNode) || null
|
|
1530
|
+
|
|
1531
|
+
|
|
1532
|
+
|
|
1533
|
+
let stableList: any[]
|
|
1534
|
+
if (chunkIds?.length) {
|
|
1535
|
+
let q = adminDb
|
|
1536
|
+
.from('items')
|
|
1537
|
+
.select('id, title, data')
|
|
1538
|
+
.filter('data->>kb_type', 'eq', 'cil_chunk')
|
|
1539
|
+
.filter('data->>project_id', 'eq', projectId)
|
|
1540
|
+
.eq('is_active', true)
|
|
1541
|
+
.in('id', chunkIds)
|
|
1542
|
+
.order('id')
|
|
1543
|
+
if (filePath) q = q.filter('data->>file_path', 'eq', filePath)
|
|
1544
|
+
const { data, error } = await q
|
|
1545
|
+
if (error) throw new Error(`Failed to load chunks: ${error.message}`)
|
|
1546
|
+
stableList = data || []
|
|
1547
|
+
} else if (selectedPaths.length > 0 && !filePath) {
|
|
1548
|
+
|
|
1549
|
+
stableList = await loadPendingChunks(projectId, selectedPaths, 'pass2_complete')
|
|
1550
|
+
} else {
|
|
1551
|
+
stableList = await loadAllChunks(projectId, filePath)
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
const totalChunks = stableList.length
|
|
1555
|
+
const pageChunks = stableList.slice(pageOffset, pageOffset + pageLimit)
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
const allToDocument = force ? pageChunks : pageChunks.filter(needsDocumentation)
|
|
1559
|
+
|
|
1560
|
+
const totalToDocument = force
|
|
1561
|
+
? stableList.length
|
|
1562
|
+
: stableList.filter(needsDocumentation).length
|
|
1563
|
+
|
|
1564
|
+
if (dryRun) {
|
|
1565
|
+
return {
|
|
1566
|
+
dry_run: true,
|
|
1567
|
+
project_id: projectId,
|
|
1568
|
+
model,
|
|
1569
|
+
total_to_document: totalToDocument,
|
|
1570
|
+
page_offset: pageOffset,
|
|
1571
|
+
page_limit: pageLimit,
|
|
1572
|
+
page_chunks: pageChunks.length,
|
|
1573
|
+
chunk_names: pageChunks.map(c => c.data?.chunk_name || c.title),
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
const results: Array<{ chunk: any; fields: Record<string, string> | null; is_fallback?: boolean; error?: string }> = []
|
|
1580
|
+
|
|
1581
|
+
for (let i = 0; i < allToDocument.length; i += concurrency) {
|
|
1582
|
+
const subBatch = allToDocument.slice(i, i + concurrency)
|
|
1583
|
+
const subResults = await Promise.all(subBatch.map(async chunk => {
|
|
1584
|
+
const d = chunk.data || {}
|
|
1585
|
+
if (!d.code_content && !d.chunk_name) {
|
|
1586
|
+
return { chunk, fields: null, error: 'No code content' }
|
|
1587
|
+
}
|
|
1588
|
+
const prompt = buildDocPrompt(chunk)
|
|
1589
|
+
try {
|
|
1590
|
+
const raw = await callLLM(prompt, model)
|
|
1591
|
+
const rawFields = parseDocResponse(raw)
|
|
1592
|
+
const hadLlmFields = hasMeaningfulLlmFields(rawFields)
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
const fields = normalizeDocFields(rawFields, chunk)
|
|
1596
|
+
return { chunk, fields, is_fallback: !hadLlmFields, error: undefined }
|
|
1597
|
+
} catch (err) {
|
|
1598
|
+
|
|
1599
|
+
const fields = normalizeDocFields({}, chunk)
|
|
1600
|
+
return { chunk, fields, is_fallback: true, error: undefined }
|
|
1601
|
+
}
|
|
1602
|
+
}))
|
|
1603
|
+
results.push(...subResults)
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
|
|
1607
|
+
let documented = 0, validated = 0, skipped = 0, failed = 0
|
|
1608
|
+
const errors: string[] = []
|
|
1609
|
+
const updatedChunks: any[] = []
|
|
1610
|
+
|
|
1611
|
+
await Promise.all(results.map(async ({ chunk, fields, is_fallback, error: llmError }) => {
|
|
1612
|
+
if (!fields) {
|
|
1613
|
+
if (llmError) { failed++; errors.push(`${chunk.data?.chunk_name || chunk.id}: ${llmError}`) }
|
|
1614
|
+
else skipped++
|
|
1615
|
+
return
|
|
1616
|
+
}
|
|
1617
|
+
const d = chunk.data || {}
|
|
1618
|
+
const toWrite: Record<string, string> = {}
|
|
1619
|
+
for (const [k, v] of Object.entries(fields)) {
|
|
1620
|
+
if (force || !d[k]) toWrite[k] = v
|
|
1621
|
+
}
|
|
1622
|
+
if (!Object.keys(toWrite).length) { skipped++; return }
|
|
1623
|
+
|
|
1624
|
+
const updatedData = { ...d, ...toWrite, doc_confidence: 'ai_generated', doc_fallback: !!is_fallback }
|
|
1625
|
+
const updatedChunk = { ...chunk, data: updatedData }
|
|
1626
|
+
|
|
1627
|
+
|
|
1628
|
+
const validationErrors = validateChunkDocs(updatedChunk)
|
|
1629
|
+
const chunkUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: chunk.id } }
|
|
1630
|
+
if (validationErrors.length > 0) {
|
|
1631
|
+
failed++
|
|
1632
|
+
errors.push(`${chunk.data?.chunk_name || chunk.id}: ${validationErrors.join(', ')}`)
|
|
1633
|
+
await adminUpdate(chunkUpdateCtx, { data: { ...updatedData, doc_validation_errors: validationErrors } })
|
|
1634
|
+
.catch(() => { /* non-fatal — don't mask original validation error */ })
|
|
1635
|
+
return
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
try {
|
|
1639
|
+
await adminUpdate(chunkUpdateCtx, { data: updatedData })
|
|
1640
|
+
} catch (updateError: any) {
|
|
1641
|
+
failed++; errors.push(`${chunk.data?.chunk_name || chunk.id}: ${updateError.message}`)
|
|
1642
|
+
return
|
|
1643
|
+
}
|
|
1644
|
+
{
|
|
1645
|
+
documented++; validated++; updatedChunks.push(updatedChunk)
|
|
1646
|
+
}
|
|
1647
|
+
}))
|
|
1648
|
+
|
|
1649
|
+
|
|
1650
|
+
|
|
1651
|
+
if (updatedChunks.length > 0) {
|
|
1652
|
+
const { data: projectItem } = await adminDb.from('items').select('id, data').eq('id', projectId).maybeSingle()
|
|
1653
|
+
const repoPath = projectItem?.data?.repo_path || ''
|
|
1654
|
+
if (repoPath) {
|
|
1655
|
+
const byFile = new Map<string, any[]>()
|
|
1656
|
+
for (const chunk of updatedChunks) {
|
|
1657
|
+
const relPath = chunk.data?.file_path
|
|
1658
|
+
if (!relPath) continue
|
|
1659
|
+
if (!byFile.has(relPath)) byFile.set(relPath, [])
|
|
1660
|
+
byFile.get(relPath)!.push(chunk)
|
|
1661
|
+
}
|
|
1662
|
+
for (const [relPath, chunks] of byFile) {
|
|
1663
|
+
const absPath = path.join(repoPath, relPath)
|
|
1664
|
+
if (!fs.existsSync(absPath)) continue
|
|
1665
|
+
const content = fs.readFileSync(absPath, 'utf-8')
|
|
1666
|
+
const fileLines = content.split('\n')
|
|
1667
|
+
const newLines = [...fileLines]
|
|
1668
|
+
|
|
1669
|
+
|
|
1670
|
+
|
|
1671
|
+
const markerMap = findChunkStartMarkers(newLines)
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
const sorted = [...chunks]
|
|
1675
|
+
.map(c => ({ chunk: c, markerIdx: markerMap.get((c.data?.chunk_name || c.title).trim().toLowerCase()) }))
|
|
1676
|
+
.filter((item): item is { chunk: any; markerIdx: number } => item.markerIdx !== undefined)
|
|
1677
|
+
.sort((a, b) => b.markerIdx - a.markerIdx)
|
|
1678
|
+
const missed = chunks
|
|
1679
|
+
.filter(c => markerMap.get((c.data?.chunk_name || c.title).trim().toLowerCase()) === undefined)
|
|
1680
|
+
.map(c => c.data?.chunk_name || c.title)
|
|
1681
|
+
if (missed.length > 0) {
|
|
1682
|
+
errors.push(`Write-back: could not find markers for ${missed.join(', ')} in ${relPath}`)
|
|
1683
|
+
}
|
|
1684
|
+
for (const { chunk, markerIdx } of sorted) {
|
|
1685
|
+
const jsDoc = buildJsDoc(chunk)
|
|
1686
|
+
if (!jsDoc) {
|
|
1687
|
+
errors.push(`Write-back: no JSDoc built for ${chunk.data?.chunk_name || chunk.title}`)
|
|
1688
|
+
continue
|
|
1689
|
+
}
|
|
1690
|
+
const existing = findExistingCilJsDoc(newLines, markerIdx)
|
|
1691
|
+
if (existing) {
|
|
1692
|
+
newLines.splice(existing.start, existing.end - existing.start + 1, jsDoc)
|
|
1693
|
+
} else {
|
|
1694
|
+
|
|
1695
|
+
newLines.splice(markerIdx + 1, 0, jsDoc)
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
fs.writeFileSync(absPath, newLines.join('\n'), 'utf-8')
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
const affectedFileIds = [...new Set((force ? pageChunks : allToDocument).map(c => c.data?.file_id).filter(Boolean))]
|
|
1705
|
+
for (const fileId of affectedFileIds) {
|
|
1706
|
+
await maybeAdvanceFileToPass3(ctx, fileId, fileTree)
|
|
1707
|
+
}
|
|
1708
|
+
if (fileTree) {
|
|
1709
|
+
await saveProjectTree(ctx, projectId, fileTree, { last_ingested_at: new Date().toISOString() })
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
|
|
1713
|
+
const nextOffset = pageOffset + pageLimit
|
|
1714
|
+
const isLastPage = nextOffset >= totalChunks
|
|
1715
|
+
if (isLastPage && documented > 0) {
|
|
1716
|
+
const { data: projectItem } = await adminDb.from('items').select('id, data').eq('id', projectId).maybeSingle()
|
|
1717
|
+
if (projectItem) {
|
|
1718
|
+
const prices = MODEL_PRICES[model] || MODEL_PRICES[DEFAULT_MODEL]
|
|
1719
|
+
const approxCost = (documented * (ESTIMATED_OUTPUT_TOKENS_PER_CHUNK + 800) / 1_000_000) * ((prices.input_per_1m + prices.output_per_1m) / 2)
|
|
1720
|
+
const projUpdateCtx = { ...ctx, query: { ...ctx.query, entity: 'items', id: projectId } }
|
|
1721
|
+
await adminUpdate(projUpdateCtx, {
|
|
1722
|
+
data: { ...projectItem.data, total_ingestion_cost_usd: (projectItem.data?.total_ingestion_cost_usd || 0) + approxCost, last_ingested_at: new Date().toISOString() },
|
|
1723
|
+
}).catch(() => { /* non-fatal */ })
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
return {
|
|
1728
|
+
project_id: projectId,
|
|
1729
|
+
model,
|
|
1730
|
+
total_to_document: totalToDocument,
|
|
1731
|
+
total_chunks: totalChunks,
|
|
1732
|
+
page_offset: pageOffset,
|
|
1733
|
+
page_limit: pageLimit,
|
|
1734
|
+
documented,
|
|
1735
|
+
validated,
|
|
1736
|
+
skipped,
|
|
1737
|
+
failed,
|
|
1738
|
+
errors: errors.slice(0, 20),
|
|
1739
|
+
|
|
1740
|
+
has_more: nextOffset < totalChunks,
|
|
1741
|
+
next_offset: nextOffset < totalChunks ? nextOffset : null,
|
|
1742
|
+
done_total: pageOffset + pageChunks.length,
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
throw new Error(`Unknown action: ${action}. Valid: estimate, gap_report, document, doc_chunk, validate`)
|
|
1747
|
+
})
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
// CIL[END chunk_id="custom_apps_cortex_functions_custom_cil_doc_handler_1784235266"]
|