snipara-companion 3.0.6 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.js +564 -67
- package/docs/FULL_REFERENCE.md +25 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,6 +43,7 @@ These commands are useful without hosted Snipara:
|
|
|
43
43
|
| ------------------------------------------------------------ | ------------------------------------------------------------ |
|
|
44
44
|
| `source init` / `source sync` / `source status` | Local source snapshot, document preview, and code overlay |
|
|
45
45
|
| `impact` / `code impact` | File-level blast-radius from the local code overlay |
|
|
46
|
+
| `reality-check` | Intent/verification checks for local or supplied changes |
|
|
46
47
|
| `code callers` / `imports` / `neighbors` / `shortest-path` | Structural repo questions from local files |
|
|
47
48
|
| `workflow start` / `phase-start` / `phase-commit` / `resume` | Agent continuity that survives compaction |
|
|
48
49
|
| `context-pack` | Reversible local packs for long logs, diffs, and tool output |
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { ProjectIntelligenceEngineeringLeadPlanSummary } from '@snipara/project-intelligence-contracts';
|
|
2
|
+
import { ProjectRealityCheckResult, ProjectIntelligenceEngineeringLeadPlanSummary } from '@snipara/project-intelligence-contracts';
|
|
3
3
|
|
|
4
4
|
declare function resolveQueryFromToolInput(toolInput?: string, tool?: string): string | null;
|
|
5
5
|
|
|
@@ -1946,6 +1946,23 @@ interface ProjectIntelligenceBrief {
|
|
|
1946
1946
|
declare function buildProjectIntelligenceBrief(options: ProjectIntelligenceBriefOptions): Promise<ProjectIntelligenceBrief>;
|
|
1947
1947
|
declare function projectIntelligenceBriefCommand(options: ProjectIntelligenceBriefOptions): Promise<void>;
|
|
1948
1948
|
|
|
1949
|
+
interface RealityCheckCommandOptions {
|
|
1950
|
+
task?: string;
|
|
1951
|
+
branch?: string;
|
|
1952
|
+
base?: string;
|
|
1953
|
+
changedFiles?: string[];
|
|
1954
|
+
diffSummary?: string;
|
|
1955
|
+
decision?: string[];
|
|
1956
|
+
document?: string[];
|
|
1957
|
+
verification?: string[];
|
|
1958
|
+
includeDirty?: boolean;
|
|
1959
|
+
enforce?: boolean;
|
|
1960
|
+
dir?: string;
|
|
1961
|
+
json?: boolean;
|
|
1962
|
+
}
|
|
1963
|
+
declare function buildLocalProjectRealityCheck(options: RealityCheckCommandOptions): ProjectRealityCheckResult;
|
|
1964
|
+
declare function realityCheckCommand(options: RealityCheckCommandOptions): Promise<void>;
|
|
1965
|
+
|
|
1949
1966
|
interface MemoryHealthCommandOptions {
|
|
1950
1967
|
scope?: MemoryScope;
|
|
1951
1968
|
includeInactive?: boolean;
|
|
@@ -3935,4 +3952,4 @@ declare function buildOrchestratorHandoff(options: OrchestratorHandoffOptions):
|
|
|
3935
3952
|
declare function buildAdaptiveWorkRoutingRecommendation(options: AdaptiveWorkRoutingOptions): AdaptiveWorkRoutingRecommendation;
|
|
3936
3953
|
declare function writeOrchestratorHandoff(options: OrchestratorHandoffOptions): WrittenOrchestratorHandoff;
|
|
3937
3954
|
|
|
3938
|
-
export { AUTOMATION_MANIFEST_RELATIVE_PATH, AutomationInstallConflictError, AutomationUnsupportedHookBundleError, CODING_INTELLIGENCE_LEDGER_VERSION, COLLABORATION_STATE_RELATIVE_PATH, ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES, ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES, ENGINEERING_LEAD_POSTURES, ENGINEERING_LEAD_PROOF_VERIFICATION_SOURCES, ENGINEERING_LEAD_PROOF_VERIFICATION_STATUSES, ENGINEERING_LEAD_ROUTING_MODES, ENGINEERING_LEAD_STATUSES, ENGINEERING_LEAD_SUPERVISION_STATUSES, ENGINEERING_LEAD_WORKER_ROLES, ENGINEERING_LEAD_WORK_PACKAGE_STATUSES, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, TEAM_SYNC_STATE_RELATIVE_PATH, WHY_OUTCOME_CAPTURE_VERSION, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, addLocalWorker, agentReadinessAuditCommand, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCodingIntelligenceLedger, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalShortestPathResult, buildLocalSourceSnapshot, buildLocalSourceStatus, buildLocalSourceSyncResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapQuality, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWhyOutcomeCaptureReport, buildWorkflowImpactGate, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, codingLedgerExportCommand, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, compareLocalSourceSnapshots, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getLocalSourceSnapshotPath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, referencesIngestCommand, referencesScanCommand, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveLocalWorkerRoutingDefaults, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, workersLocalAddCommand, workersLocalStatusCommand, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeLocalSourceSnapshot, writeOrchestratorHandoff };
|
|
3955
|
+
export { AUTOMATION_MANIFEST_RELATIVE_PATH, AutomationInstallConflictError, AutomationUnsupportedHookBundleError, CODING_INTELLIGENCE_LEDGER_VERSION, COLLABORATION_STATE_RELATIVE_PATH, ENGINEERING_LEAD_EXECUTION_RECEIPT_STAGES, ENGINEERING_LEAD_EXECUTION_RECEIPT_STATUSES, ENGINEERING_LEAD_POSTURES, ENGINEERING_LEAD_PROOF_VERIFICATION_SOURCES, ENGINEERING_LEAD_PROOF_VERIFICATION_STATUSES, ENGINEERING_LEAD_ROUTING_MODES, ENGINEERING_LEAD_STATUSES, ENGINEERING_LEAD_SUPERVISION_STATUSES, ENGINEERING_LEAD_WORKER_ROLES, ENGINEERING_LEAD_WORK_PACKAGE_STATUSES, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, TEAM_SYNC_STATE_RELATIVE_PATH, WHY_OUTCOME_CAPTURE_VERSION, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, addLocalWorker, agentReadinessAuditCommand, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCodingIntelligenceLedger, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalProjectRealityCheck, buildLocalShortestPathResult, buildLocalSourceSnapshot, buildLocalSourceStatus, buildLocalSourceSyncResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapQuality, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWhyOutcomeCaptureReport, buildWorkflowImpactGate, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, codingLedgerExportCommand, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, compareLocalSourceSnapshots, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getLocalSourceSnapshotPath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, realityCheckCommand, referencesIngestCommand, referencesScanCommand, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveLocalWorkerRoutingDefaults, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, workersLocalAddCommand, workersLocalStatusCommand, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeLocalSourceSnapshot, writeOrchestratorHandoff };
|
package/dist/index.js
CHANGED
|
@@ -85,6 +85,7 @@ __export(index_exports, {
|
|
|
85
85
|
buildLocalImpactResult: () => buildLocalImpactResult,
|
|
86
86
|
buildLocalImportsResult: () => buildLocalImportsResult,
|
|
87
87
|
buildLocalNeighborsResult: () => buildLocalNeighborsResult,
|
|
88
|
+
buildLocalProjectRealityCheck: () => buildLocalProjectRealityCheck,
|
|
88
89
|
buildLocalShortestPathResult: () => buildLocalShortestPathResult,
|
|
89
90
|
buildLocalSourceSnapshot: () => buildLocalSourceSnapshot,
|
|
90
91
|
buildLocalSourceStatus: () => buildLocalSourceStatus,
|
|
@@ -179,6 +180,7 @@ __export(index_exports, {
|
|
|
179
180
|
readLocalCodePromotionState: () => readLocalCodePromotionState,
|
|
180
181
|
readLocalSourceSnapshot: () => readLocalSourceSnapshot,
|
|
181
182
|
readLocalWorkersConfig: () => readLocalWorkersConfig,
|
|
183
|
+
realityCheckCommand: () => realityCheckCommand,
|
|
182
184
|
referencesIngestCommand: () => referencesIngestCommand,
|
|
183
185
|
referencesScanCommand: () => referencesScanCommand,
|
|
184
186
|
resolveContextPackRecord: () => resolveContextPackRecord,
|
|
@@ -1460,9 +1462,9 @@ var RLMClient = class {
|
|
|
1460
1462
|
...maxTokens ? { max_tokens: maxTokens } : {}
|
|
1461
1463
|
});
|
|
1462
1464
|
}
|
|
1463
|
-
async uploadDocument(
|
|
1465
|
+
async uploadDocument(path28, content, options = {}) {
|
|
1464
1466
|
return this.mcpCall("snipara_upload_document", {
|
|
1465
|
-
path:
|
|
1467
|
+
path: path28,
|
|
1466
1468
|
content,
|
|
1467
1469
|
...options.kind ? { kind: options.kind } : {},
|
|
1468
1470
|
...options.format ? { format: options.format } : {},
|
|
@@ -1549,9 +1551,9 @@ var RLMClient = class {
|
|
|
1549
1551
|
...maxTokens ? { max_tokens: maxTokens } : {}
|
|
1550
1552
|
});
|
|
1551
1553
|
}
|
|
1552
|
-
async loadDocument(
|
|
1554
|
+
async loadDocument(path28) {
|
|
1553
1555
|
return this.mcpCall("snipara_load_document", {
|
|
1554
|
-
path:
|
|
1556
|
+
path: path28
|
|
1555
1557
|
});
|
|
1556
1558
|
}
|
|
1557
1559
|
async getSessionMemories(maxCriticalTokens, maxDailyTokens, includeYesterday) {
|
|
@@ -13430,12 +13432,12 @@ function uniqueStringList(values) {
|
|
|
13430
13432
|
if (!values) {
|
|
13431
13433
|
return void 0;
|
|
13432
13434
|
}
|
|
13433
|
-
const
|
|
13435
|
+
const unique6 = Array.from(
|
|
13434
13436
|
new Set(
|
|
13435
13437
|
values.map((value) => stringValue4(value)).filter((value) => Boolean(value))
|
|
13436
13438
|
)
|
|
13437
13439
|
);
|
|
13438
|
-
return
|
|
13440
|
+
return unique6.length > 0 ? unique6 : void 0;
|
|
13439
13441
|
}
|
|
13440
13442
|
function sanitizeWorkflowId(value, fallback) {
|
|
13441
13443
|
const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
@@ -15680,8 +15682,8 @@ function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = proc
|
|
|
15680
15682
|
};
|
|
15681
15683
|
}
|
|
15682
15684
|
}
|
|
15683
|
-
function printUploadResult(
|
|
15684
|
-
printKeyValue2("Uploaded:",
|
|
15685
|
+
function printUploadResult(path28, result) {
|
|
15686
|
+
printKeyValue2("Uploaded:", path28);
|
|
15685
15687
|
printCompactObject(result, ["message", "document_id", "documentId", "version", "status"]);
|
|
15686
15688
|
console.log("");
|
|
15687
15689
|
printJson2(result);
|
|
@@ -15989,9 +15991,9 @@ function printOrchestrateResult(result) {
|
|
|
15989
15991
|
}
|
|
15990
15992
|
printJson2(result);
|
|
15991
15993
|
}
|
|
15992
|
-
function printLoadDocumentResult(
|
|
15994
|
+
function printLoadDocumentResult(path28, result) {
|
|
15993
15995
|
printKeyValue2("Tool:", "snipara_load_document");
|
|
15994
|
-
printKeyValue2("Path:",
|
|
15996
|
+
printKeyValue2("Path:", path28);
|
|
15995
15997
|
console.log("");
|
|
15996
15998
|
if (typeof result === "string") {
|
|
15997
15999
|
console.log(result.trim());
|
|
@@ -19684,6 +19686,339 @@ var PROJECT_INTELLIGENCE_ENGINEERING_LEAD_PROOF_VERIFICATION_SOURCES = [
|
|
|
19684
19686
|
"manual",
|
|
19685
19687
|
"unknown"
|
|
19686
19688
|
];
|
|
19689
|
+
var PROJECT_REALITY_CHECK_VERSION = "project-reality-check-v0";
|
|
19690
|
+
var SENSITIVE_SURFACES = [
|
|
19691
|
+
{
|
|
19692
|
+
key: "billing_atomicity",
|
|
19693
|
+
label: "Billing or payment settlement",
|
|
19694
|
+
type: "intent_vs_code",
|
|
19695
|
+
patterns: [/billing/i, /payment/i, /settlement/i, /invoice/i, /stripe/i],
|
|
19696
|
+
verificationPatterns: [/test/i, /spec/i, /e2e/i, /vitest/i, /pytest/i],
|
|
19697
|
+
riskTerms: [/async/i, /queue/i, /retry/i, /eventual/i, /background/i, /worker/i],
|
|
19698
|
+
defaultSeverity: "review_required"
|
|
19699
|
+
},
|
|
19700
|
+
{
|
|
19701
|
+
key: "auth_security",
|
|
19702
|
+
label: "Authentication or authorization",
|
|
19703
|
+
type: "verification_vs_claim",
|
|
19704
|
+
patterns: [/auth/i, /session/i, /permission/i, /role/i, /oauth/i, /token/i],
|
|
19705
|
+
verificationPatterns: [/test/i, /spec/i, /e2e/i, /permission/i, /auth/i],
|
|
19706
|
+
riskTerms: [/bypass/i, /public/i, /admin/i, /token/i, /session/i],
|
|
19707
|
+
defaultSeverity: "review_required"
|
|
19708
|
+
},
|
|
19709
|
+
{
|
|
19710
|
+
key: "schema_migration",
|
|
19711
|
+
label: "Database schema or migration",
|
|
19712
|
+
type: "verification_vs_claim",
|
|
19713
|
+
patterns: [/schema\.prisma$/i, /prisma\/migrations/i, /migration/i, /sql$/i],
|
|
19714
|
+
verificationPatterns: [/migration/i, /schema/i, /prisma/i, /test/i],
|
|
19715
|
+
riskTerms: [/drop/i, /delete/i, /reset/i, /force/i, /accept-data-loss/i],
|
|
19716
|
+
defaultSeverity: "review_required"
|
|
19717
|
+
},
|
|
19718
|
+
{
|
|
19719
|
+
key: "package_surface",
|
|
19720
|
+
label: "Published package or agent surface",
|
|
19721
|
+
type: "verification_vs_claim",
|
|
19722
|
+
patterns: [/packages\//i, /package\.json$/i, /CHANGELOG\.md$/i, /README\.md$/i],
|
|
19723
|
+
verificationPatterns: [/pack/i, /smoke/i, /help/i, /test/i, /type-check/i],
|
|
19724
|
+
riskTerms: [/bin/i, /cli/i, /npx/i, /command/i, /public/i],
|
|
19725
|
+
defaultSeverity: "watch"
|
|
19726
|
+
},
|
|
19727
|
+
{
|
|
19728
|
+
key: "deployment_surface",
|
|
19729
|
+
label: "Deployment or production operations",
|
|
19730
|
+
type: "verification_vs_claim",
|
|
19731
|
+
patterns: [/deploy/i, /docker/i, /traefik/i, /infomaniak/i, /production/i],
|
|
19732
|
+
verificationPatterns: [/smoke/i, /health/i, /ready/i, /deploy/i, /test/i],
|
|
19733
|
+
riskTerms: [/production/i, /secret/i, /migrate/i, /zero-downtime/i],
|
|
19734
|
+
defaultSeverity: "review_required"
|
|
19735
|
+
}
|
|
19736
|
+
];
|
|
19737
|
+
var ARCHITECTURE_RULES = [
|
|
19738
|
+
{
|
|
19739
|
+
key: "web_mcp_boundary",
|
|
19740
|
+
title: "Web/MCP runtime boundary needs review",
|
|
19741
|
+
files: [/apps\/web\//i, /apps\/mcp-server\//i]
|
|
19742
|
+
},
|
|
19743
|
+
{
|
|
19744
|
+
key: "database_runtime_boundary",
|
|
19745
|
+
title: "Database contract crosses runtime boundary",
|
|
19746
|
+
files: [/packages\/database\//i, /apps\/mcp-server\/prisma/i, /apps\/web\//i]
|
|
19747
|
+
}
|
|
19748
|
+
];
|
|
19749
|
+
function uniqueStrings8(values) {
|
|
19750
|
+
return [
|
|
19751
|
+
...new Set(
|
|
19752
|
+
values.map((value) => value?.trim()).filter((value) => Boolean(value))
|
|
19753
|
+
)
|
|
19754
|
+
];
|
|
19755
|
+
}
|
|
19756
|
+
function normalizeText(value) {
|
|
19757
|
+
return value?.toLowerCase() ?? "";
|
|
19758
|
+
}
|
|
19759
|
+
function hasPattern(values, patterns) {
|
|
19760
|
+
return values.some((value) => patterns.some((pattern) => pattern.test(value)));
|
|
19761
|
+
}
|
|
19762
|
+
function matchesAnyText(text, patterns) {
|
|
19763
|
+
return patterns.some((pattern) => pattern.test(text));
|
|
19764
|
+
}
|
|
19765
|
+
function findingSeverityScore(severity) {
|
|
19766
|
+
if (severity === "blocking") return 0;
|
|
19767
|
+
if (severity === "review_required") return 30;
|
|
19768
|
+
if (severity === "watch") return 70;
|
|
19769
|
+
return 90;
|
|
19770
|
+
}
|
|
19771
|
+
function resultStatusFromFindings(findings) {
|
|
19772
|
+
if (findings.some((finding) => finding.severity === "blocking")) return "blocking";
|
|
19773
|
+
if (findings.some((finding) => finding.severity === "review_required")) return "review_required";
|
|
19774
|
+
if (findings.some((finding) => finding.severity === "watch")) return "advisory";
|
|
19775
|
+
return "pass";
|
|
19776
|
+
}
|
|
19777
|
+
function makeFindingId(type, key, files) {
|
|
19778
|
+
const compactFiles = files.slice(0, 3).map(
|
|
19779
|
+
(file) => file.replace(/[^a-z0-9]+/gi, "-").replace(/^-|-$/g, "").toLowerCase()
|
|
19780
|
+
).filter(Boolean).join("-");
|
|
19781
|
+
return ["reality", type, key, compactFiles || "project"].join(":").slice(0, 180);
|
|
19782
|
+
}
|
|
19783
|
+
function decisionMatchesChangedFiles(decision, changedFiles) {
|
|
19784
|
+
const anchors = decision.affectedAnchors ?? [];
|
|
19785
|
+
if (anchors.length === 0) return false;
|
|
19786
|
+
return anchors.some(
|
|
19787
|
+
(anchor) => changedFiles.some((file) => file.includes(anchor) || anchor.includes(file))
|
|
19788
|
+
);
|
|
19789
|
+
}
|
|
19790
|
+
function decisionText(decision) {
|
|
19791
|
+
return [
|
|
19792
|
+
decision.title,
|
|
19793
|
+
decision.decision,
|
|
19794
|
+
decision.rationale,
|
|
19795
|
+
decision.scope,
|
|
19796
|
+
...decision.constraints ?? []
|
|
19797
|
+
].filter(Boolean).join(" ");
|
|
19798
|
+
}
|
|
19799
|
+
function surfaceFiles(surface, changedFiles) {
|
|
19800
|
+
return changedFiles.filter((file) => surface.patterns.some((pattern) => pattern.test(file)));
|
|
19801
|
+
}
|
|
19802
|
+
function testFiles(changedFiles) {
|
|
19803
|
+
return changedFiles.filter(
|
|
19804
|
+
(file) => /(^|\/)(__tests__|tests?|e2e)(\/|$)|(\.test|\.spec)\.[jt]sx?$/i.test(file)
|
|
19805
|
+
);
|
|
19806
|
+
}
|
|
19807
|
+
function docEvidence(input) {
|
|
19808
|
+
return (input.documents ?? []).slice(0, 5).map((doc) => ({
|
|
19809
|
+
kind: "document",
|
|
19810
|
+
label: doc.title ? `${doc.path}: ${doc.title}` : doc.path,
|
|
19811
|
+
sourceRef: doc.sourceRef ?? doc.path,
|
|
19812
|
+
strength: 0.6
|
|
19813
|
+
}));
|
|
19814
|
+
}
|
|
19815
|
+
function symbolEvidence(input) {
|
|
19816
|
+
return (input.symbols ?? []).slice(0, 5).map((symbol) => ({
|
|
19817
|
+
kind: "code",
|
|
19818
|
+
label: `${symbol.qualifiedName} (${symbol.modulePath})`,
|
|
19819
|
+
sourceRef: symbol.modulePath,
|
|
19820
|
+
strength: 0.7
|
|
19821
|
+
}));
|
|
19822
|
+
}
|
|
19823
|
+
function decisionEvidence(decisions) {
|
|
19824
|
+
return decisions.slice(0, 5).map((decision) => ({
|
|
19825
|
+
kind: "decision",
|
|
19826
|
+
label: `${decision.id}: ${decision.title}`,
|
|
19827
|
+
sourceRef: decision.id,
|
|
19828
|
+
strength: decision.confidenceScore ?? 0.8
|
|
19829
|
+
}));
|
|
19830
|
+
}
|
|
19831
|
+
function buildProjectRealityCheck(input) {
|
|
19832
|
+
const changedFiles = uniqueStrings8(input.changedFiles);
|
|
19833
|
+
const dirtyFiles = uniqueStrings8(input.dirtyFiles ?? []);
|
|
19834
|
+
const diffText = normalizeText(input.diffSummary);
|
|
19835
|
+
const tests = testFiles(changedFiles);
|
|
19836
|
+
const findings = [];
|
|
19837
|
+
const decisions = input.decisions ?? [];
|
|
19838
|
+
const contextEvidence2 = [...docEvidence(input), ...symbolEvidence(input)];
|
|
19839
|
+
for (const surface of SENSITIVE_SURFACES) {
|
|
19840
|
+
const files = surfaceFiles(surface, changedFiles);
|
|
19841
|
+
if (files.length === 0) continue;
|
|
19842
|
+
const relatedDecisions = decisions.filter(
|
|
19843
|
+
(decision) => decisionMatchesChangedFiles(decision, files) || matchesAnyText(normalizeText(decisionText(decision)), surface.patterns)
|
|
19844
|
+
);
|
|
19845
|
+
const hasVerification = tests.length > 0 || hasPattern(input.verificationChecklist ?? [], surface.verificationPatterns);
|
|
19846
|
+
const hasRiskTerm = matchesAnyText(diffText, surface.riskTerms);
|
|
19847
|
+
const severity = surface.defaultSeverity === "watch" ? relatedDecisions.length > 0 && !hasVerification ? "review_required" : "watch" : hasVerification && !hasRiskTerm ? "watch" : surface.defaultSeverity;
|
|
19848
|
+
const reasonCodes2 = uniqueStrings8([
|
|
19849
|
+
surface.key,
|
|
19850
|
+
relatedDecisions.length > 0 ? "linked_decision_touched" : "no_linked_decision",
|
|
19851
|
+
hasVerification ? "verification_present" : "verification_missing",
|
|
19852
|
+
hasRiskTerm ? "risk_term_in_diff" : void 0
|
|
19853
|
+
]);
|
|
19854
|
+
const recommendedActions = [
|
|
19855
|
+
hasVerification ? `Verify the ${surface.label.toLowerCase()} tests cover the changed behavior.` : `Add or cite verification for the ${surface.label.toLowerCase()} change before merge.`,
|
|
19856
|
+
relatedDecisions.length > 0 ? "Review the linked decision intent and supersede it if the implementation intentionally changes the rule." : "Capture or link the governing intent if this surface has no reviewed decision."
|
|
19857
|
+
];
|
|
19858
|
+
findings.push({
|
|
19859
|
+
id: makeFindingId(surface.type, surface.key, files),
|
|
19860
|
+
type: surface.type,
|
|
19861
|
+
severity,
|
|
19862
|
+
title: `${surface.label} needs a reality check`,
|
|
19863
|
+
summary: `${files.length} changed file(s) touch ${surface.label.toLowerCase()} with ${relatedDecisions.length > 0 ? `${relatedDecisions.length} linked decision(s)` : "no linked decision"} and ${hasVerification ? "some verification evidence" : "no obvious verification evidence"}.`,
|
|
19864
|
+
changedFiles: files.slice(0, 12),
|
|
19865
|
+
decisionIds: relatedDecisions.map((decision) => decision.id).slice(0, 8),
|
|
19866
|
+
evidence: [...decisionEvidence(relatedDecisions), ...contextEvidence2].slice(0, 8),
|
|
19867
|
+
reasonCodes: reasonCodes2,
|
|
19868
|
+
recommendedActions,
|
|
19869
|
+
caveats: [
|
|
19870
|
+
"V0 uses path, decision, document, and verification signals; it does not prove semantic causality."
|
|
19871
|
+
]
|
|
19872
|
+
});
|
|
19873
|
+
}
|
|
19874
|
+
for (const rule of ARCHITECTURE_RULES) {
|
|
19875
|
+
const matchedGroups = rule.files.filter(
|
|
19876
|
+
(patterns) => changedFiles.some((file) => patterns.test(file))
|
|
19877
|
+
);
|
|
19878
|
+
if (matchedGroups.length < 2) continue;
|
|
19879
|
+
const files = changedFiles.filter((file) => rule.files.some((pattern) => pattern.test(file)));
|
|
19880
|
+
findings.push({
|
|
19881
|
+
id: makeFindingId("architecture_drift", rule.key, files),
|
|
19882
|
+
type: "architecture_drift",
|
|
19883
|
+
severity: "watch",
|
|
19884
|
+
title: rule.title,
|
|
19885
|
+
summary: "This change spans architectural boundaries. Verify that the dependency direction and runtime ownership still match the intended architecture.",
|
|
19886
|
+
changedFiles: files.slice(0, 12),
|
|
19887
|
+
decisionIds: [],
|
|
19888
|
+
evidence: contextEvidence2.slice(0, 6),
|
|
19889
|
+
reasonCodes: [rule.key, "cross_boundary_change"],
|
|
19890
|
+
recommendedActions: [
|
|
19891
|
+
"Check that the changed modules do not introduce a forbidden runtime dependency.",
|
|
19892
|
+
"Document the boundary intent if this cross-boundary change is intentional."
|
|
19893
|
+
],
|
|
19894
|
+
caveats: [
|
|
19895
|
+
"Architecture drift V0 is boundary-based; import-level drift needs code graph confirmation."
|
|
19896
|
+
]
|
|
19897
|
+
});
|
|
19898
|
+
}
|
|
19899
|
+
if (changedFiles.length > 0 && decisions.length === 0 && (input.source === "pull_request" || findings.length > 0)) {
|
|
19900
|
+
findings.push({
|
|
19901
|
+
id: makeFindingId("decision_vs_code", "missing_intent", changedFiles),
|
|
19902
|
+
type: "decision_vs_code",
|
|
19903
|
+
severity: findings.some((finding) => finding.severity === "review_required") ? "watch" : "info",
|
|
19904
|
+
title: "No governing intent was linked",
|
|
19905
|
+
summary: "No reviewed decision or intent was linked to this change. This is an unknown, not proof that no constraint exists.",
|
|
19906
|
+
changedFiles: changedFiles.slice(0, 12),
|
|
19907
|
+
decisionIds: [],
|
|
19908
|
+
evidence: contextEvidence2.slice(0, 6),
|
|
19909
|
+
reasonCodes: ["missing_intent", "unknown_governing_decision"],
|
|
19910
|
+
recommendedActions: [
|
|
19911
|
+
"Link an existing decision or capture a review-pending intent if this change establishes a durable rule."
|
|
19912
|
+
],
|
|
19913
|
+
caveats: [
|
|
19914
|
+
"A missing linked decision can reflect retrieval/index freshness rather than missing project truth."
|
|
19915
|
+
]
|
|
19916
|
+
});
|
|
19917
|
+
}
|
|
19918
|
+
if (dirtyFiles.length > 0 && input.source === "local") {
|
|
19919
|
+
findings.push({
|
|
19920
|
+
id: makeFindingId("verification_vs_claim", "dirty_worktree", dirtyFiles),
|
|
19921
|
+
type: "verification_vs_claim",
|
|
19922
|
+
severity: "watch",
|
|
19923
|
+
title: "Dirty local files are part of the reality check",
|
|
19924
|
+
summary: `${dirtyFiles.length} dirty file(s) were included in the local scan; verify they are intentional before push.`,
|
|
19925
|
+
changedFiles: dirtyFiles.slice(0, 12),
|
|
19926
|
+
decisionIds: [],
|
|
19927
|
+
evidence: dirtyFiles.slice(0, 6).map((file) => ({
|
|
19928
|
+
kind: "repository",
|
|
19929
|
+
label: file,
|
|
19930
|
+
sourceRef: file,
|
|
19931
|
+
strength: 0.5
|
|
19932
|
+
})),
|
|
19933
|
+
reasonCodes: ["dirty_working_tree"],
|
|
19934
|
+
recommendedActions: [
|
|
19935
|
+
"Review dirty files separately from committed PR or upstream diff evidence."
|
|
19936
|
+
],
|
|
19937
|
+
caveats: [
|
|
19938
|
+
"Dirty working-tree evidence is local-only and will not exist in hosted PR checks until committed."
|
|
19939
|
+
]
|
|
19940
|
+
});
|
|
19941
|
+
}
|
|
19942
|
+
const status = resultStatusFromFindings(findings);
|
|
19943
|
+
const score = findings.length === 0 ? 95 : Math.max(
|
|
19944
|
+
0,
|
|
19945
|
+
Math.min(
|
|
19946
|
+
100,
|
|
19947
|
+
Math.round(
|
|
19948
|
+
Math.min(...findings.map((finding) => findingSeverityScore(finding.severity))) - Math.max(0, findings.length - 1) * 4
|
|
19949
|
+
)
|
|
19950
|
+
)
|
|
19951
|
+
);
|
|
19952
|
+
const requiredActions = uniqueStrings8(
|
|
19953
|
+
findings.filter(
|
|
19954
|
+
(finding) => finding.severity === "review_required" || finding.severity === "blocking"
|
|
19955
|
+
).flatMap((finding) => finding.recommendedActions)
|
|
19956
|
+
).slice(0, 10);
|
|
19957
|
+
const watchItems = uniqueStrings8(
|
|
19958
|
+
findings.filter((finding) => finding.severity === "watch" || finding.severity === "info").map((finding) => finding.summary)
|
|
19959
|
+
).slice(0, 10);
|
|
19960
|
+
const reasonCodes = uniqueStrings8(findings.flatMap((finding) => finding.reasonCodes)).slice(
|
|
19961
|
+
0,
|
|
19962
|
+
20
|
|
19963
|
+
);
|
|
19964
|
+
const caveats = uniqueStrings8([
|
|
19965
|
+
"Project Reality Check V0 is advisory and evidence-backed; it is not deterministic repository simulation.",
|
|
19966
|
+
input.source === "local" ? "Local results may include dirty files that hosted PR checks cannot see." : "PR results are scoped to GitHub-provided PR files and indexed Snipara context."
|
|
19967
|
+
]);
|
|
19968
|
+
return {
|
|
19969
|
+
version: PROJECT_REALITY_CHECK_VERSION,
|
|
19970
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19971
|
+
status,
|
|
19972
|
+
score,
|
|
19973
|
+
source: input.source,
|
|
19974
|
+
summary: findings.length === 0 ? "No contradiction-to-reality finding was detected for this scope." : `${findings.length} reality check finding(s): ${status.replace("_", " ")}.`,
|
|
19975
|
+
changedFileCount: changedFiles.length,
|
|
19976
|
+
findingCount: findings.length,
|
|
19977
|
+
findings,
|
|
19978
|
+
requiredActions,
|
|
19979
|
+
watchItems,
|
|
19980
|
+
reasonCodes,
|
|
19981
|
+
caveats
|
|
19982
|
+
};
|
|
19983
|
+
}
|
|
19984
|
+
function renderProjectRealityCheckMarkdown(result) {
|
|
19985
|
+
const lines = [
|
|
19986
|
+
`- Status: ${result.status}; score ${result.score}/100.`,
|
|
19987
|
+
`- Scope: ${result.changedFileCount} changed file(s), ${result.findingCount} finding(s).`,
|
|
19988
|
+
`- Summary: ${result.summary}`
|
|
19989
|
+
];
|
|
19990
|
+
if (result.findings.length > 0) {
|
|
19991
|
+
lines.push("", "Findings:");
|
|
19992
|
+
for (const finding of result.findings.slice(0, 8)) {
|
|
19993
|
+
lines.push(
|
|
19994
|
+
`- ${finding.severity.toUpperCase()} ${finding.type}: ${finding.title}`,
|
|
19995
|
+
` ${finding.summary}`
|
|
19996
|
+
);
|
|
19997
|
+
if (finding.changedFiles.length > 0) {
|
|
19998
|
+
lines.push(` Files: ${finding.changedFiles.map((file) => `\`${file}\``).join(", ")}`);
|
|
19999
|
+
}
|
|
20000
|
+
if (finding.decisionIds.length > 0) {
|
|
20001
|
+
lines.push(` Decisions: ${finding.decisionIds.join(", ")}`);
|
|
20002
|
+
}
|
|
20003
|
+
if (finding.recommendedActions.length > 0) {
|
|
20004
|
+
lines.push(` Action: ${finding.recommendedActions[0]}`);
|
|
20005
|
+
}
|
|
20006
|
+
}
|
|
20007
|
+
}
|
|
20008
|
+
if (result.requiredActions.length > 0) {
|
|
20009
|
+
lines.push("", "Required actions:");
|
|
20010
|
+
lines.push(...result.requiredActions.map((action) => `- ${action}`));
|
|
20011
|
+
}
|
|
20012
|
+
if (result.watchItems.length > 0) {
|
|
20013
|
+
lines.push("", "Watch items:");
|
|
20014
|
+
lines.push(...result.watchItems.map((item) => `- ${item}`));
|
|
20015
|
+
}
|
|
20016
|
+
if (result.caveats.length > 0) {
|
|
20017
|
+
lines.push("", "Caveats:");
|
|
20018
|
+
lines.push(...result.caveats.map((caveat) => `- ${caveat}`));
|
|
20019
|
+
}
|
|
20020
|
+
return lines.join("\n");
|
|
20021
|
+
}
|
|
19687
20022
|
|
|
19688
20023
|
// src/commands/execution-receipts.ts
|
|
19689
20024
|
var ENGINEERING_LEAD_PROOF_VERIFICATION_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1e3;
|
|
@@ -21378,7 +21713,7 @@ function normalizeCaptureEvent(event, now, index) {
|
|
|
21378
21713
|
const reasons = normalizeStringList3(event.reason).map(redactText);
|
|
21379
21714
|
const evidence = normalizeStringList3(event.evidence).map(redactText);
|
|
21380
21715
|
const commands = normalizeStringList3(event.commands).map(redactText);
|
|
21381
|
-
const redactionPatterns =
|
|
21716
|
+
const redactionPatterns = uniqueStrings9([
|
|
21382
21717
|
...summary.patterns,
|
|
21383
21718
|
...outcome.patterns,
|
|
21384
21719
|
...status.patterns,
|
|
@@ -21411,7 +21746,7 @@ function normalizeEventKind(value) {
|
|
|
21411
21746
|
return "feedback";
|
|
21412
21747
|
}
|
|
21413
21748
|
function reasonCodesForEvent(event, kind, status) {
|
|
21414
|
-
return
|
|
21749
|
+
return uniqueStrings9([
|
|
21415
21750
|
"why_outcome_capture_v1",
|
|
21416
21751
|
"review_pending_authority",
|
|
21417
21752
|
`source_${event.kind}`,
|
|
@@ -21476,7 +21811,7 @@ function readEventsFromFile(filePath) {
|
|
|
21476
21811
|
function stableHash(parts) {
|
|
21477
21812
|
return (0, import_node_crypto3.createHash)("sha256").update(parts.join("\0")).digest("hex");
|
|
21478
21813
|
}
|
|
21479
|
-
function
|
|
21814
|
+
function uniqueStrings9(values) {
|
|
21480
21815
|
return Array.from(new Set(values.filter(Boolean)));
|
|
21481
21816
|
}
|
|
21482
21817
|
function compactWhitespace2(value) {
|
|
@@ -21574,7 +21909,7 @@ function createRedactor(rootDir) {
|
|
|
21574
21909
|
patterns.add(item.name);
|
|
21575
21910
|
item.pattern.lastIndex = 0;
|
|
21576
21911
|
}
|
|
21577
|
-
const uniqueMatchedPatterns =
|
|
21912
|
+
const uniqueMatchedPatterns = uniqueStrings10(matchedPatterns);
|
|
21578
21913
|
if (uniqueMatchedPatterns.length > 0) {
|
|
21579
21914
|
redactedValueCount += 1;
|
|
21580
21915
|
}
|
|
@@ -21689,14 +22024,14 @@ function buildRepoState(input, options, rootDir, redactor) {
|
|
|
21689
22024
|
const inputRepo = inputRecord(input, "repoState", "repo_state", "repo");
|
|
21690
22025
|
const detected = detectGitState(rootDir);
|
|
21691
22026
|
const statusCounts = countGitStatus(detected.statusLines);
|
|
21692
|
-
const changedFiles =
|
|
22027
|
+
const changedFiles = uniqueStrings10([
|
|
21693
22028
|
...normalizeUnknownStringList(inputRepo.changedFiles),
|
|
21694
22029
|
...normalizeUnknownStringList(inputRepo.changed_files),
|
|
21695
22030
|
...normalizeUnknownStringList(input.changedFiles),
|
|
21696
22031
|
...normalizeUnknownStringList(input.changed_files),
|
|
21697
22032
|
...options.changedFiles ?? []
|
|
21698
22033
|
]).map((item) => redactor.redact(item).value);
|
|
21699
|
-
const recentFiles =
|
|
22034
|
+
const recentFiles = uniqueStrings10([
|
|
21700
22035
|
...normalizeUnknownStringList(inputRepo.recentFiles),
|
|
21701
22036
|
...normalizeUnknownStringList(inputRepo.recent_files),
|
|
21702
22037
|
...normalizeUnknownStringList(input.recentFiles),
|
|
@@ -21764,18 +22099,18 @@ function normalizeEvidenceItem(value, section, index, redactor) {
|
|
|
21764
22099
|
"command",
|
|
21765
22100
|
"check"
|
|
21766
22101
|
]) ?? fallbackSummary(value, section, index);
|
|
21767
|
-
const reasonCodes =
|
|
22102
|
+
const reasonCodes = uniqueStrings10([
|
|
21768
22103
|
`section_${section}`,
|
|
21769
22104
|
...normalizeUnknownStringList(value.reasonCodes),
|
|
21770
22105
|
...normalizeUnknownStringList(value.reason_codes)
|
|
21771
22106
|
]).map((item) => redactor.redact(item).value);
|
|
21772
|
-
const files =
|
|
22107
|
+
const files = uniqueStrings10([
|
|
21773
22108
|
...normalizeUnknownStringList(value.files),
|
|
21774
22109
|
...normalizeUnknownStringList(value.changedFiles),
|
|
21775
22110
|
...normalizeUnknownStringList(value.changed_files),
|
|
21776
22111
|
...normalizeUnknownStringList(value.file)
|
|
21777
22112
|
]).slice(0, MAX_LIST_ITEMS2).map((item) => redactor.redact(item).value);
|
|
21778
|
-
const commands =
|
|
22113
|
+
const commands = uniqueStrings10([
|
|
21779
22114
|
...normalizeUnknownStringList(value.commands),
|
|
21780
22115
|
...normalizeUnknownStringList(value.command),
|
|
21781
22116
|
...normalizeUnknownStringList(value.checks),
|
|
@@ -21799,7 +22134,7 @@ function normalizeEvidenceItem(value, section, index, redactor) {
|
|
|
21799
22134
|
});
|
|
21800
22135
|
}
|
|
21801
22136
|
function collectReasonCodes(input, cliValues, items, redactor) {
|
|
21802
|
-
return
|
|
22137
|
+
return uniqueStrings10([
|
|
21803
22138
|
"coding_intelligence_ledger_v0",
|
|
21804
22139
|
...normalizeUnknownStringList(input.reasonCodes),
|
|
21805
22140
|
...normalizeUnknownStringList(input.reason_codes),
|
|
@@ -21830,13 +22165,13 @@ function buildCalibrationMetadata(input, cliValues, redactor) {
|
|
|
21830
22165
|
"calibration",
|
|
21831
22166
|
"calibration_metadata"
|
|
21832
22167
|
);
|
|
21833
|
-
const notes =
|
|
22168
|
+
const notes = uniqueStrings10([
|
|
21834
22169
|
...normalizeUnknownStringList(calibration.notes),
|
|
21835
22170
|
...normalizeUnknownStringList(calibration.note),
|
|
21836
22171
|
...normalizeUnknownStringList(input.calibrationNotes),
|
|
21837
22172
|
...cliValues ?? []
|
|
21838
22173
|
]).slice(0, MAX_LIST_ITEMS2).map((item) => redactor.redact(item).value);
|
|
21839
|
-
const caveats =
|
|
22174
|
+
const caveats = uniqueStrings10([
|
|
21840
22175
|
...normalizeUnknownStringList(calibration.caveats),
|
|
21841
22176
|
...normalizeUnknownStringList(calibration.caveat),
|
|
21842
22177
|
...normalizeUnknownStringList(input.calibrationCaveats)
|
|
@@ -22033,7 +22368,7 @@ function validIso(value) {
|
|
|
22033
22368
|
const date = new Date(value);
|
|
22034
22369
|
return Number.isNaN(date.getTime()) ? void 0 : date.toISOString();
|
|
22035
22370
|
}
|
|
22036
|
-
function
|
|
22371
|
+
function uniqueStrings10(values) {
|
|
22037
22372
|
return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
|
|
22038
22373
|
}
|
|
22039
22374
|
function compactWhitespace3(value) {
|
|
@@ -23516,14 +23851,154 @@ async function projectIntelligenceBriefCommand(options) {
|
|
|
23516
23851
|
}
|
|
23517
23852
|
}
|
|
23518
23853
|
|
|
23854
|
+
// src/commands/reality-check.ts
|
|
23855
|
+
var import_node_child_process8 = require("child_process");
|
|
23856
|
+
var import_node_path = __toESM(require("path"));
|
|
23857
|
+
var import_chalk10 = __toESM(require("chalk"));
|
|
23858
|
+
function runGit2(args, cwd, options = {}) {
|
|
23859
|
+
try {
|
|
23860
|
+
const output = (0, import_node_child_process8.execFileSync)("git", args, {
|
|
23861
|
+
cwd,
|
|
23862
|
+
encoding: "utf8",
|
|
23863
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
23864
|
+
timeout: 5e3
|
|
23865
|
+
});
|
|
23866
|
+
return options.preserveLeadingWhitespace ? output.trimEnd() : output.trim();
|
|
23867
|
+
} catch {
|
|
23868
|
+
return void 0;
|
|
23869
|
+
}
|
|
23870
|
+
}
|
|
23871
|
+
function splitLines(value) {
|
|
23872
|
+
return value ? value.split(/\r?\n/g).map((line) => line.trim()).filter(Boolean) : [];
|
|
23873
|
+
}
|
|
23874
|
+
function unique5(values) {
|
|
23875
|
+
return [
|
|
23876
|
+
...new Set(
|
|
23877
|
+
values.map((value) => value?.trim()).filter((value) => Boolean(value))
|
|
23878
|
+
)
|
|
23879
|
+
];
|
|
23880
|
+
}
|
|
23881
|
+
function parseDirtyFile(line) {
|
|
23882
|
+
if (!line.trim()) return void 0;
|
|
23883
|
+
const withoutStatus = line.length >= 3 ? line.slice(3).trim() : line.trim();
|
|
23884
|
+
const renameParts = withoutStatus.split(" -> ");
|
|
23885
|
+
return renameParts[renameParts.length - 1]?.replace(/^"|"$/g, "");
|
|
23886
|
+
}
|
|
23887
|
+
function resolveGitRoot(cwd) {
|
|
23888
|
+
return runGit2(["rev-parse", "--show-toplevel"], cwd) ?? cwd;
|
|
23889
|
+
}
|
|
23890
|
+
function resolveBaseRef(root, explicitBase) {
|
|
23891
|
+
if (explicitBase) return explicitBase;
|
|
23892
|
+
return runGit2(["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], root) ?? void 0;
|
|
23893
|
+
}
|
|
23894
|
+
function buildLocalGitScope(options) {
|
|
23895
|
+
const requestedRoot = import_node_path.default.resolve(options.dir ?? process.cwd());
|
|
23896
|
+
const workspaceRoot = findWorkspaceRoot(requestedRoot, true) ?? requestedRoot;
|
|
23897
|
+
const root = resolveGitRoot(workspaceRoot);
|
|
23898
|
+
const branch = options.branch ?? runGit2(["rev-parse", "--abbrev-ref", "HEAD"], root);
|
|
23899
|
+
const baseRef = resolveBaseRef(root, options.base);
|
|
23900
|
+
const headRef = runGit2(["rev-parse", "--verify", "HEAD"], root);
|
|
23901
|
+
const statusLines = runGit2(["status", "--short"], root, { preserveLeadingWhitespace: true })?.split(/\r?\n/g).filter((line) => line.trim()) ?? [];
|
|
23902
|
+
const dirtyFiles = unique5(statusLines.map(parseDirtyFile));
|
|
23903
|
+
const committedFiles = baseRef ? splitLines(runGit2(["diff", "--name-only", `${baseRef}...HEAD`], root)) : [];
|
|
23904
|
+
const cachedFiles = splitLines(runGit2(["diff", "--cached", "--name-only"], root));
|
|
23905
|
+
const unstagedFiles = splitLines(runGit2(["diff", "--name-only"], root));
|
|
23906
|
+
const changedFiles = unique5([
|
|
23907
|
+
...options.changedFiles ?? [],
|
|
23908
|
+
...committedFiles,
|
|
23909
|
+
...cachedFiles,
|
|
23910
|
+
...options.includeDirty === false ? [] : unstagedFiles
|
|
23911
|
+
]);
|
|
23912
|
+
const diffSummary = options.diffSummary ?? [
|
|
23913
|
+
baseRef ? runGit2(["diff", "--stat", `${baseRef}...HEAD`], root) : void 0,
|
|
23914
|
+
options.includeDirty === false ? void 0 : runGit2(["diff", "--stat"], root)
|
|
23915
|
+
].filter(Boolean).join("\n");
|
|
23916
|
+
const caveats = [
|
|
23917
|
+
baseRef ? void 0 : "No upstream/base ref was resolved; local reality check used dirty/cached files only.",
|
|
23918
|
+
dirtyFiles.length > 0 && options.includeDirty === false ? "Dirty files were detected but excluded by --no-include-dirty." : void 0
|
|
23919
|
+
].filter((item) => Boolean(item));
|
|
23920
|
+
return {
|
|
23921
|
+
root,
|
|
23922
|
+
...branch && branch !== "HEAD" ? { branch } : {},
|
|
23923
|
+
...baseRef ? { baseRef } : {},
|
|
23924
|
+
...headRef ? { headRef } : {},
|
|
23925
|
+
changedFiles,
|
|
23926
|
+
dirtyFiles: options.includeDirty === false ? [] : dirtyFiles,
|
|
23927
|
+
...diffSummary ? { diffSummary } : {},
|
|
23928
|
+
caveats
|
|
23929
|
+
};
|
|
23930
|
+
}
|
|
23931
|
+
function parseDecision(value, index) {
|
|
23932
|
+
const [rawId, ...rest] = value.split(":");
|
|
23933
|
+
const hasExplicitId = rest.length > 0 && rawId.trim().length > 0;
|
|
23934
|
+
const id = hasExplicitId ? rawId.trim() : `local-decision-${index + 1}`;
|
|
23935
|
+
const title = hasExplicitId ? rest.join(":").trim() : value.trim();
|
|
23936
|
+
return {
|
|
23937
|
+
id,
|
|
23938
|
+
title: title || id,
|
|
23939
|
+
decision: title || value,
|
|
23940
|
+
confidenceScore: 0.75
|
|
23941
|
+
};
|
|
23942
|
+
}
|
|
23943
|
+
function parseDocument(value) {
|
|
23944
|
+
const [rawPath, ...rest] = value.split(":");
|
|
23945
|
+
return {
|
|
23946
|
+
path: rawPath.trim() || value,
|
|
23947
|
+
contentPreview: rest.join(":").trim() || null
|
|
23948
|
+
};
|
|
23949
|
+
}
|
|
23950
|
+
function buildLocalProjectRealityCheck(options) {
|
|
23951
|
+
const scope = buildLocalGitScope(options);
|
|
23952
|
+
const result = buildProjectRealityCheck({
|
|
23953
|
+
source: "local",
|
|
23954
|
+
task: options.task,
|
|
23955
|
+
branch: scope.branch,
|
|
23956
|
+
baseRef: scope.baseRef,
|
|
23957
|
+
headRef: scope.headRef,
|
|
23958
|
+
changedFiles: scope.changedFiles,
|
|
23959
|
+
dirtyFiles: scope.dirtyFiles,
|
|
23960
|
+
diffSummary: scope.diffSummary,
|
|
23961
|
+
decisions: (options.decision ?? []).map(parseDecision),
|
|
23962
|
+
documents: (options.document ?? []).map(parseDocument),
|
|
23963
|
+
verificationChecklist: options.verification ?? []
|
|
23964
|
+
});
|
|
23965
|
+
if (scope.caveats.length === 0) {
|
|
23966
|
+
return result;
|
|
23967
|
+
}
|
|
23968
|
+
return {
|
|
23969
|
+
...result,
|
|
23970
|
+
caveats: [...result.caveats, ...scope.caveats]
|
|
23971
|
+
};
|
|
23972
|
+
}
|
|
23973
|
+
function printRealityCheck(result) {
|
|
23974
|
+
console.log(import_chalk10.default.bold("Project Reality Check"));
|
|
23975
|
+
console.log(`Status: ${result.status}`);
|
|
23976
|
+
console.log(`Score: ${result.score}/100`);
|
|
23977
|
+
console.log(`Changed files: ${result.changedFileCount}`);
|
|
23978
|
+
console.log(`Findings: ${result.findingCount}`);
|
|
23979
|
+
console.log("");
|
|
23980
|
+
console.log(renderProjectRealityCheckMarkdown(result));
|
|
23981
|
+
}
|
|
23982
|
+
async function realityCheckCommand(options) {
|
|
23983
|
+
const result = buildLocalProjectRealityCheck(options);
|
|
23984
|
+
if (options.json) {
|
|
23985
|
+
console.log(JSON.stringify(result, null, 2));
|
|
23986
|
+
} else {
|
|
23987
|
+
printRealityCheck(result);
|
|
23988
|
+
}
|
|
23989
|
+
if (options.enforce && (result.status === "review_required" || result.status === "blocking")) {
|
|
23990
|
+
process.exitCode = 1;
|
|
23991
|
+
}
|
|
23992
|
+
}
|
|
23993
|
+
|
|
23519
23994
|
// src/commands/references.ts
|
|
23520
23995
|
var crypto6 = __toESM(require("crypto"));
|
|
23521
23996
|
var fs25 = __toESM(require("fs"));
|
|
23522
|
-
var
|
|
23523
|
-
var
|
|
23997
|
+
var path25 = __toESM(require("path"));
|
|
23998
|
+
var import_chalk11 = __toESM(require("chalk"));
|
|
23524
23999
|
var MANIFEST_VERSION2 = "snipara.references.v1";
|
|
23525
|
-
var DEFAULT_MANIFEST_PATH =
|
|
23526
|
-
var DEFAULT_SNAPSHOT_DIR =
|
|
24000
|
+
var DEFAULT_MANIFEST_PATH = path25.join(".snipara", "references", "manifest.json");
|
|
24001
|
+
var DEFAULT_SNAPSHOT_DIR = path25.join(".snipara", "references", "snapshots");
|
|
23527
24002
|
var DEFAULT_DESTINATION_PREFIX = "external-references";
|
|
23528
24003
|
var DEFAULT_SCAN_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx", ".txt", ".rst"]);
|
|
23529
24004
|
var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -23599,10 +24074,10 @@ function sanitizeSegment(value, fallback) {
|
|
|
23599
24074
|
return sanitized || fallback;
|
|
23600
24075
|
}
|
|
23601
24076
|
function toRelative(root, file) {
|
|
23602
|
-
return
|
|
24077
|
+
return path25.relative(root, file).split(path25.sep).join("/");
|
|
23603
24078
|
}
|
|
23604
24079
|
function ensureParentDir(file) {
|
|
23605
|
-
fs25.mkdirSync(
|
|
24080
|
+
fs25.mkdirSync(path25.dirname(file), { recursive: true });
|
|
23606
24081
|
}
|
|
23607
24082
|
function walkFiles(root, extensions, maxFiles, files = []) {
|
|
23608
24083
|
if (files.length >= maxFiles) {
|
|
@@ -23612,14 +24087,14 @@ function walkFiles(root, extensions, maxFiles, files = []) {
|
|
|
23612
24087
|
if (files.length >= maxFiles) {
|
|
23613
24088
|
break;
|
|
23614
24089
|
}
|
|
23615
|
-
const fullPath =
|
|
24090
|
+
const fullPath = path25.join(root, entry.name);
|
|
23616
24091
|
if (entry.isDirectory()) {
|
|
23617
24092
|
if (!DEFAULT_IGNORE_DIRS.has(entry.name)) {
|
|
23618
24093
|
walkFiles(fullPath, extensions, maxFiles, files);
|
|
23619
24094
|
}
|
|
23620
24095
|
continue;
|
|
23621
24096
|
}
|
|
23622
|
-
if (entry.isFile() && extensions.has(
|
|
24097
|
+
if (entry.isFile() && extensions.has(path25.extname(entry.name).toLowerCase())) {
|
|
23623
24098
|
files.push(fullPath);
|
|
23624
24099
|
}
|
|
23625
24100
|
}
|
|
@@ -23674,8 +24149,8 @@ function collectReferenceItems(root, files, allowDomains, denyDomains) {
|
|
|
23674
24149
|
return Array.from(byUrl.values()).sort((a, b) => a.normalizedUrl.localeCompare(b.normalizedUrl));
|
|
23675
24150
|
}
|
|
23676
24151
|
function scanReferences(options = {}) {
|
|
23677
|
-
const root =
|
|
23678
|
-
const outputPath =
|
|
24152
|
+
const root = path25.resolve(options.root ?? process.cwd());
|
|
24153
|
+
const outputPath = path25.resolve(root, options.output ?? DEFAULT_MANIFEST_PATH);
|
|
23679
24154
|
const allowDomains = normalizeList(options.allowDomain);
|
|
23680
24155
|
const denyDomains = normalizeList(options.denyDomain);
|
|
23681
24156
|
const extensions = new Set(
|
|
@@ -23777,8 +24252,8 @@ async function fetchReference(item, outputDir, destinationPrefix, timeoutMs, max
|
|
|
23777
24252
|
slugSource,
|
|
23778
24253
|
item.id
|
|
23779
24254
|
)}-${item.id}.md`;
|
|
23780
|
-
const snapshotPath =
|
|
23781
|
-
const destinationPath =
|
|
24255
|
+
const snapshotPath = path25.resolve(outputDir, fileName);
|
|
24256
|
+
const destinationPath = path25.posix.join(
|
|
23782
24257
|
destinationPrefix.replace(/^\/+|\/+$/g, "") || DEFAULT_DESTINATION_PREFIX,
|
|
23783
24258
|
fileName
|
|
23784
24259
|
);
|
|
@@ -23823,14 +24298,14 @@ function selectItems(manifest, options, allowDomains) {
|
|
|
23823
24298
|
return typeof options.max === "number" && options.max > 0 ? selected.slice(0, options.max) : selected;
|
|
23824
24299
|
}
|
|
23825
24300
|
async function ingestReferences(options = {}) {
|
|
23826
|
-
const manifestPath =
|
|
24301
|
+
const manifestPath = path25.resolve(options.manifest ?? DEFAULT_MANIFEST_PATH);
|
|
23827
24302
|
const manifest = readManifest2(manifestPath);
|
|
23828
|
-
const root = manifest.root ?
|
|
24303
|
+
const root = manifest.root ? path25.resolve(manifest.root) : process.cwd();
|
|
23829
24304
|
const allowDomains = normalizeList([
|
|
23830
24305
|
...manifest.allowDomains ?? [],
|
|
23831
24306
|
...options.allowDomain ?? []
|
|
23832
24307
|
]);
|
|
23833
|
-
const outputDir =
|
|
24308
|
+
const outputDir = path25.resolve(root, options.outputDir ?? DEFAULT_SNAPSHOT_DIR);
|
|
23834
24309
|
const destinationPrefix = options.destinationPrefix ?? DEFAULT_DESTINATION_PREFIX;
|
|
23835
24310
|
const items = selectItems(manifest, options, allowDomains);
|
|
23836
24311
|
const summary = {
|
|
@@ -23857,7 +24332,7 @@ async function ingestReferences(options = {}) {
|
|
|
23857
24332
|
options.maxBytes ?? 512 * 1024
|
|
23858
24333
|
);
|
|
23859
24334
|
summary.fetched += 1;
|
|
23860
|
-
item.latestSnapshotPath =
|
|
24335
|
+
item.latestSnapshotPath = path25.relative(root, snapshot.snapshotPath).split(path25.sep).join("/");
|
|
23861
24336
|
item.latestFetchStatus = snapshot.status;
|
|
23862
24337
|
item.latestFetchAt = snapshot.fetchedAt;
|
|
23863
24338
|
item.latestContentHash = snapshot.contentHash;
|
|
@@ -23920,7 +24395,7 @@ async function referencesScanCommand(options) {
|
|
|
23920
24395
|
printJson4(result);
|
|
23921
24396
|
return;
|
|
23922
24397
|
}
|
|
23923
|
-
console.log(
|
|
24398
|
+
console.log(import_chalk11.default.bold("External References"));
|
|
23924
24399
|
console.log(`Manifest: ${result.outputPath}`);
|
|
23925
24400
|
console.log(`Files scanned: ${result.scannedFiles}`);
|
|
23926
24401
|
console.log(`URLs found: ${result.foundUrls}`);
|
|
@@ -23929,7 +24404,7 @@ async function referencesScanCommand(options) {
|
|
|
23929
24404
|
console.log(`Denied: ${result.denied}`);
|
|
23930
24405
|
if (result.pending > 0) {
|
|
23931
24406
|
console.log(
|
|
23932
|
-
|
|
24407
|
+
import_chalk11.default.gray("Re-run with --allow-domain <domain> or pass --allow-domain to ingest.")
|
|
23933
24408
|
);
|
|
23934
24409
|
}
|
|
23935
24410
|
}
|
|
@@ -23939,7 +24414,7 @@ async function referencesIngestCommand(options) {
|
|
|
23939
24414
|
printJson4(result);
|
|
23940
24415
|
return;
|
|
23941
24416
|
}
|
|
23942
|
-
console.log(
|
|
24417
|
+
console.log(import_chalk11.default.bold("External Reference Ingest"));
|
|
23943
24418
|
console.log(`Manifest: ${result.manifestPath}`);
|
|
23944
24419
|
console.log(`Selected: ${result.selected}`);
|
|
23945
24420
|
if (result.dryRun) {
|
|
@@ -23956,8 +24431,8 @@ async function referencesIngestCommand(options) {
|
|
|
23956
24431
|
}
|
|
23957
24432
|
|
|
23958
24433
|
// src/commands/run.ts
|
|
23959
|
-
var
|
|
23960
|
-
var
|
|
24434
|
+
var import_node_child_process9 = require("child_process");
|
|
24435
|
+
var import_chalk12 = __toESM(require("chalk"));
|
|
23961
24436
|
|
|
23962
24437
|
// src/commands/policy-gates.ts
|
|
23963
24438
|
var REGISTRY_VERSION = "project-intelligence.policy-gates.registry.v1";
|
|
@@ -24721,7 +25196,7 @@ function runGuard(options, changedFiles) {
|
|
|
24721
25196
|
if (options.task) {
|
|
24722
25197
|
args.push("--action", options.release ? "release" : "run");
|
|
24723
25198
|
}
|
|
24724
|
-
const result = (0,
|
|
25199
|
+
const result = (0, import_node_child_process9.spawnSync)(process.execPath, args, {
|
|
24725
25200
|
cwd: process.cwd(),
|
|
24726
25201
|
encoding: "utf8",
|
|
24727
25202
|
env: process.env,
|
|
@@ -24753,7 +25228,7 @@ function runPackageReview(options) {
|
|
|
24753
25228
|
};
|
|
24754
25229
|
}
|
|
24755
25230
|
try {
|
|
24756
|
-
const output = (0,
|
|
25231
|
+
const output = (0, import_node_child_process9.execFileSync)(
|
|
24757
25232
|
"npm",
|
|
24758
25233
|
["view", "snipara-companion", "version", "bin", "dist-tags", "--json"],
|
|
24759
25234
|
{
|
|
@@ -24866,19 +25341,19 @@ async function projectIntelligenceRunCommand(options) {
|
|
|
24866
25341
|
if (options.json) {
|
|
24867
25342
|
console.log(JSON.stringify(result, null, 2));
|
|
24868
25343
|
} else {
|
|
24869
|
-
console.log(
|
|
25344
|
+
console.log(import_chalk12.default.bold("Project Intelligence Run"));
|
|
24870
25345
|
if (result.brief.task) {
|
|
24871
25346
|
console.log(`Task: ${result.brief.task}`);
|
|
24872
25347
|
}
|
|
24873
25348
|
console.log(`Release: ${result.release ? "yes" : "no"}`);
|
|
24874
25349
|
console.log("");
|
|
24875
|
-
console.log(
|
|
25350
|
+
console.log(import_chalk12.default.bold("Project Judgment"));
|
|
24876
25351
|
for (const line of formatProjectJudgmentCard(result.judgmentCard)) {
|
|
24877
25352
|
console.log(line);
|
|
24878
25353
|
}
|
|
24879
25354
|
console.log("");
|
|
24880
25355
|
if (result.policyGates.gates.length > 0) {
|
|
24881
|
-
console.log(
|
|
25356
|
+
console.log(import_chalk12.default.bold("Policy Gates"));
|
|
24882
25357
|
console.log(
|
|
24883
25358
|
`Strongest: ${result.policyGates.summary.strongestSeverity}; advisory ${result.policyGates.summary.advisory}, required ${result.policyGates.summary.requiredAction}, block ${result.policyGates.summary.block}`
|
|
24884
25359
|
);
|
|
@@ -24890,7 +25365,7 @@ async function projectIntelligenceRunCommand(options) {
|
|
|
24890
25365
|
console.log("");
|
|
24891
25366
|
}
|
|
24892
25367
|
if (result.guard) {
|
|
24893
|
-
console.log(
|
|
25368
|
+
console.log(import_chalk12.default.bold("Guard"));
|
|
24894
25369
|
console.log(`Status: ${result.guard.status}`);
|
|
24895
25370
|
const actionCards = isRecord15(result.guard.payload) ? result.guard.payload.actionCards : [];
|
|
24896
25371
|
if (Array.isArray(actionCards) && actionCards.length > 0) {
|
|
@@ -24902,7 +25377,7 @@ async function projectIntelligenceRunCommand(options) {
|
|
|
24902
25377
|
console.log("");
|
|
24903
25378
|
}
|
|
24904
25379
|
if (result.packageReview) {
|
|
24905
|
-
console.log(
|
|
25380
|
+
console.log(import_chalk12.default.bold("Package Review"));
|
|
24906
25381
|
console.log(`${result.packageReview.packageName}: ${result.packageReview.status}`);
|
|
24907
25382
|
if (result.packageReview.error) {
|
|
24908
25383
|
console.log(result.packageReview.error);
|
|
@@ -24910,7 +25385,7 @@ async function projectIntelligenceRunCommand(options) {
|
|
|
24910
25385
|
console.log("");
|
|
24911
25386
|
}
|
|
24912
25387
|
if (result.advisorReceiptCapture) {
|
|
24913
|
-
console.log(
|
|
25388
|
+
console.log(import_chalk12.default.bold("Advisor Receipts"));
|
|
24914
25389
|
console.log(`Status: ${result.advisorReceiptCapture.status}`);
|
|
24915
25390
|
if (result.advisorReceiptCapture.servedJudgmentId) {
|
|
24916
25391
|
console.log(`Served judgment: ${result.advisorReceiptCapture.servedJudgmentId}`);
|
|
@@ -24931,7 +25406,7 @@ async function projectIntelligenceRunCommand(options) {
|
|
|
24931
25406
|
}
|
|
24932
25407
|
console.log("");
|
|
24933
25408
|
}
|
|
24934
|
-
console.log(
|
|
25409
|
+
console.log(import_chalk12.default.bold("Suggested Commands"));
|
|
24935
25410
|
for (const command of result.suggestedCommands.slice(0, 8)) {
|
|
24936
25411
|
console.log(command);
|
|
24937
25412
|
}
|
|
@@ -24942,12 +25417,12 @@ async function projectIntelligenceRunCommand(options) {
|
|
|
24942
25417
|
}
|
|
24943
25418
|
|
|
24944
25419
|
// src/commands/collaboration.ts
|
|
24945
|
-
var
|
|
25420
|
+
var import_node_child_process10 = require("child_process");
|
|
24946
25421
|
var import_node_crypto5 = require("crypto");
|
|
24947
25422
|
var fs26 = __toESM(require("fs"));
|
|
24948
25423
|
var os6 = __toESM(require("os"));
|
|
24949
|
-
var
|
|
24950
|
-
var COLLABORATION_STATE_RELATIVE_PATH =
|
|
25424
|
+
var path26 = __toESM(require("path"));
|
|
25425
|
+
var COLLABORATION_STATE_RELATIVE_PATH = path26.join(
|
|
24951
25426
|
".snipara",
|
|
24952
25427
|
"collaboration",
|
|
24953
25428
|
"session.json"
|
|
@@ -25034,7 +25509,7 @@ function createEmptyCollaborationState(now = /* @__PURE__ */ new Date()) {
|
|
|
25034
25509
|
};
|
|
25035
25510
|
}
|
|
25036
25511
|
function getCollaborationStatePath(rootDir = process.cwd()) {
|
|
25037
|
-
return
|
|
25512
|
+
return path26.join(rootDir, COLLABORATION_STATE_RELATIVE_PATH);
|
|
25038
25513
|
}
|
|
25039
25514
|
function loadCollaborationState(rootDir = process.cwd()) {
|
|
25040
25515
|
const statePath = getCollaborationStatePath(rootDir);
|
|
@@ -25068,7 +25543,7 @@ function loadCollaborationState(rootDir = process.cwd()) {
|
|
|
25068
25543
|
}
|
|
25069
25544
|
function saveCollaborationState(state, rootDir = process.cwd()) {
|
|
25070
25545
|
const statePath = getCollaborationStatePath(rootDir);
|
|
25071
|
-
fs26.mkdirSync(
|
|
25546
|
+
fs26.mkdirSync(path26.dirname(statePath), { recursive: true });
|
|
25072
25547
|
const tempPath = `${statePath}.${process.pid}.${Date.now()}.tmp`;
|
|
25073
25548
|
try {
|
|
25074
25549
|
fs26.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}
|
|
@@ -25487,7 +25962,7 @@ async function collaborationIdeStatusCommand(options) {
|
|
|
25487
25962
|
console.log(`Active leases: ${payload.hosted.activeLeases.length}`);
|
|
25488
25963
|
}
|
|
25489
25964
|
function resolveCollaborationContext(options) {
|
|
25490
|
-
const rootDir =
|
|
25965
|
+
const rootDir = path26.resolve(options.dir ?? process.cwd());
|
|
25491
25966
|
const config = loadConfig({ cwd: rootDir });
|
|
25492
25967
|
const actor = buildCollaborationActor(options, config);
|
|
25493
25968
|
return {
|
|
@@ -25823,9 +26298,9 @@ function readGitChangedFiles(rootDir, args) {
|
|
|
25823
26298
|
return output ? normalizeFiles2(output.split(/\r?\n/)) : [];
|
|
25824
26299
|
}
|
|
25825
26300
|
function resolveRepoRoot3(cwd) {
|
|
25826
|
-
const resolved =
|
|
26301
|
+
const resolved = path26.resolve(cwd);
|
|
25827
26302
|
const gitRoot = readGitValue3(resolved, ["rev-parse", "--show-toplevel"]);
|
|
25828
|
-
return gitRoot ?
|
|
26303
|
+
return gitRoot ? path26.resolve(gitRoot) : resolved;
|
|
25829
26304
|
}
|
|
25830
26305
|
function deriveGuardProfileResources(profile, files) {
|
|
25831
26306
|
const resources = [];
|
|
@@ -26030,7 +26505,7 @@ function readGitRawValue(rootDir, args) {
|
|
|
26030
26505
|
stdio: ["ignore", "pipe", "ignore"],
|
|
26031
26506
|
timeout: 1e3
|
|
26032
26507
|
};
|
|
26033
|
-
const output = (0,
|
|
26508
|
+
const output = (0, import_node_child_process10.execFileSync)("git", args, execOptions);
|
|
26034
26509
|
return output || void 0;
|
|
26035
26510
|
} catch {
|
|
26036
26511
|
return void 0;
|
|
@@ -26076,16 +26551,16 @@ ${nextBlock}`);
|
|
|
26076
26551
|
}
|
|
26077
26552
|
function resolveGitHooksDir2(repoRoot) {
|
|
26078
26553
|
const gitHooksPath = readGitValue3(repoRoot, ["rev-parse", "--git-path", "hooks"]);
|
|
26079
|
-
const hooksDir =
|
|
26080
|
-
const huskyUserHooksDir =
|
|
26081
|
-
if (
|
|
26554
|
+
const hooksDir = path26.resolve(repoRoot, gitHooksPath ?? path26.join(".git", "hooks"));
|
|
26555
|
+
const huskyUserHooksDir = path26.dirname(hooksDir);
|
|
26556
|
+
if (path26.basename(hooksDir) === "_" && path26.basename(huskyUserHooksDir) === ".husky" && fs26.existsSync(path26.join(hooksDir, "h"))) {
|
|
26082
26557
|
return huskyUserHooksDir;
|
|
26083
26558
|
}
|
|
26084
26559
|
return hooksDir;
|
|
26085
26560
|
}
|
|
26086
26561
|
function installManagedCollaborationGitHook(repoRoot, hookName, options) {
|
|
26087
26562
|
const hooksDir = resolveGitHooksDir2(repoRoot);
|
|
26088
|
-
const hookPath =
|
|
26563
|
+
const hookPath = path26.join(hooksDir, hookName);
|
|
26089
26564
|
const currentContent = fs26.existsSync(hookPath) ? fs26.readFileSync(hookPath, "utf8") : null;
|
|
26090
26565
|
const block = buildCollaborationGitHookBlock(hookName);
|
|
26091
26566
|
const nextContent = mergeManagedCollaborationHookBlock(hookName, currentContent, block);
|
|
@@ -26566,7 +27041,7 @@ function normalizeResourceId(kind, id) {
|
|
|
26566
27041
|
return normalized;
|
|
26567
27042
|
}
|
|
26568
27043
|
function normalizeRepoPath3(value) {
|
|
26569
|
-
return value.trim().split(
|
|
27044
|
+
return value.trim().split(path26.sep).join("/").replace(/^\.?\//, "");
|
|
26570
27045
|
}
|
|
26571
27046
|
function normalizeOptionalString2(value) {
|
|
26572
27047
|
const normalized = typeof value === "string" ? value.trim() : "";
|
|
@@ -26807,6 +27282,24 @@ var program = new import_commander.Command();
|
|
|
26807
27282
|
function collectOption(value, previous = []) {
|
|
26808
27283
|
return [...previous, value];
|
|
26809
27284
|
}
|
|
27285
|
+
function configureRealityCheckCommand(command) {
|
|
27286
|
+
return command.description("Run a Project Reality Check against local or supplied change scope").option("--task <task>", "Task or change summary").option("--branch <branch>", "Branch to scope the check").option("--base <ref>", "Base ref for committed local changes (default: upstream)").option("--changed-files <files...>", "Changed files to analyze").option("--diff-summary <summary>", "Natural-language diff summary").option("--decision <decision...>", "Decision or intent in ID: text form").option("--document <document...>", "Document/context hint in path: preview form").option("--verification <item...>", "Verification evidence or checklist item").option("--no-include-dirty", "Exclude dirty working-tree files from local scope").option("--enforce", "Exit non-zero for review-required or blocking findings").option("-d, --dir <directory>", "Project directory (default: current)").option("--json", "Print raw JSON").action(async (options) => {
|
|
27287
|
+
await realityCheckCommand({
|
|
27288
|
+
task: options.task,
|
|
27289
|
+
branch: options.branch,
|
|
27290
|
+
base: options.base,
|
|
27291
|
+
changedFiles: options.changedFiles,
|
|
27292
|
+
diffSummary: options.diffSummary,
|
|
27293
|
+
decision: options.decision,
|
|
27294
|
+
document: options.document,
|
|
27295
|
+
verification: options.verification,
|
|
27296
|
+
includeDirty: options.includeDirty,
|
|
27297
|
+
enforce: Boolean(options.enforce),
|
|
27298
|
+
dir: options.dir,
|
|
27299
|
+
json: Boolean(options.json)
|
|
27300
|
+
});
|
|
27301
|
+
});
|
|
27302
|
+
}
|
|
26810
27303
|
program.name("snipara-companion").description("Snipara companion CLI for local hooks and automation workflows").version(readCliVersion());
|
|
26811
27304
|
program.command("login").description("Authenticate this workspace through the Snipara project picker").option("--api-url <url>", "Override the API URL (default: https://api.snipara.com)").option("-c, --client <client>", "Client type for the project API key label").option("-p, --project <project>", "Project slug or ID to preselect in the browser").option("--project-id <id>", "Project slug or ID (deprecated alias)").option("-d, --dir <directory>", "Project directory (default: current)").option("--user-key", "Use the legacy project-agnostic user-key login flow").action(async (options) => {
|
|
26812
27305
|
try {
|
|
@@ -27572,6 +28065,7 @@ program.command("brief").description("Build a Project Intelligence continuity br
|
|
|
27572
28065
|
json: Boolean(options.json)
|
|
27573
28066
|
});
|
|
27574
28067
|
});
|
|
28068
|
+
configureRealityCheckCommand(program.command("reality-check"));
|
|
27575
28069
|
var intelligence = program.command("intelligence").description(
|
|
27576
28070
|
"Compose Project Intelligence briefs from continuity, memory health, and code impact"
|
|
27577
28071
|
);
|
|
@@ -27588,6 +28082,7 @@ intelligence.command("brief").description("Build a Project Intelligence continui
|
|
|
27588
28082
|
json: Boolean(options.json)
|
|
27589
28083
|
});
|
|
27590
28084
|
});
|
|
28085
|
+
configureRealityCheckCommand(intelligence.command("reality-check"));
|
|
27591
28086
|
intelligence.command("ledger-export").description("Export a structured, redacted Coding Intelligence Ledger JSON artifact").option("--from-file <file>", "Read ledger inputs from a JSON object").option("--task <task>", "Task or work package summary").option("--prompt <prompt>", "Prompt or operator request summary").option("--source-ref <ref>", "Stable prompt or source reference").option("--branch <branch>", "Repository branch").option("--commit <commit>", "Repository commit or revision").option("--changed-files <files...>", "Changed files represented by the ledger").option("--recent-files <files...>", "Recently relevant files").option("--diff-summary <summary>", "Diff summary represented by the ledger").option("--served-context <context>", "Served context item; repeatable", collectOption, []).option("--plan <plan>", "Plan or decision item; repeatable", collectOption, []).option("--diff <diff>", "Diff item; repeatable", collectOption, []).option("--test <test>", "Test or verification item; repeatable", collectOption, []).option("--ci <ci>", "CI or build item; repeatable", collectOption, []).option("--review <review>", "Review item; repeatable", collectOption, []).option("--outcome <outcome>", "Outcome item; repeatable", collectOption, []).option(
|
|
27592
28087
|
"--influence-receipt <receipt>",
|
|
27593
28088
|
"Advisor influence or receipt item; repeatable",
|
|
@@ -28659,6 +29154,7 @@ if (require.main === module) {
|
|
|
28659
29154
|
buildLocalImpactResult,
|
|
28660
29155
|
buildLocalImportsResult,
|
|
28661
29156
|
buildLocalNeighborsResult,
|
|
29157
|
+
buildLocalProjectRealityCheck,
|
|
28662
29158
|
buildLocalShortestPathResult,
|
|
28663
29159
|
buildLocalSourceSnapshot,
|
|
28664
29160
|
buildLocalSourceStatus,
|
|
@@ -28753,6 +29249,7 @@ if (require.main === module) {
|
|
|
28753
29249
|
readLocalCodePromotionState,
|
|
28754
29250
|
readLocalSourceSnapshot,
|
|
28755
29251
|
readLocalWorkersConfig,
|
|
29252
|
+
realityCheckCommand,
|
|
28756
29253
|
referencesIngestCommand,
|
|
28757
29254
|
referencesScanCommand,
|
|
28758
29255
|
resolveContextPackRecord,
|
package/docs/FULL_REFERENCE.md
CHANGED
|
@@ -174,6 +174,7 @@ snipara-companion status
|
|
|
174
174
|
snipara-companion source init .
|
|
175
175
|
snipara-companion source sync --json
|
|
176
176
|
snipara-companion brief --task "ship auth hardening" --changed-files src/auth.ts
|
|
177
|
+
snipara-companion reality-check --task "ship auth hardening" --changed-files src/auth.ts --enforce
|
|
177
178
|
snipara-companion timeline
|
|
178
179
|
snipara-companion workflow phase-commit build --summary "tests green"
|
|
179
180
|
snipara-companion workflow impact-gate
|
|
@@ -192,6 +193,10 @@ snipara-companion workflow resume --include-session-context
|
|
|
192
193
|
it writes a source snapshot, previews supported document sync, and refreshes
|
|
193
194
|
the local code overlay cache without requiring GitHub.
|
|
194
195
|
- `brief` is the short alias for `intelligence brief`.
|
|
196
|
+
- `reality-check` compares changed files, linked intent, context docs, symbols,
|
|
197
|
+
and verification hints to flag contradiction-to-reality risks before commit or
|
|
198
|
+
merge. Use `--enforce` in local hooks when review-required findings should
|
|
199
|
+
fail the hook.
|
|
195
200
|
- `timeline` is the Git-style log for workflow starts, phase starts, phase
|
|
196
201
|
commits, final commits, and Team Sync handoffs.
|
|
197
202
|
- `workflow impact-gate` audits committed local workflow phases that are ahead
|
|
@@ -741,6 +746,7 @@ snipara-companion query --query "auth middleware"
|
|
|
741
746
|
snipara-companion query --query "who calls src.mcp_transport.handle_call_tool" --follow-recommendation
|
|
742
747
|
snipara-companion status
|
|
743
748
|
snipara-companion brief --task "ship auth hardening" --changed-files apps/web/src/lib/auth.ts tests/auth.test.ts --diff-summary "auth hardening"
|
|
749
|
+
snipara-companion reality-check --task "ship auth hardening" --changed-files apps/web/src/lib/auth.ts --verification "pnpm test auth" --enforce
|
|
744
750
|
snipara-companion handoff --summary "auth hardening implemented" --next "run permissions tests" --files apps/web/src/lib/auth.ts --output handoff.md
|
|
745
751
|
snipara-companion intelligence brief --task "ship auth hardening" --changed-files apps/web/src/lib/auth.ts tests/auth.test.ts --diff-summary "auth hardening"
|
|
746
752
|
snipara-companion workflow scaffold --preset project-intelligence-continuity-layer --output .snipara/workflow/plans/project-intelligence-plan.json
|
|
@@ -930,6 +936,23 @@ checkouts use hosted graph impact. It prints continuity signals, memory health,
|
|
|
930
936
|
risk and verification hints, degraded surfaces, and the Judgment Card's
|
|
931
937
|
weighted readiness, evidence, and required actions.
|
|
932
938
|
|
|
939
|
+
Use `reality-check` or `intelligence reality-check` when a local hook, agent, or
|
|
940
|
+
CI adapter needs the contradiction-to-reality gate without a full hosted brief:
|
|
941
|
+
|
|
942
|
+
```bash
|
|
943
|
+
snipara-companion reality-check \
|
|
944
|
+
--task "refactor auth middleware" \
|
|
945
|
+
--changed-files src/auth/middleware.ts \
|
|
946
|
+
--decision "DEC-001: auth middleware must keep side effects explicit" \
|
|
947
|
+
--verification "pnpm test auth" \
|
|
948
|
+
--enforce
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
The command reads the local Git scope by default, includes dirty files unless
|
|
952
|
+
`--no-include-dirty` is set, and also accepts explicit `--changed-files` for
|
|
953
|
+
hooks or CI collectors. `--enforce` exits non-zero for `review_required` or
|
|
954
|
+
`blocking` findings; JSON output is available with `--json`.
|
|
955
|
+
|
|
933
956
|
Use `intelligence ledger-export` when an agent run, review, or replay benchmark
|
|
934
957
|
needs a portable Coding Intelligence Ledger instead of a raw transcript:
|
|
935
958
|
|
|
@@ -1005,9 +1028,11 @@ Semantics:
|
|
|
1005
1028
|
- `snipara-companion status` = top-level agentic work status across local workflow state, git dirtiness, and Team Sync carryover
|
|
1006
1029
|
- `snipara-companion source init|sync|status|snapshot|watch` = automatic local source activation for folders with or without Git metadata; writes `.snipara/source/latest.json`, previews document sync, and refreshes the local code overlay cache
|
|
1007
1030
|
- `snipara-companion brief` = short alias for `snipara-companion intelligence brief`
|
|
1031
|
+
- `snipara-companion reality-check` = local Project Reality Check for supplied or Git-derived changed files; `--enforce` makes review-required contradiction-to-reality findings fail hooks
|
|
1008
1032
|
- `snipara-companion timeline` = local timeline of workflow starts, phase starts, phase commits, final commits, and Team Sync handoffs
|
|
1009
1033
|
- `snipara-companion handoff` = top-level agent-ready Markdown/JSON handoff artifact plus the same local/hosted Team Sync handoff persistence
|
|
1010
1034
|
- `snipara-companion intelligence brief` = one local Project Intelligence brief that combines resume context, memory health, and code impact for a task
|
|
1035
|
+
- `snipara-companion intelligence reality-check` = Project Intelligence namespace alias for the same local Reality Check gate
|
|
1011
1036
|
- `snipara-companion intelligence ledger-export` = structured redacted Coding Intelligence Ledger JSON for replay, review, and commercial proof assets without dumping raw transcripts
|
|
1012
1037
|
- `snipara-companion run` = production Project Intelligence flow that combines the brief, guard action cards, package review, verification hints, and a final weighted Judgment Card
|
|
1013
1038
|
- `snipara-companion workflow start --plan-file` = records the visible LLM plan locally so phase state survives agent compaction; prefer JSON plans with explicit ids for stable machine phase state
|