@soleri/core 2.1.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brain/brain.d.ts +10 -1
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +116 -13
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/intelligence.d.ts +36 -1
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +119 -14
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/types.d.ts +34 -2
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/cognee/client.d.ts +3 -0
- package/dist/cognee/client.d.ts.map +1 -1
- package/dist/cognee/client.js +17 -0
- package/dist/cognee/client.js.map +1 -1
- package/dist/cognee/sync-manager.d.ts +94 -0
- package/dist/cognee/sync-manager.d.ts.map +1 -0
- package/dist/cognee/sync-manager.js +293 -0
- package/dist/cognee/sync-manager.js.map +1 -0
- package/dist/control/identity-manager.d.ts +22 -0
- package/dist/control/identity-manager.d.ts.map +1 -0
- package/dist/control/identity-manager.js +233 -0
- package/dist/control/identity-manager.js.map +1 -0
- package/dist/control/intent-router.d.ts +32 -0
- package/dist/control/intent-router.d.ts.map +1 -0
- package/dist/control/intent-router.js +242 -0
- package/dist/control/intent-router.js.map +1 -0
- package/dist/control/types.d.ts +68 -0
- package/dist/control/types.d.ts.map +1 -0
- package/dist/control/types.js +9 -0
- package/dist/control/types.js.map +1 -0
- package/dist/curator/curator.d.ts +37 -1
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +199 -1
- package/dist/curator/curator.js.map +1 -1
- package/dist/errors/classify.d.ts +13 -0
- package/dist/errors/classify.d.ts.map +1 -0
- package/dist/errors/classify.js +97 -0
- package/dist/errors/classify.js.map +1 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +4 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/retry.d.ts +40 -0
- package/dist/errors/retry.d.ts.map +1 -0
- package/dist/errors/retry.js +97 -0
- package/dist/errors/retry.js.map +1 -0
- package/dist/errors/types.d.ts +48 -0
- package/dist/errors/types.d.ts.map +1 -0
- package/dist/errors/types.js +59 -0
- package/dist/errors/types.js.map +1 -0
- package/dist/facades/types.d.ts +1 -1
- package/dist/governance/governance.d.ts +42 -0
- package/dist/governance/governance.d.ts.map +1 -0
- package/dist/governance/governance.js +488 -0
- package/dist/governance/governance.js.map +1 -0
- package/dist/governance/index.d.ts +3 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +2 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/types.d.ts +102 -0
- package/dist/governance/types.d.ts.map +1 -0
- package/dist/governance/types.js +3 -0
- package/dist/governance/types.js.map +1 -0
- package/dist/index.d.ts +52 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -1
- package/dist/index.js.map +1 -1
- package/dist/intake/content-classifier.d.ts +14 -0
- package/dist/intake/content-classifier.d.ts.map +1 -0
- package/dist/intake/content-classifier.js +125 -0
- package/dist/intake/content-classifier.js.map +1 -0
- package/dist/intake/dedup-gate.d.ts +17 -0
- package/dist/intake/dedup-gate.d.ts.map +1 -0
- package/dist/intake/dedup-gate.js +66 -0
- package/dist/intake/dedup-gate.js.map +1 -0
- package/dist/intake/intake-pipeline.d.ts +63 -0
- package/dist/intake/intake-pipeline.d.ts.map +1 -0
- package/dist/intake/intake-pipeline.js +373 -0
- package/dist/intake/intake-pipeline.js.map +1 -0
- package/dist/intake/types.d.ts +65 -0
- package/dist/intake/types.d.ts.map +1 -0
- package/dist/intake/types.js +3 -0
- package/dist/intake/types.js.map +1 -0
- package/dist/intelligence/loader.js +1 -1
- package/dist/intelligence/loader.js.map +1 -1
- package/dist/intelligence/types.d.ts +3 -1
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/logging/logger.d.ts +37 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +145 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/types.d.ts +19 -0
- package/dist/logging/types.d.ts.map +1 -0
- package/dist/logging/types.js +2 -0
- package/dist/logging/types.js.map +1 -0
- package/dist/loop/loop-manager.d.ts +100 -0
- package/dist/loop/loop-manager.d.ts.map +1 -0
- package/dist/loop/loop-manager.js +379 -0
- package/dist/loop/loop-manager.js.map +1 -0
- package/dist/loop/types.d.ts +103 -0
- package/dist/loop/types.d.ts.map +1 -0
- package/dist/loop/types.js +11 -0
- package/dist/loop/types.js.map +1 -0
- package/dist/persistence/index.d.ts +3 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +2 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/sqlite-provider.d.ts +25 -0
- package/dist/persistence/sqlite-provider.d.ts.map +1 -0
- package/dist/persistence/sqlite-provider.js +59 -0
- package/dist/persistence/sqlite-provider.js.map +1 -0
- package/dist/persistence/types.d.ts +36 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +8 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/planning/gap-analysis.d.ts +72 -0
- package/dist/planning/gap-analysis.d.ts.map +1 -0
- package/dist/planning/gap-analysis.js +442 -0
- package/dist/planning/gap-analysis.js.map +1 -0
- package/dist/planning/gap-types.d.ts +29 -0
- package/dist/planning/gap-types.d.ts.map +1 -0
- package/dist/planning/gap-types.js +28 -0
- package/dist/planning/gap-types.js.map +1 -0
- package/dist/planning/planner.d.ts +421 -4
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +949 -21
- package/dist/planning/planner.js.map +1 -1
- package/dist/playbooks/generic/brainstorming.d.ts +9 -0
- package/dist/playbooks/generic/brainstorming.d.ts.map +1 -0
- package/dist/playbooks/generic/brainstorming.js +105 -0
- package/dist/playbooks/generic/brainstorming.js.map +1 -0
- package/dist/playbooks/generic/code-review.d.ts +11 -0
- package/dist/playbooks/generic/code-review.d.ts.map +1 -0
- package/dist/playbooks/generic/code-review.js +176 -0
- package/dist/playbooks/generic/code-review.js.map +1 -0
- package/dist/playbooks/generic/subagent-execution.d.ts +9 -0
- package/dist/playbooks/generic/subagent-execution.d.ts.map +1 -0
- package/dist/playbooks/generic/subagent-execution.js +68 -0
- package/dist/playbooks/generic/subagent-execution.js.map +1 -0
- package/dist/playbooks/generic/systematic-debugging.d.ts +9 -0
- package/dist/playbooks/generic/systematic-debugging.d.ts.map +1 -0
- package/dist/playbooks/generic/systematic-debugging.js +87 -0
- package/dist/playbooks/generic/systematic-debugging.js.map +1 -0
- package/dist/playbooks/generic/tdd.d.ts +9 -0
- package/dist/playbooks/generic/tdd.d.ts.map +1 -0
- package/dist/playbooks/generic/tdd.js +70 -0
- package/dist/playbooks/generic/tdd.js.map +1 -0
- package/dist/playbooks/generic/verification.d.ts +9 -0
- package/dist/playbooks/generic/verification.d.ts.map +1 -0
- package/dist/playbooks/generic/verification.js +74 -0
- package/dist/playbooks/generic/verification.js.map +1 -0
- package/dist/playbooks/index.d.ts +4 -0
- package/dist/playbooks/index.d.ts.map +1 -0
- package/dist/playbooks/index.js +5 -0
- package/dist/playbooks/index.js.map +1 -0
- package/dist/playbooks/playbook-registry.d.ts +42 -0
- package/dist/playbooks/playbook-registry.d.ts.map +1 -0
- package/dist/playbooks/playbook-registry.js +227 -0
- package/dist/playbooks/playbook-registry.js.map +1 -0
- package/dist/playbooks/playbook-seeder.d.ts +47 -0
- package/dist/playbooks/playbook-seeder.d.ts.map +1 -0
- package/dist/playbooks/playbook-seeder.js +104 -0
- package/dist/playbooks/playbook-seeder.js.map +1 -0
- package/dist/playbooks/playbook-types.d.ts +132 -0
- package/dist/playbooks/playbook-types.d.ts.map +1 -0
- package/dist/playbooks/playbook-types.js +12 -0
- package/dist/playbooks/playbook-types.js.map +1 -0
- package/dist/project/project-registry.d.ts +79 -0
- package/dist/project/project-registry.d.ts.map +1 -0
- package/dist/project/project-registry.js +274 -0
- package/dist/project/project-registry.js.map +1 -0
- package/dist/project/types.d.ts +28 -0
- package/dist/project/types.d.ts.map +1 -0
- package/dist/project/types.js +5 -0
- package/dist/project/types.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +3 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/parser.d.ts +17 -0
- package/dist/prompts/parser.d.ts.map +1 -0
- package/dist/prompts/parser.js +47 -0
- package/dist/prompts/parser.js.map +1 -0
- package/dist/prompts/template-manager.d.ts +25 -0
- package/dist/prompts/template-manager.d.ts.map +1 -0
- package/dist/prompts/template-manager.js +71 -0
- package/dist/prompts/template-manager.js.map +1 -0
- package/dist/prompts/types.d.ts +26 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +5 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/runtime/admin-extra-ops.d.ts +15 -0
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -0
- package/dist/runtime/admin-extra-ops.js +595 -0
- package/dist/runtime/admin-extra-ops.js.map +1 -0
- package/dist/runtime/admin-ops.d.ts +15 -0
- package/dist/runtime/admin-ops.d.ts.map +1 -0
- package/dist/runtime/admin-ops.js +329 -0
- package/dist/runtime/admin-ops.js.map +1 -0
- package/dist/runtime/capture-ops.d.ts +15 -0
- package/dist/runtime/capture-ops.d.ts.map +1 -0
- package/dist/runtime/capture-ops.js +363 -0
- package/dist/runtime/capture-ops.js.map +1 -0
- package/dist/runtime/cognee-sync-ops.d.ts +12 -0
- package/dist/runtime/cognee-sync-ops.d.ts.map +1 -0
- package/dist/runtime/cognee-sync-ops.js +55 -0
- package/dist/runtime/cognee-sync-ops.js.map +1 -0
- package/dist/runtime/core-ops.d.ts +9 -3
- package/dist/runtime/core-ops.d.ts.map +1 -1
- package/dist/runtime/core-ops.js +693 -10
- package/dist/runtime/core-ops.js.map +1 -1
- package/dist/runtime/curator-extra-ops.d.ts +9 -0
- package/dist/runtime/curator-extra-ops.d.ts.map +1 -0
- package/dist/runtime/curator-extra-ops.js +71 -0
- package/dist/runtime/curator-extra-ops.js.map +1 -0
- package/dist/runtime/domain-ops.d.ts.map +1 -1
- package/dist/runtime/domain-ops.js +61 -15
- package/dist/runtime/domain-ops.js.map +1 -1
- package/dist/runtime/grading-ops.d.ts +14 -0
- package/dist/runtime/grading-ops.d.ts.map +1 -0
- package/dist/runtime/grading-ops.js +105 -0
- package/dist/runtime/grading-ops.js.map +1 -0
- package/dist/runtime/intake-ops.d.ts +14 -0
- package/dist/runtime/intake-ops.d.ts.map +1 -0
- package/dist/runtime/intake-ops.js +110 -0
- package/dist/runtime/intake-ops.js.map +1 -0
- package/dist/runtime/loop-ops.d.ts +14 -0
- package/dist/runtime/loop-ops.d.ts.map +1 -0
- package/dist/runtime/loop-ops.js +251 -0
- package/dist/runtime/loop-ops.js.map +1 -0
- package/dist/runtime/memory-cross-project-ops.d.ts +12 -0
- package/dist/runtime/memory-cross-project-ops.d.ts.map +1 -0
- package/dist/runtime/memory-cross-project-ops.js +165 -0
- package/dist/runtime/memory-cross-project-ops.js.map +1 -0
- package/dist/runtime/memory-extra-ops.d.ts +13 -0
- package/dist/runtime/memory-extra-ops.d.ts.map +1 -0
- package/dist/runtime/memory-extra-ops.js +173 -0
- package/dist/runtime/memory-extra-ops.js.map +1 -0
- package/dist/runtime/orchestrate-ops.d.ts +17 -0
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -0
- package/dist/runtime/orchestrate-ops.js +246 -0
- package/dist/runtime/orchestrate-ops.js.map +1 -0
- package/dist/runtime/planning-extra-ops.d.ts +25 -0
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -0
- package/dist/runtime/planning-extra-ops.js +663 -0
- package/dist/runtime/planning-extra-ops.js.map +1 -0
- package/dist/runtime/playbook-ops.d.ts +14 -0
- package/dist/runtime/playbook-ops.d.ts.map +1 -0
- package/dist/runtime/playbook-ops.js +141 -0
- package/dist/runtime/playbook-ops.js.map +1 -0
- package/dist/runtime/project-ops.d.ts +15 -0
- package/dist/runtime/project-ops.d.ts.map +1 -0
- package/dist/runtime/project-ops.js +186 -0
- package/dist/runtime/project-ops.js.map +1 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +65 -3
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +29 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.d.ts +10 -0
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -0
- package/dist/runtime/vault-extra-ops.js +536 -0
- package/dist/runtime/vault-extra-ops.js.map +1 -0
- package/dist/telemetry/telemetry.d.ts +48 -0
- package/dist/telemetry/telemetry.d.ts.map +1 -0
- package/dist/telemetry/telemetry.js +87 -0
- package/dist/telemetry/telemetry.js.map +1 -0
- package/dist/vault/playbook.d.ts +34 -0
- package/dist/vault/playbook.d.ts.map +1 -0
- package/dist/vault/playbook.js +60 -0
- package/dist/vault/playbook.js.map +1 -0
- package/dist/vault/vault.d.ts +97 -4
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +424 -65
- package/dist/vault/vault.js.map +1 -1
- package/package.json +7 -3
- package/src/__tests__/admin-extra-ops.test.ts +467 -0
- package/src/__tests__/admin-ops.test.ts +271 -0
- package/src/__tests__/brain-intelligence.test.ts +205 -0
- package/src/__tests__/brain.test.ts +134 -3
- package/src/__tests__/capture-ops.test.ts +509 -0
- package/src/__tests__/cognee-integration.test.ts +80 -0
- package/src/__tests__/cognee-sync-manager.test.ts +103 -0
- package/src/__tests__/core-ops.test.ts +292 -2
- package/src/__tests__/curator-extra-ops.test.ts +381 -0
- package/src/__tests__/domain-ops.test.ts +66 -0
- package/src/__tests__/errors.test.ts +388 -0
- package/src/__tests__/governance.test.ts +522 -0
- package/src/__tests__/grading-ops.test.ts +361 -0
- package/src/__tests__/identity-manager.test.ts +243 -0
- package/src/__tests__/intake-pipeline.test.ts +162 -0
- package/src/__tests__/intent-router.test.ts +222 -0
- package/src/__tests__/logger.test.ts +200 -0
- package/src/__tests__/loop-ops.test.ts +469 -0
- package/src/__tests__/memory-cross-project-ops.test.ts +248 -0
- package/src/__tests__/memory-extra-ops.test.ts +352 -0
- package/src/__tests__/orchestrate-ops.test.ts +289 -0
- package/src/__tests__/persistence.test.ts +225 -0
- package/src/__tests__/planner.test.ts +416 -7
- package/src/__tests__/planning-extra-ops.test.ts +706 -0
- package/src/__tests__/playbook-registry.test.ts +326 -0
- package/src/__tests__/playbook-seeder.test.ts +163 -0
- package/src/__tests__/playbook.test.ts +389 -0
- package/src/__tests__/project-ops.test.ts +381 -0
- package/src/__tests__/template-manager.test.ts +222 -0
- package/src/__tests__/vault-extra-ops.test.ts +482 -0
- package/src/brain/brain.ts +185 -16
- package/src/brain/intelligence.ts +179 -10
- package/src/brain/types.ts +40 -2
- package/src/cognee/client.ts +18 -0
- package/src/cognee/sync-manager.ts +389 -0
- package/src/control/identity-manager.ts +354 -0
- package/src/control/intent-router.ts +326 -0
- package/src/control/types.ts +102 -0
- package/src/curator/curator.ts +295 -1
- package/src/errors/classify.ts +102 -0
- package/src/errors/index.ts +5 -0
- package/src/errors/retry.ts +132 -0
- package/src/errors/types.ts +81 -0
- package/src/governance/governance.ts +698 -0
- package/src/governance/index.ts +18 -0
- package/src/governance/types.ts +111 -0
- package/src/index.ts +213 -2
- package/src/intake/content-classifier.ts +146 -0
- package/src/intake/dedup-gate.ts +92 -0
- package/src/intake/intake-pipeline.ts +503 -0
- package/src/intake/types.ts +69 -0
- package/src/intelligence/loader.ts +1 -1
- package/src/intelligence/types.ts +3 -1
- package/src/logging/logger.ts +154 -0
- package/src/logging/types.ts +21 -0
- package/src/loop/loop-manager.ts +448 -0
- package/src/loop/types.ts +115 -0
- package/src/persistence/index.ts +7 -0
- package/src/persistence/sqlite-provider.ts +62 -0
- package/src/persistence/types.ts +44 -0
- package/src/planning/gap-analysis.ts +775 -0
- package/src/planning/gap-types.ts +61 -0
- package/src/planning/planner.ts +1273 -24
- package/src/playbooks/generic/brainstorming.ts +110 -0
- package/src/playbooks/generic/code-review.ts +181 -0
- package/src/playbooks/generic/subagent-execution.ts +74 -0
- package/src/playbooks/generic/systematic-debugging.ts +92 -0
- package/src/playbooks/generic/tdd.ts +75 -0
- package/src/playbooks/generic/verification.ts +79 -0
- package/src/playbooks/index.ts +27 -0
- package/src/playbooks/playbook-registry.ts +284 -0
- package/src/playbooks/playbook-seeder.ts +119 -0
- package/src/playbooks/playbook-types.ts +162 -0
- package/src/project/project-registry.ts +370 -0
- package/src/project/types.ts +31 -0
- package/src/prompts/index.ts +3 -0
- package/src/prompts/parser.ts +59 -0
- package/src/prompts/template-manager.ts +77 -0
- package/src/prompts/types.ts +28 -0
- package/src/runtime/admin-extra-ops.ts +652 -0
- package/src/runtime/admin-ops.ts +340 -0
- package/src/runtime/capture-ops.ts +404 -0
- package/src/runtime/cognee-sync-ops.ts +63 -0
- package/src/runtime/core-ops.ts +787 -9
- package/src/runtime/curator-extra-ops.ts +85 -0
- package/src/runtime/domain-ops.ts +67 -15
- package/src/runtime/grading-ops.ts +130 -0
- package/src/runtime/intake-ops.ts +126 -0
- package/src/runtime/loop-ops.ts +277 -0
- package/src/runtime/memory-cross-project-ops.ts +191 -0
- package/src/runtime/memory-extra-ops.ts +186 -0
- package/src/runtime/orchestrate-ops.ts +278 -0
- package/src/runtime/planning-extra-ops.ts +718 -0
- package/src/runtime/playbook-ops.ts +169 -0
- package/src/runtime/project-ops.ts +202 -0
- package/src/runtime/runtime.ts +77 -3
- package/src/runtime/types.ts +29 -0
- package/src/runtime/vault-extra-ops.ts +606 -0
- package/src/telemetry/telemetry.ts +118 -0
- package/src/vault/playbook.ts +87 -0
- package/src/vault/vault.ts +575 -98
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Registry — SQLite-backed registry for tracking projects,
|
|
3
|
+
* rules, and cross-project links.
|
|
4
|
+
*
|
|
5
|
+
* Uses the Vault's underlying SQLite database via `vault.getDb()`.
|
|
6
|
+
* Tables are created lazily on first access.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type Database from 'better-sqlite3';
|
|
10
|
+
import type { RegisteredProject, ProjectRule, ProjectLink, LinkType } from './types.js';
|
|
11
|
+
|
|
12
|
+
/** Row shape for the projects table. */
|
|
13
|
+
interface ProjectRow {
|
|
14
|
+
id: string;
|
|
15
|
+
path: string;
|
|
16
|
+
name: string | null;
|
|
17
|
+
registered_at: number;
|
|
18
|
+
last_accessed_at: number;
|
|
19
|
+
metadata: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Row shape for the project_rules table. */
|
|
23
|
+
interface RuleRow {
|
|
24
|
+
id: string;
|
|
25
|
+
project_id: string;
|
|
26
|
+
category: string;
|
|
27
|
+
text: string;
|
|
28
|
+
priority: number;
|
|
29
|
+
created_at: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Row shape for the project_links table. */
|
|
33
|
+
interface LinkRow {
|
|
34
|
+
id: number;
|
|
35
|
+
source_project_id: string;
|
|
36
|
+
target_project_id: string;
|
|
37
|
+
link_type: string;
|
|
38
|
+
created_at: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate a deterministic project ID from a filesystem path.
|
|
43
|
+
*/
|
|
44
|
+
function pathToId(path: string): string {
|
|
45
|
+
return path
|
|
46
|
+
.replace(/[^a-z0-9]/gi, '-')
|
|
47
|
+
.toLowerCase()
|
|
48
|
+
.replace(/-+/g, '-')
|
|
49
|
+
.replace(/^-|-$/g, '');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function rowToProject(row: ProjectRow): RegisteredProject {
|
|
53
|
+
return {
|
|
54
|
+
id: row.id,
|
|
55
|
+
path: row.path,
|
|
56
|
+
name: row.name ?? undefined,
|
|
57
|
+
registeredAt: row.registered_at,
|
|
58
|
+
lastAccessedAt: row.last_accessed_at,
|
|
59
|
+
metadata: JSON.parse(row.metadata || '{}'),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function rowToRule(row: RuleRow): ProjectRule {
|
|
64
|
+
return {
|
|
65
|
+
id: row.id,
|
|
66
|
+
projectId: row.project_id,
|
|
67
|
+
category: row.category as ProjectRule['category'],
|
|
68
|
+
text: row.text,
|
|
69
|
+
priority: row.priority,
|
|
70
|
+
createdAt: row.created_at,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function rowToLink(row: LinkRow): ProjectLink {
|
|
75
|
+
return {
|
|
76
|
+
id: row.id,
|
|
77
|
+
sourceProjectId: row.source_project_id,
|
|
78
|
+
targetProjectId: row.target_project_id,
|
|
79
|
+
linkType: row.link_type as LinkType,
|
|
80
|
+
createdAt: row.created_at,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class ProjectRegistry {
|
|
85
|
+
private db: Database.Database;
|
|
86
|
+
|
|
87
|
+
constructor(db: Database.Database) {
|
|
88
|
+
this.db = db;
|
|
89
|
+
this.initTables();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private initTables(): void {
|
|
93
|
+
this.db.exec(`
|
|
94
|
+
CREATE TABLE IF NOT EXISTS registered_projects (
|
|
95
|
+
id TEXT PRIMARY KEY,
|
|
96
|
+
path TEXT UNIQUE NOT NULL,
|
|
97
|
+
name TEXT,
|
|
98
|
+
registered_at INTEGER NOT NULL,
|
|
99
|
+
last_accessed_at INTEGER NOT NULL,
|
|
100
|
+
metadata TEXT DEFAULT '{}'
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
CREATE TABLE IF NOT EXISTS project_rules (
|
|
104
|
+
id TEXT PRIMARY KEY,
|
|
105
|
+
project_id TEXT NOT NULL,
|
|
106
|
+
category TEXT NOT NULL,
|
|
107
|
+
text TEXT NOT NULL,
|
|
108
|
+
priority INTEGER DEFAULT 0,
|
|
109
|
+
created_at INTEGER NOT NULL,
|
|
110
|
+
FOREIGN KEY (project_id) REFERENCES registered_projects(id)
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
CREATE TABLE IF NOT EXISTS project_links (
|
|
114
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
115
|
+
source_project_id TEXT NOT NULL,
|
|
116
|
+
target_project_id TEXT NOT NULL,
|
|
117
|
+
link_type TEXT NOT NULL,
|
|
118
|
+
created_at INTEGER NOT NULL,
|
|
119
|
+
UNIQUE(source_project_id, target_project_id, link_type)
|
|
120
|
+
);
|
|
121
|
+
`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Register (upsert) a project. Updates lastAccessedAt on re-register.
|
|
126
|
+
*/
|
|
127
|
+
register(path: string, name?: string, metadata?: Record<string, unknown>): RegisteredProject {
|
|
128
|
+
const id = pathToId(path);
|
|
129
|
+
const now = Date.now();
|
|
130
|
+
|
|
131
|
+
const existing = this.db.prepare('SELECT * FROM registered_projects WHERE id = ?').get(id) as
|
|
132
|
+
| ProjectRow
|
|
133
|
+
| undefined;
|
|
134
|
+
|
|
135
|
+
if (existing) {
|
|
136
|
+
// Update lastAccessedAt, and optionally name/metadata if provided
|
|
137
|
+
const newName = name ?? existing.name;
|
|
138
|
+
const newMetadata = metadata ? JSON.stringify(metadata) : existing.metadata;
|
|
139
|
+
this.db
|
|
140
|
+
.prepare(
|
|
141
|
+
'UPDATE registered_projects SET last_accessed_at = ?, name = ?, metadata = ? WHERE id = ?',
|
|
142
|
+
)
|
|
143
|
+
.run(now, newName, newMetadata, id);
|
|
144
|
+
return rowToProject({
|
|
145
|
+
...existing,
|
|
146
|
+
last_accessed_at: now,
|
|
147
|
+
name: newName,
|
|
148
|
+
metadata: newMetadata,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const row: ProjectRow = {
|
|
153
|
+
id,
|
|
154
|
+
path,
|
|
155
|
+
name: name ?? null,
|
|
156
|
+
registered_at: now,
|
|
157
|
+
last_accessed_at: now,
|
|
158
|
+
metadata: JSON.stringify(metadata ?? {}),
|
|
159
|
+
};
|
|
160
|
+
this.db
|
|
161
|
+
.prepare(
|
|
162
|
+
'INSERT INTO registered_projects (id, path, name, registered_at, last_accessed_at, metadata) VALUES (?, ?, ?, ?, ?, ?)',
|
|
163
|
+
)
|
|
164
|
+
.run(row.id, row.path, row.name, row.registered_at, row.last_accessed_at, row.metadata);
|
|
165
|
+
|
|
166
|
+
return rowToProject(row);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get a project by ID.
|
|
171
|
+
*/
|
|
172
|
+
get(projectId: string): RegisteredProject | null {
|
|
173
|
+
const row = this.db.prepare('SELECT * FROM registered_projects WHERE id = ?').get(projectId) as
|
|
174
|
+
| ProjectRow
|
|
175
|
+
| undefined;
|
|
176
|
+
return row ? rowToProject(row) : null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Get a project by its filesystem path.
|
|
181
|
+
*/
|
|
182
|
+
getByPath(path: string): RegisteredProject | null {
|
|
183
|
+
const row = this.db.prepare('SELECT * FROM registered_projects WHERE path = ?').get(path) as
|
|
184
|
+
| ProjectRow
|
|
185
|
+
| undefined;
|
|
186
|
+
return row ? rowToProject(row) : null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* List all registered projects.
|
|
191
|
+
*/
|
|
192
|
+
list(): RegisteredProject[] {
|
|
193
|
+
const rows = this.db
|
|
194
|
+
.prepare('SELECT * FROM registered_projects ORDER BY last_accessed_at DESC')
|
|
195
|
+
.all() as ProjectRow[];
|
|
196
|
+
return rows.map(rowToProject);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Unregister a project by ID. Also removes associated rules and links.
|
|
201
|
+
*/
|
|
202
|
+
unregister(projectId: string): boolean {
|
|
203
|
+
const result = this.db.transaction(() => {
|
|
204
|
+
this.db.prepare('DELETE FROM project_rules WHERE project_id = ?').run(projectId);
|
|
205
|
+
this.db
|
|
206
|
+
.prepare('DELETE FROM project_links WHERE source_project_id = ? OR target_project_id = ?')
|
|
207
|
+
.run(projectId, projectId);
|
|
208
|
+
return (
|
|
209
|
+
this.db.prepare('DELETE FROM registered_projects WHERE id = ?').run(projectId).changes > 0
|
|
210
|
+
);
|
|
211
|
+
})();
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Update the lastAccessedAt timestamp for a project.
|
|
217
|
+
*/
|
|
218
|
+
touch(projectId: string): void {
|
|
219
|
+
this.db
|
|
220
|
+
.prepare('UPDATE registered_projects SET last_accessed_at = ? WHERE id = ?')
|
|
221
|
+
.run(Date.now(), projectId);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ─── Rules ──────────────────────────────────────────────────────────
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Add a rule to a project.
|
|
228
|
+
*/
|
|
229
|
+
addRule(
|
|
230
|
+
projectId: string,
|
|
231
|
+
rule: Omit<ProjectRule, 'id' | 'projectId' | 'createdAt'>,
|
|
232
|
+
): ProjectRule {
|
|
233
|
+
const id = `rule-${projectId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
234
|
+
const now = Date.now();
|
|
235
|
+
this.db
|
|
236
|
+
.prepare(
|
|
237
|
+
'INSERT INTO project_rules (id, project_id, category, text, priority, created_at) VALUES (?, ?, ?, ?, ?, ?)',
|
|
238
|
+
)
|
|
239
|
+
.run(id, projectId, rule.category, rule.text, rule.priority, now);
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
id,
|
|
243
|
+
projectId,
|
|
244
|
+
category: rule.category,
|
|
245
|
+
text: rule.text,
|
|
246
|
+
priority: rule.priority,
|
|
247
|
+
createdAt: now,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get all rules for a project.
|
|
253
|
+
*/
|
|
254
|
+
getRules(projectId: string): ProjectRule[] {
|
|
255
|
+
const rows = this.db
|
|
256
|
+
.prepare(
|
|
257
|
+
'SELECT * FROM project_rules WHERE project_id = ? ORDER BY priority DESC, created_at ASC',
|
|
258
|
+
)
|
|
259
|
+
.all(projectId) as RuleRow[];
|
|
260
|
+
return rows.map(rowToRule);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Remove a rule by ID.
|
|
265
|
+
*/
|
|
266
|
+
removeRule(ruleId: string): boolean {
|
|
267
|
+
return this.db.prepare('DELETE FROM project_rules WHERE id = ?').run(ruleId).changes > 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* List all projects with their rules.
|
|
272
|
+
*/
|
|
273
|
+
listRulesAll(): Array<{ project: RegisteredProject; rules: ProjectRule[] }> {
|
|
274
|
+
const projects = this.list();
|
|
275
|
+
return projects.map((project) => ({
|
|
276
|
+
project,
|
|
277
|
+
rules: this.getRules(project.id),
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// ─── Links ──────────────────────────────────────────────────────────
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Link two projects.
|
|
285
|
+
*/
|
|
286
|
+
link(sourceId: string, targetId: string, linkType: LinkType): ProjectLink {
|
|
287
|
+
const now = Date.now();
|
|
288
|
+
const info = this.db
|
|
289
|
+
.prepare(
|
|
290
|
+
'INSERT OR IGNORE INTO project_links (source_project_id, target_project_id, link_type, created_at) VALUES (?, ?, ?, ?)',
|
|
291
|
+
)
|
|
292
|
+
.run(sourceId, targetId, linkType, now);
|
|
293
|
+
|
|
294
|
+
// If insert was ignored (duplicate), fetch existing
|
|
295
|
+
if (info.changes === 0) {
|
|
296
|
+
const existing = this.db
|
|
297
|
+
.prepare(
|
|
298
|
+
'SELECT * FROM project_links WHERE source_project_id = ? AND target_project_id = ? AND link_type = ?',
|
|
299
|
+
)
|
|
300
|
+
.get(sourceId, targetId, linkType) as LinkRow;
|
|
301
|
+
return rowToLink(existing);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
id: Number(info.lastInsertRowid),
|
|
306
|
+
sourceProjectId: sourceId,
|
|
307
|
+
targetProjectId: targetId,
|
|
308
|
+
linkType,
|
|
309
|
+
createdAt: now,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Unlink two projects. If linkType is omitted, removes all links between them.
|
|
315
|
+
* Returns count of links removed.
|
|
316
|
+
*/
|
|
317
|
+
unlink(sourceId: string, targetId: string, linkType?: LinkType): number {
|
|
318
|
+
if (linkType) {
|
|
319
|
+
return this.db
|
|
320
|
+
.prepare(
|
|
321
|
+
'DELETE FROM project_links WHERE source_project_id = ? AND target_project_id = ? AND link_type = ?',
|
|
322
|
+
)
|
|
323
|
+
.run(sourceId, targetId, linkType).changes;
|
|
324
|
+
}
|
|
325
|
+
return this.db
|
|
326
|
+
.prepare('DELETE FROM project_links WHERE source_project_id = ? AND target_project_id = ?')
|
|
327
|
+
.run(sourceId, targetId).changes;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Get all links for a project (both outgoing and incoming).
|
|
332
|
+
*/
|
|
333
|
+
getLinks(projectId: string): ProjectLink[] {
|
|
334
|
+
const rows = this.db
|
|
335
|
+
.prepare(
|
|
336
|
+
'SELECT * FROM project_links WHERE source_project_id = ? OR target_project_id = ? ORDER BY created_at DESC',
|
|
337
|
+
)
|
|
338
|
+
.all(projectId, projectId) as LinkRow[];
|
|
339
|
+
return rows.map(rowToLink);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get linked projects with details — returns project info, link type, and direction.
|
|
344
|
+
*/
|
|
345
|
+
getLinkedProjects(
|
|
346
|
+
projectId: string,
|
|
347
|
+
): Array<{ project: RegisteredProject; linkType: LinkType; direction: 'outgoing' | 'incoming' }> {
|
|
348
|
+
const links = this.getLinks(projectId);
|
|
349
|
+
const results: Array<{
|
|
350
|
+
project: RegisteredProject;
|
|
351
|
+
linkType: LinkType;
|
|
352
|
+
direction: 'outgoing' | 'incoming';
|
|
353
|
+
}> = [];
|
|
354
|
+
|
|
355
|
+
for (const link of links) {
|
|
356
|
+
const isOutgoing = link.sourceProjectId === projectId;
|
|
357
|
+
const otherProjectId = isOutgoing ? link.targetProjectId : link.sourceProjectId;
|
|
358
|
+
const project = this.get(otherProjectId);
|
|
359
|
+
if (project) {
|
|
360
|
+
results.push({
|
|
361
|
+
project,
|
|
362
|
+
linkType: link.linkType,
|
|
363
|
+
direction: isOutgoing ? 'outgoing' : 'incoming',
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return results;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project registry types — tracks projects, rules, and cross-project links.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface RegisteredProject {
|
|
6
|
+
id: string;
|
|
7
|
+
path: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
registeredAt: number;
|
|
10
|
+
lastAccessedAt: number;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ProjectRule {
|
|
15
|
+
id: string;
|
|
16
|
+
projectId: string;
|
|
17
|
+
category: 'behavior' | 'preference' | 'restriction' | 'convention';
|
|
18
|
+
text: string;
|
|
19
|
+
priority: number;
|
|
20
|
+
createdAt: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type LinkType = 'related' | 'parent' | 'child' | 'fork';
|
|
24
|
+
|
|
25
|
+
export interface ProjectLink {
|
|
26
|
+
id: number;
|
|
27
|
+
sourceProjectId: string;
|
|
28
|
+
targetProjectId: string;
|
|
29
|
+
linkType: LinkType;
|
|
30
|
+
createdAt: number;
|
|
31
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template parser — extract variables and resolve includes.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { TemplateVariable } from './types.js';
|
|
6
|
+
|
|
7
|
+
const VAR_PATTERN = /\{\{(\w+)(?::([^}]*))?\}\}/g;
|
|
8
|
+
const INCLUDE_PATTERN = /@include\(([^)]+)\)/g;
|
|
9
|
+
const MAX_INCLUDE_DEPTH = 10;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Extract unique variables from template content.
|
|
13
|
+
* Supports {{name}} (required) and {{name:default}} (optional with default).
|
|
14
|
+
*/
|
|
15
|
+
export function parseVariables(content: string): TemplateVariable[] {
|
|
16
|
+
const seen = new Map<string, TemplateVariable>();
|
|
17
|
+
|
|
18
|
+
for (const match of content.matchAll(VAR_PATTERN)) {
|
|
19
|
+
const name = match[1];
|
|
20
|
+
const defaultValue = match[2];
|
|
21
|
+
if (!seen.has(name)) {
|
|
22
|
+
seen.set(name, {
|
|
23
|
+
name,
|
|
24
|
+
required: defaultValue === undefined,
|
|
25
|
+
defaultValue,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return Array.from(seen.values());
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Resolve @include(partial-name) directives.
|
|
35
|
+
*
|
|
36
|
+
* The loader function receives the partial name and returns its content.
|
|
37
|
+
* Cycle detection prevents infinite recursion.
|
|
38
|
+
*/
|
|
39
|
+
export function resolveIncludes(
|
|
40
|
+
content: string,
|
|
41
|
+
loader: (name: string) => string,
|
|
42
|
+
_stack: Set<string> = new Set(),
|
|
43
|
+
_depth: number = 0,
|
|
44
|
+
): string {
|
|
45
|
+
if (_depth > MAX_INCLUDE_DEPTH) {
|
|
46
|
+
throw new Error(`Include depth exceeded ${MAX_INCLUDE_DEPTH}. Possible circular include.`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return content.replace(INCLUDE_PATTERN, (_match, partialName: string) => {
|
|
50
|
+
const trimmed = partialName.trim();
|
|
51
|
+
if (_stack.has(trimmed)) {
|
|
52
|
+
throw new Error(`Circular include detected: ${trimmed} (stack: ${[..._stack].join(' → ')})`);
|
|
53
|
+
}
|
|
54
|
+
const newStack = new Set(_stack);
|
|
55
|
+
newStack.add(trimmed);
|
|
56
|
+
const partialContent = loader(trimmed);
|
|
57
|
+
return resolveIncludes(partialContent, loader, newStack, _depth + 1);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template manager — load, render, and list .prompt templates.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
6
|
+
import { join, basename } from 'node:path';
|
|
7
|
+
import type { PromptTemplate, RenderOptions } from './types.js';
|
|
8
|
+
import { parseVariables, resolveIncludes } from './parser.js';
|
|
9
|
+
|
|
10
|
+
const VAR_REGEX = /\{\{(\w+)(?::([^}]*))?\}\}/g;
|
|
11
|
+
|
|
12
|
+
export class TemplateManager {
|
|
13
|
+
private templates = new Map<string, PromptTemplate>();
|
|
14
|
+
private templatesDir: string;
|
|
15
|
+
|
|
16
|
+
constructor(templatesDir: string) {
|
|
17
|
+
this.templatesDir = templatesDir;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Load all .prompt files from templatesDir. */
|
|
21
|
+
load(): void {
|
|
22
|
+
if (!existsSync(this.templatesDir)) return;
|
|
23
|
+
|
|
24
|
+
const files = readdirSync(this.templatesDir).filter((f) => f.endsWith('.prompt'));
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
const fullPath = join(this.templatesDir, file);
|
|
27
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
28
|
+
const name = basename(file, '.prompt');
|
|
29
|
+
this.templates.set(name, {
|
|
30
|
+
name,
|
|
31
|
+
content,
|
|
32
|
+
variables: parseVariables(content),
|
|
33
|
+
path: fullPath,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Render a template by name with variable substitution.
|
|
40
|
+
*
|
|
41
|
+
* @param name - Template name (without .prompt extension)
|
|
42
|
+
* @param vars - Variable values to substitute
|
|
43
|
+
* @param options - Render options (strict mode)
|
|
44
|
+
* @throws If template not found, or strict mode and required variable missing
|
|
45
|
+
*/
|
|
46
|
+
render(name: string, vars: Record<string, string> = {}, options?: RenderOptions): string {
|
|
47
|
+
const template = this.templates.get(name);
|
|
48
|
+
if (!template) throw new Error(`Template not found: ${name}`);
|
|
49
|
+
|
|
50
|
+
const strict = options?.strict ?? true;
|
|
51
|
+
|
|
52
|
+
// Resolve @include() directives
|
|
53
|
+
const resolved = resolveIncludes(template.content, (partialName) => {
|
|
54
|
+
const partial = this.templates.get(partialName);
|
|
55
|
+
if (!partial) throw new Error(`Include not found: ${partialName} (in template: ${name})`);
|
|
56
|
+
return partial.content;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Replace {{var}} and {{var:default}}
|
|
60
|
+
return resolved.replace(VAR_REGEX, (_match, varName: string, defaultValue?: string) => {
|
|
61
|
+
if (vars[varName] !== undefined) return vars[varName];
|
|
62
|
+
if (defaultValue !== undefined) return defaultValue;
|
|
63
|
+
if (strict) throw new Error(`Missing required variable: ${varName} (in template: ${name})`);
|
|
64
|
+
return _match; // Leave placeholder as-is in non-strict mode
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** List all loaded template names. */
|
|
69
|
+
listTemplates(): string[] {
|
|
70
|
+
return Array.from(this.templates.keys());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Get a template by name (raw, unrendered). */
|
|
74
|
+
getTemplate(name: string): PromptTemplate | null {
|
|
75
|
+
return this.templates.get(name) ?? null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt template types.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface TemplateVariable {
|
|
6
|
+
/** Variable name, e.g. 'agentName' */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Whether the variable must be provided at render time. */
|
|
9
|
+
required: boolean;
|
|
10
|
+
/** Default value used when variable is not provided (makes required=false). */
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface PromptTemplate {
|
|
15
|
+
/** Template name (filename without .prompt extension). */
|
|
16
|
+
name: string;
|
|
17
|
+
/** Raw template content before variable substitution. */
|
|
18
|
+
content: string;
|
|
19
|
+
/** Variables extracted from the template. */
|
|
20
|
+
variables: TemplateVariable[];
|
|
21
|
+
/** Absolute file path. */
|
|
22
|
+
path: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface RenderOptions {
|
|
26
|
+
/** If true (default), throw on missing required variables. */
|
|
27
|
+
strict?: boolean;
|
|
28
|
+
}
|