thevoidforge 21.0.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/scripts/vault-read.d.ts +11 -0
- package/dist/scripts/vault-read.js +89 -0
- package/dist/scripts/voidforge.d.ts +20 -0
- package/dist/scripts/voidforge.js +404 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/wizard/api/auth.d.ts +5 -0
- package/dist/wizard/api/auth.js +133 -0
- package/dist/wizard/api/blueprint.d.ts +45 -0
- package/dist/wizard/api/blueprint.js +184 -0
- package/dist/wizard/api/cloud-providers.d.ts +16 -0
- package/dist/wizard/api/cloud-providers.js +363 -0
- package/dist/wizard/api/credentials.d.ts +1 -0
- package/dist/wizard/api/credentials.js +258 -0
- package/dist/wizard/api/danger-room.d.ts +18 -0
- package/dist/wizard/api/danger-room.js +401 -0
- package/dist/wizard/api/deploy.d.ts +4 -0
- package/dist/wizard/api/deploy.js +164 -0
- package/dist/wizard/api/prd.d.ts +1 -0
- package/dist/wizard/api/prd.js +363 -0
- package/dist/wizard/api/project.d.ts +1 -0
- package/dist/wizard/api/project.js +239 -0
- package/dist/wizard/api/projects.d.ts +6 -0
- package/dist/wizard/api/projects.js +648 -0
- package/dist/wizard/api/provision.d.ts +4 -0
- package/dist/wizard/api/provision.js +535 -0
- package/dist/wizard/api/terminal.d.ts +25 -0
- package/dist/wizard/api/terminal.js +241 -0
- package/dist/wizard/api/users.d.ts +6 -0
- package/dist/wizard/api/users.js +244 -0
- package/dist/wizard/api/war-room.d.ts +14 -0
- package/dist/wizard/api/war-room.js +45 -0
- package/dist/wizard/lib/ad-platform-core.d.ts +6 -0
- package/dist/wizard/lib/ad-platform-core.js +1 -0
- package/dist/wizard/lib/adapters/index.d.ts +52 -0
- package/dist/wizard/lib/adapters/index.js +38 -0
- package/dist/wizard/lib/adapters/sandbox-bank.d.ts +17 -0
- package/dist/wizard/lib/adapters/sandbox-bank.js +77 -0
- package/dist/wizard/lib/adapters/sandbox.d.ts +39 -0
- package/dist/wizard/lib/adapters/sandbox.js +174 -0
- package/dist/wizard/lib/adapters/stripe.d.ts +19 -0
- package/dist/wizard/lib/adapters/stripe.js +143 -0
- package/dist/wizard/lib/adapters/types.d.ts +9 -0
- package/dist/wizard/lib/adapters/types.js +10 -0
- package/dist/wizard/lib/agent-memory.d.ts +36 -0
- package/dist/wizard/lib/agent-memory.js +114 -0
- package/dist/wizard/lib/anomaly-detection.d.ts +59 -0
- package/dist/wizard/lib/anomaly-detection.js +122 -0
- package/dist/wizard/lib/anthropic.d.ts +21 -0
- package/dist/wizard/lib/anthropic.js +105 -0
- package/dist/wizard/lib/asset-scanner.d.ts +23 -0
- package/dist/wizard/lib/asset-scanner.js +107 -0
- package/dist/wizard/lib/audit-log.d.ts +23 -0
- package/dist/wizard/lib/audit-log.js +70 -0
- package/dist/wizard/lib/autonomy-controller.d.ts +76 -0
- package/dist/wizard/lib/autonomy-controller.js +183 -0
- package/dist/wizard/lib/body-parser.d.ts +2 -0
- package/dist/wizard/lib/body-parser.js +36 -0
- package/dist/wizard/lib/build-analytics.d.ts +39 -0
- package/dist/wizard/lib/build-analytics.js +91 -0
- package/dist/wizard/lib/build-step.d.ts +21 -0
- package/dist/wizard/lib/build-step.js +104 -0
- package/dist/wizard/lib/campaign-proposer.d.ts +39 -0
- package/dist/wizard/lib/campaign-proposer.js +180 -0
- package/dist/wizard/lib/campaign-state-machine.d.ts +63 -0
- package/dist/wizard/lib/campaign-state-machine.js +114 -0
- package/dist/wizard/lib/ci-generator.d.ts +14 -0
- package/dist/wizard/lib/ci-generator.js +187 -0
- package/dist/wizard/lib/claude-merge.d.ts +38 -0
- package/dist/wizard/lib/claude-merge.js +115 -0
- package/dist/wizard/lib/codegen/erd-gen.d.ts +16 -0
- package/dist/wizard/lib/codegen/erd-gen.js +98 -0
- package/dist/wizard/lib/codegen/integrations.d.ts +18 -0
- package/dist/wizard/lib/codegen/integrations.js +189 -0
- package/dist/wizard/lib/codegen/openapi-gen.d.ts +15 -0
- package/dist/wizard/lib/codegen/openapi-gen.js +79 -0
- package/dist/wizard/lib/codegen/prisma-types.d.ts +15 -0
- package/dist/wizard/lib/codegen/prisma-types.js +44 -0
- package/dist/wizard/lib/codegen/seed-gen.d.ts +16 -0
- package/dist/wizard/lib/codegen/seed-gen.js +128 -0
- package/dist/wizard/lib/compliance.d.ts +51 -0
- package/dist/wizard/lib/compliance.js +112 -0
- package/dist/wizard/lib/correlation-engine.d.ts +59 -0
- package/dist/wizard/lib/correlation-engine.js +151 -0
- package/dist/wizard/lib/cost-estimator.d.ts +22 -0
- package/dist/wizard/lib/cost-estimator.js +72 -0
- package/dist/wizard/lib/cost-tracker.d.ts +27 -0
- package/dist/wizard/lib/cost-tracker.js +37 -0
- package/dist/wizard/lib/daemon-aggregator.d.ts +71 -0
- package/dist/wizard/lib/daemon-aggregator.js +204 -0
- package/dist/wizard/lib/daemon-core.d.ts +6 -0
- package/dist/wizard/lib/daemon-core.js +5 -0
- package/dist/wizard/lib/dashboard-data.d.ts +132 -0
- package/dist/wizard/lib/dashboard-data.js +336 -0
- package/dist/wizard/lib/dashboard-ws.d.ts +25 -0
- package/dist/wizard/lib/dashboard-ws.js +91 -0
- package/dist/wizard/lib/deep-current.d.ts +77 -0
- package/dist/wizard/lib/deep-current.js +234 -0
- package/dist/wizard/lib/deploy-coordinator.d.ts +40 -0
- package/dist/wizard/lib/deploy-coordinator.js +86 -0
- package/dist/wizard/lib/deploy-log.d.ts +28 -0
- package/dist/wizard/lib/deploy-log.js +52 -0
- package/dist/wizard/lib/desktop-notify.d.ts +27 -0
- package/dist/wizard/lib/desktop-notify.js +98 -0
- package/dist/wizard/lib/dns/cloudflare-dns.d.ts +35 -0
- package/dist/wizard/lib/dns/cloudflare-dns.js +216 -0
- package/dist/wizard/lib/dns/cloudflare-registrar.d.ts +31 -0
- package/dist/wizard/lib/dns/cloudflare-registrar.js +148 -0
- package/dist/wizard/lib/dns/types.d.ts +22 -0
- package/dist/wizard/lib/dns/types.js +4 -0
- package/dist/wizard/lib/document-discovery.d.ts +33 -0
- package/dist/wizard/lib/document-discovery.js +145 -0
- package/dist/wizard/lib/env-validator.d.ts +14 -0
- package/dist/wizard/lib/env-validator.js +205 -0
- package/dist/wizard/lib/env-writer.d.ts +13 -0
- package/dist/wizard/lib/env-writer.js +26 -0
- package/dist/wizard/lib/exec.d.ts +30 -0
- package/dist/wizard/lib/exec.js +52 -0
- package/dist/wizard/lib/experiment.d.ts +70 -0
- package/dist/wizard/lib/experiment.js +169 -0
- package/dist/wizard/lib/extensions.d.ts +20 -0
- package/dist/wizard/lib/extensions.js +183 -0
- package/dist/wizard/lib/financial/adapter-factory.d.ts +47 -0
- package/dist/wizard/lib/financial/adapter-factory.js +225 -0
- package/dist/wizard/lib/financial/billing/base.d.ts +6 -0
- package/dist/wizard/lib/financial/billing/base.js +1 -0
- package/dist/wizard/lib/financial/billing/google-billing.d.ts +56 -0
- package/dist/wizard/lib/financial/billing/google-billing.js +298 -0
- package/dist/wizard/lib/financial/billing/meta-billing.d.ts +54 -0
- package/dist/wizard/lib/financial/billing/meta-billing.js +243 -0
- package/dist/wizard/lib/financial/billing/tiktok-billing.d.ts +54 -0
- package/dist/wizard/lib/financial/billing/tiktok-billing.js +260 -0
- package/dist/wizard/lib/financial/campaign/base.d.ts +13 -0
- package/dist/wizard/lib/financial/campaign/base.js +1 -0
- package/dist/wizard/lib/financial/campaign/google-campaign.d.ts +42 -0
- package/dist/wizard/lib/financial/campaign/google-campaign.js +388 -0
- package/dist/wizard/lib/financial/campaign/meta-campaign.d.ts +41 -0
- package/dist/wizard/lib/financial/campaign/meta-campaign.js +311 -0
- package/dist/wizard/lib/financial/campaign/sandbox-campaign.d.ts +45 -0
- package/dist/wizard/lib/financial/campaign/sandbox-campaign.js +261 -0
- package/dist/wizard/lib/financial/campaign/tiktok-campaign.d.ts +40 -0
- package/dist/wizard/lib/financial/campaign/tiktok-campaign.js +350 -0
- package/dist/wizard/lib/financial/funding-auto.d.ts +44 -0
- package/dist/wizard/lib/financial/funding-auto.js +52 -0
- package/dist/wizard/lib/financial/funding-policy.d.ts +60 -0
- package/dist/wizard/lib/financial/funding-policy.js +179 -0
- package/dist/wizard/lib/financial/platform-planner.d.ts +47 -0
- package/dist/wizard/lib/financial/platform-planner.js +134 -0
- package/dist/wizard/lib/financial/reconciliation-engine.d.ts +78 -0
- package/dist/wizard/lib/financial/reconciliation-engine.js +193 -0
- package/dist/wizard/lib/financial/registry.d.ts +22 -0
- package/dist/wizard/lib/financial/registry.js +26 -0
- package/dist/wizard/lib/financial/reporting.d.ts +96 -0
- package/dist/wizard/lib/financial/reporting.js +198 -0
- package/dist/wizard/lib/financial/stablecoin/base.d.ts +6 -0
- package/dist/wizard/lib/financial/stablecoin/base.js +1 -0
- package/dist/wizard/lib/financial/stablecoin/circle.d.ts +54 -0
- package/dist/wizard/lib/financial/stablecoin/circle.js +367 -0
- package/dist/wizard/lib/financial/stablecoin/mercury.d.ts +24 -0
- package/dist/wizard/lib/financial/stablecoin/mercury.js +171 -0
- package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.d.ts +47 -0
- package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.js +202 -0
- package/dist/wizard/lib/financial/treasury-planner.d.ts +52 -0
- package/dist/wizard/lib/financial/treasury-planner.js +128 -0
- package/dist/wizard/lib/financial-core.d.ts +6 -0
- package/dist/wizard/lib/financial-core.js +5 -0
- package/dist/wizard/lib/financial-vault.d.ts +34 -0
- package/dist/wizard/lib/financial-vault.js +199 -0
- package/dist/wizard/lib/frontmatter.d.ts +30 -0
- package/dist/wizard/lib/frontmatter.js +96 -0
- package/dist/wizard/lib/gap-analysis.d.ts +37 -0
- package/dist/wizard/lib/gap-analysis.js +218 -0
- package/dist/wizard/lib/github.d.ts +22 -0
- package/dist/wizard/lib/github.js +261 -0
- package/dist/wizard/lib/headless-deploy.d.ts +14 -0
- package/dist/wizard/lib/headless-deploy.js +452 -0
- package/dist/wizard/lib/health-monitor.d.ts +15 -0
- package/dist/wizard/lib/health-monitor.js +91 -0
- package/dist/wizard/lib/health-poller.d.ts +9 -0
- package/dist/wizard/lib/health-poller.js +123 -0
- package/dist/wizard/lib/heartbeat.d.ts +15 -0
- package/dist/wizard/lib/heartbeat.js +827 -0
- package/dist/wizard/lib/http-helpers.d.ts +9 -0
- package/dist/wizard/lib/http-helpers.js +24 -0
- package/dist/wizard/lib/image-gen.d.ts +56 -0
- package/dist/wizard/lib/image-gen.js +159 -0
- package/dist/wizard/lib/instance-sizing.d.ts +26 -0
- package/dist/wizard/lib/instance-sizing.js +51 -0
- package/dist/wizard/lib/kongo/analytics.d.ts +29 -0
- package/dist/wizard/lib/kongo/analytics.js +179 -0
- package/dist/wizard/lib/kongo/campaigns.d.ts +52 -0
- package/dist/wizard/lib/kongo/campaigns.js +91 -0
- package/dist/wizard/lib/kongo/client.d.ts +58 -0
- package/dist/wizard/lib/kongo/client.js +221 -0
- package/dist/wizard/lib/kongo/jobs.d.ts +57 -0
- package/dist/wizard/lib/kongo/jobs.js +122 -0
- package/dist/wizard/lib/kongo/pages.d.ts +60 -0
- package/dist/wizard/lib/kongo/pages.js +150 -0
- package/dist/wizard/lib/kongo/provisioner.d.ts +64 -0
- package/dist/wizard/lib/kongo/provisioner.js +116 -0
- package/dist/wizard/lib/kongo/seed.d.ts +49 -0
- package/dist/wizard/lib/kongo/seed.js +237 -0
- package/dist/wizard/lib/kongo/types.d.ts +323 -0
- package/dist/wizard/lib/kongo/types.js +11 -0
- package/dist/wizard/lib/kongo/variants.d.ts +57 -0
- package/dist/wizard/lib/kongo/variants.js +88 -0
- package/dist/wizard/lib/kongo/webhooks.d.ts +41 -0
- package/dist/wizard/lib/kongo/webhooks.js +112 -0
- package/dist/wizard/lib/marker.d.ts +28 -0
- package/dist/wizard/lib/marker.js +79 -0
- package/dist/wizard/lib/migrator.d.ts +35 -0
- package/dist/wizard/lib/migrator.js +190 -0
- package/dist/wizard/lib/natural-language-deploy.d.ts +30 -0
- package/dist/wizard/lib/natural-language-deploy.js +186 -0
- package/dist/wizard/lib/network.d.ts +22 -0
- package/dist/wizard/lib/network.js +72 -0
- package/dist/wizard/lib/oauth-core.d.ts +6 -0
- package/dist/wizard/lib/oauth-core.js +5 -0
- package/dist/wizard/lib/open-browser.d.ts +1 -0
- package/dist/wizard/lib/open-browser.js +26 -0
- package/dist/wizard/lib/patterns/ad-billing-adapter.d.ts +209 -0
- package/dist/wizard/lib/patterns/ad-billing-adapter.js +269 -0
- package/dist/wizard/lib/patterns/ad-platform-adapter.d.ts +200 -0
- package/dist/wizard/lib/patterns/ad-platform-adapter.js +212 -0
- package/dist/wizard/lib/patterns/daemon-process.d.ts +88 -0
- package/dist/wizard/lib/patterns/daemon-process.js +271 -0
- package/dist/wizard/lib/patterns/financial-transaction.d.ts +161 -0
- package/dist/wizard/lib/patterns/financial-transaction.js +132 -0
- package/dist/wizard/lib/patterns/funding-plan.d.ts +136 -0
- package/dist/wizard/lib/patterns/funding-plan.js +200 -0
- package/dist/wizard/lib/patterns/oauth-token-lifecycle.d.ts +94 -0
- package/dist/wizard/lib/patterns/oauth-token-lifecycle.js +139 -0
- package/dist/wizard/lib/patterns/outbound-rate-limiter.d.ts +67 -0
- package/dist/wizard/lib/patterns/outbound-rate-limiter.js +216 -0
- package/dist/wizard/lib/patterns/revenue-source-adapter.d.ts +96 -0
- package/dist/wizard/lib/patterns/revenue-source-adapter.js +182 -0
- package/dist/wizard/lib/patterns/stablecoin-adapter.d.ts +218 -0
- package/dist/wizard/lib/patterns/stablecoin-adapter.js +264 -0
- package/dist/wizard/lib/prd-validator.d.ts +39 -0
- package/dist/wizard/lib/prd-validator.js +137 -0
- package/dist/wizard/lib/project-init.d.ts +24 -0
- package/dist/wizard/lib/project-init.js +193 -0
- package/dist/wizard/lib/project-registry.d.ts +86 -0
- package/dist/wizard/lib/project-registry.js +359 -0
- package/dist/wizard/lib/provision-manifest.d.ts +44 -0
- package/dist/wizard/lib/provision-manifest.js +164 -0
- package/dist/wizard/lib/provisioner-registry.d.ts +15 -0
- package/dist/wizard/lib/provisioner-registry.js +34 -0
- package/dist/wizard/lib/provisioners/aws-vps.d.ts +6 -0
- package/dist/wizard/lib/provisioners/aws-vps.js +643 -0
- package/dist/wizard/lib/provisioners/cloudflare.d.ts +6 -0
- package/dist/wizard/lib/provisioners/cloudflare.js +300 -0
- package/dist/wizard/lib/provisioners/docker.d.ts +6 -0
- package/dist/wizard/lib/provisioners/docker.js +75 -0
- package/dist/wizard/lib/provisioners/http-client.d.ts +20 -0
- package/dist/wizard/lib/provisioners/http-client.js +79 -0
- package/dist/wizard/lib/provisioners/railway.d.ts +6 -0
- package/dist/wizard/lib/provisioners/railway.js +413 -0
- package/dist/wizard/lib/provisioners/scripts/caddyfile.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/caddyfile.js +54 -0
- package/dist/wizard/lib/provisioners/scripts/deploy-vps.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/deploy-vps.js +112 -0
- package/dist/wizard/lib/provisioners/scripts/docker-compose.d.ts +11 -0
- package/dist/wizard/lib/provisioners/scripts/docker-compose.js +91 -0
- package/dist/wizard/lib/provisioners/scripts/dockerfile.d.ts +5 -0
- package/dist/wizard/lib/provisioners/scripts/dockerfile.js +185 -0
- package/dist/wizard/lib/provisioners/scripts/ecosystem-config.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/ecosystem-config.js +36 -0
- package/dist/wizard/lib/provisioners/scripts/provision-vps.d.ts +14 -0
- package/dist/wizard/lib/provisioners/scripts/provision-vps.js +202 -0
- package/dist/wizard/lib/provisioners/scripts/rollback-vps.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/rollback-vps.js +67 -0
- package/dist/wizard/lib/provisioners/self-deploy.d.ts +41 -0
- package/dist/wizard/lib/provisioners/self-deploy.js +185 -0
- package/dist/wizard/lib/provisioners/static-s3.d.ts +6 -0
- package/dist/wizard/lib/provisioners/static-s3.js +235 -0
- package/dist/wizard/lib/provisioners/types.d.ts +40 -0
- package/dist/wizard/lib/provisioners/types.js +4 -0
- package/dist/wizard/lib/provisioners/vercel.d.ts +6 -0
- package/dist/wizard/lib/provisioners/vercel.js +287 -0
- package/dist/wizard/lib/pty-manager.d.ts +42 -0
- package/dist/wizard/lib/pty-manager.js +231 -0
- package/dist/wizard/lib/rate-limiter-core.d.ts +5 -0
- package/dist/wizard/lib/rate-limiter-core.js +5 -0
- package/dist/wizard/lib/reconciliation.d.ts +43 -0
- package/dist/wizard/lib/reconciliation.js +173 -0
- package/dist/wizard/lib/revenue-types.d.ts +5 -0
- package/dist/wizard/lib/revenue-types.js +1 -0
- package/dist/wizard/lib/route-optimizer.d.ts +28 -0
- package/dist/wizard/lib/route-optimizer.js +93 -0
- package/dist/wizard/lib/s3-deploy.d.ts +19 -0
- package/dist/wizard/lib/s3-deploy.js +156 -0
- package/dist/wizard/lib/safety-tiers.d.ts +76 -0
- package/dist/wizard/lib/safety-tiers.js +134 -0
- package/dist/wizard/lib/sentry-generator.d.ts +15 -0
- package/dist/wizard/lib/sentry-generator.js +116 -0
- package/dist/wizard/lib/server-config.d.ts +13 -0
- package/dist/wizard/lib/server-config.js +23 -0
- package/dist/wizard/lib/service-install.d.ts +18 -0
- package/dist/wizard/lib/service-install.js +182 -0
- package/dist/wizard/lib/site-scanner.d.ts +80 -0
- package/dist/wizard/lib/site-scanner.js +262 -0
- package/dist/wizard/lib/ssh-deploy.d.ts +25 -0
- package/dist/wizard/lib/ssh-deploy.js +225 -0
- package/dist/wizard/lib/templates.d.ts +24 -0
- package/dist/wizard/lib/templates.js +219 -0
- package/dist/wizard/lib/totp.d.ts +35 -0
- package/dist/wizard/lib/totp.js +276 -0
- package/dist/wizard/lib/tower-auth.d.ts +43 -0
- package/dist/wizard/lib/tower-auth.js +352 -0
- package/dist/wizard/lib/tower-rate-limit.d.ts +14 -0
- package/dist/wizard/lib/tower-rate-limit.js +61 -0
- package/dist/wizard/lib/tower-session.d.ts +28 -0
- package/dist/wizard/lib/tower-session.js +119 -0
- package/dist/wizard/lib/treasury-backup.d.ts +23 -0
- package/dist/wizard/lib/treasury-backup.js +126 -0
- package/dist/wizard/lib/treasury-heartbeat.d.ts +82 -0
- package/dist/wizard/lib/treasury-heartbeat.js +1104 -0
- package/dist/wizard/lib/updater.d.ts +29 -0
- package/dist/wizard/lib/updater.js +190 -0
- package/dist/wizard/lib/user-manager.d.ts +39 -0
- package/dist/wizard/lib/user-manager.js +182 -0
- package/dist/wizard/lib/vault.d.ts +26 -0
- package/dist/wizard/lib/vault.js +161 -0
- package/dist/wizard/router.d.ts +5 -0
- package/dist/wizard/router.js +15 -0
- package/dist/wizard/server.d.ts +18 -0
- package/dist/wizard/server.js +436 -0
- package/package.json +59 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD Structural Validator — Troi's compliance checks.
|
|
3
|
+
*
|
|
4
|
+
* Validates that a PRD document has the expected sections and
|
|
5
|
+
* cross-references based on its frontmatter configuration.
|
|
6
|
+
* Produces warnings (not errors) — the user can proceed with gaps.
|
|
7
|
+
*
|
|
8
|
+
* PRD Reference: RFC-blueprint-path.md
|
|
9
|
+
*/
|
|
10
|
+
import type { PrdFrontmatter } from './frontmatter.js';
|
|
11
|
+
export interface ValidationResult {
|
|
12
|
+
errors: string[];
|
|
13
|
+
warnings: string[];
|
|
14
|
+
sections: string[];
|
|
15
|
+
valid: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extract all markdown heading sections from PRD content.
|
|
19
|
+
* Returns lowercase heading text for case-insensitive matching.
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractSections(content: string): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Validate PRD structure against frontmatter configuration.
|
|
24
|
+
*
|
|
25
|
+
* Rules (warnings, not blockers):
|
|
26
|
+
* - PRD must have an OVERVIEW or SUMMARY section
|
|
27
|
+
* - PRD must have at least one feature section
|
|
28
|
+
* - If database is configured, should have DATA MODELS section
|
|
29
|
+
* - If deploy target is set, should have DEPLOYMENT section
|
|
30
|
+
* - If auth is enabled, should mention authentication
|
|
31
|
+
* - If workers are enabled, should define background workers
|
|
32
|
+
* - If payments are configured, should have a payments/billing section
|
|
33
|
+
*/
|
|
34
|
+
export declare function validatePrdStructure(content: string, frontmatter: PrdFrontmatter): ValidationResult;
|
|
35
|
+
/**
|
|
36
|
+
* Run conflict scan between frontmatter fields.
|
|
37
|
+
* Checks for contradictions that cost hours if caught late.
|
|
38
|
+
*/
|
|
39
|
+
export declare function scanConflicts(frontmatter: PrdFrontmatter): string[];
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD Structural Validator — Troi's compliance checks.
|
|
3
|
+
*
|
|
4
|
+
* Validates that a PRD document has the expected sections and
|
|
5
|
+
* cross-references based on its frontmatter configuration.
|
|
6
|
+
* Produces warnings (not errors) — the user can proceed with gaps.
|
|
7
|
+
*
|
|
8
|
+
* PRD Reference: RFC-blueprint-path.md
|
|
9
|
+
*/
|
|
10
|
+
// ── Section Detection ───────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Extract all markdown heading sections from PRD content.
|
|
13
|
+
* Returns lowercase heading text for case-insensitive matching.
|
|
14
|
+
*/
|
|
15
|
+
export function extractSections(content) {
|
|
16
|
+
const headingPattern = /^#{1,3}\s+(.+)$/gm;
|
|
17
|
+
const sections = [];
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = headingPattern.exec(content)) !== null) {
|
|
20
|
+
sections.push(match[1].trim().toLowerCase());
|
|
21
|
+
}
|
|
22
|
+
return sections;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if any section heading contains a given keyword.
|
|
26
|
+
*/
|
|
27
|
+
function hasSection(sections, keyword) {
|
|
28
|
+
const lower = keyword.toLowerCase();
|
|
29
|
+
return sections.some(s => s.includes(lower));
|
|
30
|
+
}
|
|
31
|
+
// ── Structural Validation ───────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Validate PRD structure against frontmatter configuration.
|
|
34
|
+
*
|
|
35
|
+
* Rules (warnings, not blockers):
|
|
36
|
+
* - PRD must have an OVERVIEW or SUMMARY section
|
|
37
|
+
* - PRD must have at least one feature section
|
|
38
|
+
* - If database is configured, should have DATA MODELS section
|
|
39
|
+
* - If deploy target is set, should have DEPLOYMENT section
|
|
40
|
+
* - If auth is enabled, should mention authentication
|
|
41
|
+
* - If workers are enabled, should define background workers
|
|
42
|
+
* - If payments are configured, should have a payments/billing section
|
|
43
|
+
*/
|
|
44
|
+
export function validatePrdStructure(content, frontmatter) {
|
|
45
|
+
const sections = extractSections(content);
|
|
46
|
+
const errors = [];
|
|
47
|
+
const warnings = [];
|
|
48
|
+
const contentLower = content.toLowerCase();
|
|
49
|
+
// Required: Overview or Summary section
|
|
50
|
+
if (!hasSection(sections, 'overview') && !hasSection(sections, 'summary') && !hasSection(sections, 'introduction')) {
|
|
51
|
+
warnings.push('Missing OVERVIEW or SUMMARY section — add a high-level description of the product');
|
|
52
|
+
}
|
|
53
|
+
// Required: At least one feature section
|
|
54
|
+
if (!hasSection(sections, 'feature') && !hasSection(sections, 'core') && !hasSection(sections, 'functionality')) {
|
|
55
|
+
warnings.push('No feature sections found — add sections describing what the product does');
|
|
56
|
+
}
|
|
57
|
+
// Conditional: Database → Data Models
|
|
58
|
+
if (frontmatter.database && frontmatter.database !== 'no' && frontmatter.database !== 'none') {
|
|
59
|
+
if (!hasSection(sections, 'data model') && !hasSection(sections, 'schema') && !hasSection(sections, 'database')) {
|
|
60
|
+
warnings.push(`Database "${frontmatter.database}" configured but no DATA MODELS or SCHEMA section found`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Conditional: Deploy → Deployment section
|
|
64
|
+
if (frontmatter.deploy && frontmatter.deploy !== 'no' && frontmatter.deploy !== 'none') {
|
|
65
|
+
if (!hasSection(sections, 'deploy') && !hasSection(sections, 'infrastructure') && !hasSection(sections, 'hosting')) {
|
|
66
|
+
warnings.push(`Deploy target "${frontmatter.deploy}" configured but no DEPLOYMENT section found`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Conditional: Auth → Authentication mentioned
|
|
70
|
+
if (frontmatter.auth && frontmatter.auth !== 'no' && frontmatter.auth !== 'none' && frontmatter.auth !== 'false') {
|
|
71
|
+
if (!contentLower.includes('auth') && !contentLower.includes('login') && !contentLower.includes('sign in')) {
|
|
72
|
+
warnings.push('Auth is enabled but PRD does not mention authentication, login, or sign-in');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Conditional: Workers → Background jobs defined
|
|
76
|
+
if (frontmatter.workers && frontmatter.workers !== 'no' && frontmatter.workers !== 'none' && frontmatter.workers !== 'false') {
|
|
77
|
+
if (!contentLower.includes('worker') && !contentLower.includes('background') && !contentLower.includes('queue') && !contentLower.includes('cron')) {
|
|
78
|
+
warnings.push('Workers enabled but PRD does not mention workers, background jobs, queues, or cron');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Conditional: Payments → Billing section
|
|
82
|
+
if (frontmatter.payments && frontmatter.payments !== 'no' && frontmatter.payments !== 'none' && frontmatter.payments !== 'false') {
|
|
83
|
+
if (!contentLower.includes('payment') && !contentLower.includes('billing') && !contentLower.includes('subscription') && !contentLower.includes('pricing')) {
|
|
84
|
+
warnings.push(`Payments "${frontmatter.payments}" configured but PRD does not mention payments, billing, or pricing`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Conditional: Email → Email section or mentions
|
|
88
|
+
if (frontmatter.email && frontmatter.email !== 'no' && frontmatter.email !== 'none' && frontmatter.email !== 'false') {
|
|
89
|
+
if (!contentLower.includes('email') && !contentLower.includes('notification') && !contentLower.includes('mail')) {
|
|
90
|
+
warnings.push(`Email "${frontmatter.email}" configured but PRD does not mention email or notifications`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
errors,
|
|
95
|
+
warnings,
|
|
96
|
+
sections,
|
|
97
|
+
valid: errors.length === 0,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Run conflict scan between frontmatter fields.
|
|
102
|
+
* Checks for contradictions that cost hours if caught late.
|
|
103
|
+
*/
|
|
104
|
+
export function scanConflicts(frontmatter) {
|
|
105
|
+
const conflicts = [];
|
|
106
|
+
// Auth + Database: auth usually needs a database
|
|
107
|
+
if (frontmatter.auth && frontmatter.auth !== 'no' && frontmatter.auth !== 'none') {
|
|
108
|
+
if (!frontmatter.database || frontmatter.database === 'none') {
|
|
109
|
+
conflicts.push('Auth is enabled but no database configured — auth needs persistent storage for users/sessions');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Payments + Auth: payments need auth
|
|
113
|
+
if (frontmatter.payments && frontmatter.payments !== 'no' && frontmatter.payments !== 'none') {
|
|
114
|
+
if (!frontmatter.auth || frontmatter.auth === 'no' || frontmatter.auth === 'none') {
|
|
115
|
+
conflicts.push('Payments configured but auth is disabled — payments require authenticated users');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Workers + Deploy: workers need persistent hosting
|
|
119
|
+
if (frontmatter.workers && frontmatter.workers !== 'no' && frontmatter.workers !== 'none' && frontmatter.workers !== 'false') {
|
|
120
|
+
if (frontmatter.deploy === 'static' || frontmatter.deploy === 'cloudflare') {
|
|
121
|
+
conflicts.push(`Workers enabled but deploy target "${frontmatter.deploy}" does not support background processes`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Cache + Deploy: Redis needs a host
|
|
125
|
+
if (frontmatter.cache && frontmatter.cache !== 'none' && frontmatter.cache !== 'no') {
|
|
126
|
+
if (frontmatter.deploy === 'static' || frontmatter.deploy === 'cloudflare') {
|
|
127
|
+
conflicts.push(`Cache "${frontmatter.cache}" configured but deploy target "${frontmatter.deploy}" does not support cache services`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Admin + Auth: admin panel needs auth
|
|
131
|
+
if (frontmatter.admin && frontmatter.admin !== 'no' && frontmatter.admin !== 'none' && frontmatter.admin !== 'false') {
|
|
132
|
+
if (!frontmatter.auth || frontmatter.auth === 'no' || frontmatter.auth === 'none') {
|
|
133
|
+
conflicts.push('Admin panel enabled but auth is disabled — admin requires authenticated access');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return conflicts;
|
|
137
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project creation — headless and browser init flows.
|
|
3
|
+
*
|
|
4
|
+
* Creates a new VoidForge project by copying methodology files,
|
|
5
|
+
* injecting project identity, writing the marker, and registering.
|
|
6
|
+
*/
|
|
7
|
+
import { type VoidForgeMarker } from './marker.js';
|
|
8
|
+
export interface ProjectConfig {
|
|
9
|
+
name: string;
|
|
10
|
+
directory: string;
|
|
11
|
+
oneliner?: string;
|
|
12
|
+
domain?: string;
|
|
13
|
+
repoUrl?: string;
|
|
14
|
+
tier?: VoidForgeMarker['tier'];
|
|
15
|
+
extensions?: string[];
|
|
16
|
+
core?: boolean;
|
|
17
|
+
skipGit?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ProjectResult {
|
|
20
|
+
projectDir: string;
|
|
21
|
+
markerId: string;
|
|
22
|
+
filesCreated: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function createProject(config: ProjectConfig): Promise<ProjectResult>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project creation — headless and browser init flows.
|
|
3
|
+
*
|
|
4
|
+
* Creates a new VoidForge project by copying methodology files,
|
|
5
|
+
* injecting project identity, writing the marker, and registering.
|
|
6
|
+
*/
|
|
7
|
+
import { mkdir, readFile, writeFile, readdir, cp } from 'node:fs/promises';
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { join, resolve } from 'node:path';
|
|
10
|
+
import { execSync } from 'node:child_process';
|
|
11
|
+
import { createMarker, writeMarker, } from './marker.js';
|
|
12
|
+
import { addProject } from './project-registry.js';
|
|
13
|
+
// ── Methodology Source ───────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* Resolves the methodology source directory.
|
|
16
|
+
* In development: monorepo root (where CLAUDE.md lives).
|
|
17
|
+
* In production: the installed @voidforge/methodology package.
|
|
18
|
+
*/
|
|
19
|
+
async function resolveMethodologyRoot() {
|
|
20
|
+
// Development: walk up from this file to find CLAUDE.md at monorepo root
|
|
21
|
+
const dir = import.meta.dirname ?? new URL('.', import.meta.url).pathname;
|
|
22
|
+
let current = dir;
|
|
23
|
+
for (let i = 0; i < 10; i++) {
|
|
24
|
+
if (existsSync(join(current, 'CLAUDE.md')) && existsSync(join(current, '.claude', 'commands'))) {
|
|
25
|
+
return current;
|
|
26
|
+
}
|
|
27
|
+
current = resolve(current, '..');
|
|
28
|
+
}
|
|
29
|
+
// Production: try to resolve from @voidforge/methodology
|
|
30
|
+
try {
|
|
31
|
+
const { createRequire } = await import('node:module');
|
|
32
|
+
const require_ = createRequire(import.meta.url);
|
|
33
|
+
const methodologyPkg = require_.resolve('@voidforge/methodology/package.json');
|
|
34
|
+
return resolve(methodologyPkg, '..');
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Package not installed — expected in development
|
|
38
|
+
}
|
|
39
|
+
throw new Error('Cannot find methodology source. Checked: CLAUDE.md walkup (development), ' +
|
|
40
|
+
'@voidforge/methodology package (production). Ensure VoidForge is installed correctly.');
|
|
41
|
+
}
|
|
42
|
+
// ── Copy Methodology ─────────────────────────────────────
|
|
43
|
+
async function copyDir(src, dest) {
|
|
44
|
+
if (!existsSync(src))
|
|
45
|
+
return 0;
|
|
46
|
+
await mkdir(dest, { recursive: true });
|
|
47
|
+
let count = 0;
|
|
48
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
const srcPath = join(src, entry.name);
|
|
51
|
+
const destPath = join(dest, entry.name);
|
|
52
|
+
if (entry.isDirectory()) {
|
|
53
|
+
count += await copyDir(srcPath, destPath);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
await cp(srcPath, destPath);
|
|
57
|
+
count++;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return count;
|
|
61
|
+
}
|
|
62
|
+
async function copyMethodology(methodologyRoot, projectDir, core) {
|
|
63
|
+
let count = 0;
|
|
64
|
+
// Always copy: CLAUDE.md, VERSION.md
|
|
65
|
+
for (const file of ['CLAUDE.md', 'VERSION.md']) {
|
|
66
|
+
const src = join(methodologyRoot, file);
|
|
67
|
+
if (existsSync(src)) {
|
|
68
|
+
await cp(src, join(projectDir, file));
|
|
69
|
+
count++;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Full tier: also copy HOLOCRON.md, CHANGELOG.md
|
|
73
|
+
if (!core) {
|
|
74
|
+
for (const file of ['HOLOCRON.md', 'CHANGELOG.md']) {
|
|
75
|
+
const src = join(methodologyRoot, file);
|
|
76
|
+
if (existsSync(src)) {
|
|
77
|
+
await cp(src, join(projectDir, file));
|
|
78
|
+
count++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Commands
|
|
83
|
+
const commandsSrc = join(methodologyRoot, '.claude', 'commands');
|
|
84
|
+
if (existsSync(commandsSrc)) {
|
|
85
|
+
count += await copyDir(commandsSrc, join(projectDir, '.claude', 'commands'));
|
|
86
|
+
}
|
|
87
|
+
// Methods
|
|
88
|
+
const methodsSrc = join(methodologyRoot, 'docs', 'methods');
|
|
89
|
+
if (existsSync(methodsSrc)) {
|
|
90
|
+
count += await copyDir(methodsSrc, join(projectDir, 'docs', 'methods'));
|
|
91
|
+
}
|
|
92
|
+
// Patterns (full tier only)
|
|
93
|
+
if (!core) {
|
|
94
|
+
const patternsSrc = join(methodologyRoot, 'docs', 'patterns');
|
|
95
|
+
if (existsSync(patternsSrc)) {
|
|
96
|
+
count += await copyDir(patternsSrc, join(projectDir, 'docs', 'patterns'));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Naming registry
|
|
100
|
+
const registrySrc = join(methodologyRoot, 'docs', 'NAMING_REGISTRY.md');
|
|
101
|
+
if (existsSync(registrySrc)) {
|
|
102
|
+
await mkdir(join(projectDir, 'docs'), { recursive: true });
|
|
103
|
+
await cp(registrySrc, join(projectDir, 'docs', 'NAMING_REGISTRY.md'));
|
|
104
|
+
count++;
|
|
105
|
+
}
|
|
106
|
+
// Thumper scripts
|
|
107
|
+
const thumperSrc = join(methodologyRoot, 'scripts', 'thumper');
|
|
108
|
+
if (existsSync(thumperSrc)) {
|
|
109
|
+
count += await copyDir(thumperSrc, join(projectDir, 'scripts', 'thumper'));
|
|
110
|
+
}
|
|
111
|
+
return count;
|
|
112
|
+
}
|
|
113
|
+
// ── Identity Injection ───────────────────────────────────
|
|
114
|
+
async function injectIdentity(projectDir, config) {
|
|
115
|
+
const claudePath = join(projectDir, 'CLAUDE.md');
|
|
116
|
+
if (!existsSync(claudePath))
|
|
117
|
+
return;
|
|
118
|
+
let content = await readFile(claudePath, 'utf-8');
|
|
119
|
+
content = content.replace('[PROJECT_NAME]', config.name);
|
|
120
|
+
content = content.replace('[ONE_LINE_DESCRIPTION]', config.oneliner ?? '');
|
|
121
|
+
content = content.replace('[DOMAIN]', config.domain ?? '');
|
|
122
|
+
content = content.replace('[REPO_URL]', config.repoUrl ?? '');
|
|
123
|
+
await writeFile(claudePath, content, 'utf-8');
|
|
124
|
+
}
|
|
125
|
+
// ── Git Init ─────────────────────────────────────────────
|
|
126
|
+
function gitInit(projectDir) {
|
|
127
|
+
try {
|
|
128
|
+
execSync('git init', { cwd: projectDir, stdio: 'pipe' });
|
|
129
|
+
execSync('git add -A', { cwd: projectDir, stdio: 'pipe' });
|
|
130
|
+
execSync('git commit -m "Initial commit — created with VoidForge"', {
|
|
131
|
+
cwd: projectDir,
|
|
132
|
+
stdio: 'pipe',
|
|
133
|
+
env: { ...process.env },
|
|
134
|
+
});
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// ── Main Entry ───────────────────────────────────────────
|
|
142
|
+
export async function createProject(config) {
|
|
143
|
+
const projectDir = resolve(config.directory);
|
|
144
|
+
// 1. Create directory
|
|
145
|
+
await mkdir(projectDir, { recursive: true });
|
|
146
|
+
// 2. Copy methodology
|
|
147
|
+
const methodologyRoot = await resolveMethodologyRoot();
|
|
148
|
+
const filesCreated = await copyMethodology(methodologyRoot, projectDir, config.core ?? false);
|
|
149
|
+
// 3. Inject project identity
|
|
150
|
+
await injectIdentity(projectDir, config);
|
|
151
|
+
// 4. Write .voidforge marker
|
|
152
|
+
const marker = createMarker('21.0.0', config.core ? 'methodology' : 'full', config.extensions ?? []);
|
|
153
|
+
await writeMarker(projectDir, marker);
|
|
154
|
+
// 5. Register in project registry
|
|
155
|
+
try {
|
|
156
|
+
await addProject({
|
|
157
|
+
name: config.name,
|
|
158
|
+
directory: projectDir,
|
|
159
|
+
deployTarget: '',
|
|
160
|
+
deployUrl: '',
|
|
161
|
+
sshHost: '',
|
|
162
|
+
framework: 'unknown',
|
|
163
|
+
database: 'none',
|
|
164
|
+
createdAt: marker.created,
|
|
165
|
+
lastBuildPhase: 0,
|
|
166
|
+
lastDeployAt: '',
|
|
167
|
+
healthCheckUrl: '',
|
|
168
|
+
monthlyCost: 0,
|
|
169
|
+
owner: '',
|
|
170
|
+
access: [],
|
|
171
|
+
linkedProjects: [],
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Registry write is best-effort — don't fail project creation
|
|
176
|
+
}
|
|
177
|
+
// 6. Validate critical files were copied
|
|
178
|
+
if (!existsSync(join(projectDir, 'CLAUDE.md'))) {
|
|
179
|
+
throw new Error('Failed to copy CLAUDE.md — methodology source may be corrupted.');
|
|
180
|
+
}
|
|
181
|
+
// 7. Git init + initial commit
|
|
182
|
+
if (!config.skipGit) {
|
|
183
|
+
const gitOk = gitInit(projectDir);
|
|
184
|
+
if (!gitOk) {
|
|
185
|
+
console.warn('Warning: git init failed. Project created but not version-controlled.');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
projectDir,
|
|
190
|
+
markerId: marker.id,
|
|
191
|
+
filesCreated: filesCreated + 1, // +1 for .voidforge marker
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Registry — CRUD for ~/.voidforge/projects.json.
|
|
3
|
+
* Zero-dep JSON file storage for multi-project Avengers Tower.
|
|
4
|
+
* File permissions: 0600 (owner read/write only).
|
|
5
|
+
*
|
|
6
|
+
* Follows vault.ts patterns: serialized writes, atomic file ops, homedir().
|
|
7
|
+
*/
|
|
8
|
+
export type HealthStatus = 'healthy' | 'degraded' | 'down' | 'unchecked';
|
|
9
|
+
export interface ProjectAccessEntry {
|
|
10
|
+
username: string;
|
|
11
|
+
role: 'deployer' | 'viewer';
|
|
12
|
+
}
|
|
13
|
+
export interface Project {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
directory: string;
|
|
17
|
+
deployTarget: string;
|
|
18
|
+
deployUrl: string;
|
|
19
|
+
sshHost: string;
|
|
20
|
+
framework: string;
|
|
21
|
+
database: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
lastBuildPhase: number;
|
|
24
|
+
lastDeployAt: string;
|
|
25
|
+
healthCheckUrl: string;
|
|
26
|
+
monthlyCost: number;
|
|
27
|
+
healthStatus: HealthStatus;
|
|
28
|
+
healthCheckedAt: string;
|
|
29
|
+
owner: string;
|
|
30
|
+
access: ProjectAccessEntry[];
|
|
31
|
+
linkedProjects: string[];
|
|
32
|
+
}
|
|
33
|
+
export type ProjectInput = Omit<Project, 'id' | 'healthStatus' | 'healthCheckedAt'> & {
|
|
34
|
+
owner?: string;
|
|
35
|
+
access?: ProjectAccessEntry[];
|
|
36
|
+
linkedProjects?: string[];
|
|
37
|
+
};
|
|
38
|
+
/** Read the full registry. Returns empty array if file doesn't exist. */
|
|
39
|
+
export declare function readRegistry(): Promise<Project[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Add a new project to the registry.
|
|
42
|
+
* @throws Error if a project with the same directory is already registered.
|
|
43
|
+
*/
|
|
44
|
+
export declare function addProject(input: ProjectInput): Promise<Project>;
|
|
45
|
+
/** Get a project by ID. Returns null if not found. */
|
|
46
|
+
export declare function getProject(id: string): Promise<Project | null>;
|
|
47
|
+
/** Find a project by directory path. Returns null if not found. */
|
|
48
|
+
export declare function findByDirectory(directory: string): Promise<Project | null>;
|
|
49
|
+
/** Update a project by ID. Merges only known mutable fields. Returns null if not found. */
|
|
50
|
+
export declare function updateProject(id: string, updates: Partial<Omit<Project, 'id' | 'createdAt' | 'directory'>>): Promise<Project | null>;
|
|
51
|
+
/** Remove a project by ID. Cleans up linked references in other projects. */
|
|
52
|
+
export declare function removeProject(id: string): Promise<boolean>;
|
|
53
|
+
/** Update health status for a project. */
|
|
54
|
+
export declare function updateHealthStatus(id: string, status: HealthStatus): Promise<void>;
|
|
55
|
+
/** LOKI-004: Batch update health status — single read-write cycle for N projects. */
|
|
56
|
+
export declare function batchUpdateHealthStatus(updates: Array<{
|
|
57
|
+
id: string;
|
|
58
|
+
status: HealthStatus;
|
|
59
|
+
}>): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Get projects visible to a user.
|
|
62
|
+
* Admins see all. Others see owned + explicitly shared.
|
|
63
|
+
*/
|
|
64
|
+
export declare function getProjectsForUser(username: string, globalRole: string): Promise<Project[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Check if a user can access a project at the given role level.
|
|
67
|
+
* Returns the effective role or null if no access.
|
|
68
|
+
*/
|
|
69
|
+
export declare function checkProjectAccess(projectId: string, username: string, globalRole: string): Promise<'admin' | 'deployer' | 'viewer' | null>;
|
|
70
|
+
/** Grant access to a project for a user. Overwrites existing entry for that user. */
|
|
71
|
+
export declare function grantAccess(projectId: string, username: string, role: 'deployer' | 'viewer'): Promise<void>;
|
|
72
|
+
/** Revoke access from a project for a user. */
|
|
73
|
+
export declare function revokeAccess(projectId: string, username: string): Promise<void>;
|
|
74
|
+
/** Remove a user from all project access lists and clear ownership (cleanup on user deletion). */
|
|
75
|
+
export declare function removeUserFromAllProjects(username: string): Promise<number>;
|
|
76
|
+
/** Get access list for a project. */
|
|
77
|
+
export declare function getProjectAccess(projectId: string): Promise<{
|
|
78
|
+
owner: string;
|
|
79
|
+
access: ProjectAccessEntry[];
|
|
80
|
+
} | null>;
|
|
81
|
+
/** Link two projects bidirectionally. */
|
|
82
|
+
export declare function linkProjects(projectIdA: string, projectIdB: string): Promise<void>;
|
|
83
|
+
/** Unlink two projects bidirectionally. */
|
|
84
|
+
export declare function unlinkProjects(projectIdA: string, projectIdB: string): Promise<void>;
|
|
85
|
+
/** Get all projects in the linked group (BFS traversal with cycle detection). */
|
|
86
|
+
export declare function getLinkedGroup(projectId: string): Promise<Project[]>;
|