snipara-companion 3.5.0 → 3.5.2
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/CHANGELOG.md +22 -0
- package/README.md +21 -4
- package/dist/index.d.ts +51 -12
- package/dist/index.js +282 -113
- package/docs/FULL_REFERENCE.md +37 -15
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Release notes for `snipara-companion`, newest first.
|
|
4
4
|
|
|
5
|
+
## New In 3.5.2
|
|
6
|
+
|
|
7
|
+
- Replaces the retired Windsurf preset with Kimi Code CLI across setup,
|
|
8
|
+
automation, readiness, handoff, and help surfaces.
|
|
9
|
+
- Adds merge-safe `.kimi-code/mcp.json` installation plus a reviewable Kimi
|
|
10
|
+
plugin bundle for Companion lifecycle hooks, skills, and commands.
|
|
11
|
+
- Keeps the Kimi adapter fail-open and requires explicit plugin installation;
|
|
12
|
+
risky tool approval and Hosted MCP tenant boundaries remain authoritative.
|
|
13
|
+
|
|
14
|
+
## New In 3.5.1
|
|
15
|
+
|
|
16
|
+
- Adds Context Control V1 hosted diff/apply commands for declarative
|
|
17
|
+
`snipara.project-context.json` sources.
|
|
18
|
+
- Binds hosted mutations to tenant-scoped server plans, remote compare-and-set
|
|
19
|
+
hashes, explicit resolved Decision Requests, EDITOR API-key access, and
|
|
20
|
+
detailed apply/reindex receipts.
|
|
21
|
+
- Keeps reconciliation add/update-only: unmanaged hosted documents are reported
|
|
22
|
+
but never deleted, managed authority promotions are blocked, and stale plans
|
|
23
|
+
fail before writes.
|
|
24
|
+
- Makes local V0 `context-control apply` enforce its review flag through an
|
|
25
|
+
explicit `--approve` acknowledgement.
|
|
26
|
+
|
|
5
27
|
## New In 3.5.0
|
|
6
28
|
|
|
7
29
|
- Adds an explicit `workflow run --strong-repair` handoff contract for one
|
package/README.md
CHANGED
|
@@ -100,7 +100,7 @@ These commands are useful without hosted Snipara:
|
|
|
100
100
|
| `workflow producer-triage` | Ask for human review of unreviewed Producer Loop samples |
|
|
101
101
|
| `workflow producer-report` | Local Producer Loop adoption and calibration report |
|
|
102
102
|
| `workflow producer-review` | Mark local Producer Loop samples reviewed or rejected |
|
|
103
|
-
| `context-control plan` / `apply` / `drift` / `validate`
|
|
103
|
+
| `context-control plan` / `apply` / `drift` / `validate` / `hosted-*` | Review local state and reconcile Context as Code with hosted project context |
|
|
104
104
|
| `context-pack` | Reversible local packs for long logs, diffs, and tool output |
|
|
105
105
|
| `judgment-card`, `verify`, `lead-plan`, `agent-readiness` | Local review artifacts and delegation contracts |
|
|
106
106
|
| `intelligence ledger-export` | Structured redacted ledger JSON for replay and review |
|
|
@@ -111,8 +111,9 @@ These commands are useful without hosted Snipara:
|
|
|
111
111
|
`context-control` is the local trust layer for Project Intelligence state. It
|
|
112
112
|
borrows Terraform's useful product grammar without copying Terraform: preview a
|
|
113
113
|
bounded context mutation, inspect drift, then apply only the exact reviewed
|
|
114
|
-
plan. V0
|
|
115
|
-
hosted
|
|
114
|
+
plan. V0 remains the local trust-artifact layer. Context Control V1 adds an
|
|
115
|
+
authenticated hosted diff/apply path with tenant scoping, compare-and-set hashes,
|
|
116
|
+
explicit Decision Request approval, detailed receipts, and add/update-only writes.
|
|
116
117
|
|
|
117
118
|
```bash
|
|
118
119
|
npx -y snipara-companion context-control plan \
|
|
@@ -120,7 +121,8 @@ npx -y snipara-companion context-control plan \
|
|
|
120
121
|
--output .snipara/context-control/plans/demo.json
|
|
121
122
|
|
|
122
123
|
npx -y snipara-companion context-control apply \
|
|
123
|
-
--plan .snipara/context-control/plans/demo.json
|
|
124
|
+
--plan .snipara/context-control/plans/demo.json \
|
|
125
|
+
--approve
|
|
124
126
|
|
|
125
127
|
npx -y snipara-companion context-control drift
|
|
126
128
|
```
|
|
@@ -151,6 +153,21 @@ locally:
|
|
|
151
153
|
}
|
|
152
154
|
```
|
|
153
155
|
|
|
156
|
+
To reconcile that manifest with hosted project context, first write a reviewed
|
|
157
|
+
plan and Decision Request, resolve the request, then apply the exact plan:
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
snipara-companion context-control hosted-diff --manifest snipara.project-context.json --output .snipara/context-control/plans/hosted.json --emit-decision-request
|
|
161
|
+
snipara-companion workflow decide <request-id> --choose approve_hosted_apply --reviewer <name>
|
|
162
|
+
snipara-companion context-control hosted-apply --plan .snipara/context-control/plans/hosted.json --approval .snipara/decisions/resolved/<request-id>.json --output .snipara/context-control/applied/hosted.json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
V1 never deletes remote documents. It reports hosted paths outside the manifest,
|
|
166
|
+
blocks authority promotions on existing managed sources, rejects stale remote
|
|
167
|
+
hashes, and requires an EDITOR-authorized API key for mutation. The local
|
|
168
|
+
approval artifact records declared human review; the API key remains the actual
|
|
169
|
+
hosted mutation authority.
|
|
170
|
+
|
|
154
171
|
```bash
|
|
155
172
|
npx -y snipara-companion context-control validate --manifest snipara.project-context.json
|
|
156
173
|
npx -y snipara-companion context-control plan --manifest snipara.project-context.json
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { AdvisorInfluenceLifecycle, ProjectIntentDetectionResult, ProjectPolicyDecision, ProjectRealityCheckResult, ContextMutationPlan, ContextMutationApplyReceipt, ProjectContextValidationReport, ProjectDriftReport, ProjectIntelligenceEngineeringLeadPlanSummary, ProjectPolicyRule, DecisionRequest, AdvisorInfluenceLifecycleState, OutcomeIntelligenceCalibration, ControlledWorkerExecutionMode, WorkerTrustCategory, ControlledWorkerExecutionReceipt, UnifiedReceiptEnvelope, WorkerTrustCandidate, WorkerProfile, WorkerTrustEvent } from '@snipara/project-intelligence-contracts';
|
|
2
|
+
import { AdvisorInfluenceLifecycle, HostedContextControlSource, HostedContextControlPlan, HostedContextControlApplyReceipt, ProjectIntentDetectionResult, ProjectPolicyDecision, ProjectRealityCheckResult, ContextMutationPlan, ContextMutationApplyReceipt, ProjectContextValidationReport, ProjectDriftReport, ProjectIntelligenceEngineeringLeadPlanSummary, ProjectPolicyRule, DecisionRequest, AdvisorInfluenceLifecycleState, OutcomeIntelligenceCalibration, ControlledWorkerExecutionMode, WorkerTrustCategory, ControlledWorkerExecutionReceipt, UnifiedReceiptEnvelope, WorkerTrustCandidate, WorkerProfile, WorkerTrustEvent } from '@snipara/project-intelligence-contracts';
|
|
3
3
|
|
|
4
4
|
declare function resolveQueryFromToolInput(toolInput?: string, tool?: string): string | null;
|
|
5
5
|
|
|
@@ -299,6 +299,22 @@ interface AnswerPack {
|
|
|
299
299
|
};
|
|
300
300
|
token_count?: number;
|
|
301
301
|
}
|
|
302
|
+
interface HostedContextControlDiffResponse {
|
|
303
|
+
project: {
|
|
304
|
+
id: string;
|
|
305
|
+
name: string;
|
|
306
|
+
slug: string;
|
|
307
|
+
};
|
|
308
|
+
plan: HostedContextControlPlan;
|
|
309
|
+
}
|
|
310
|
+
interface HostedContextControlApplyResponse {
|
|
311
|
+
project: {
|
|
312
|
+
id: string;
|
|
313
|
+
name: string;
|
|
314
|
+
slug: string;
|
|
315
|
+
};
|
|
316
|
+
receipt: HostedContextControlApplyReceipt;
|
|
317
|
+
}
|
|
302
318
|
interface CodeGraphNodeResult {
|
|
303
319
|
symbol_key: string;
|
|
304
320
|
qualified_name: string;
|
|
@@ -1439,6 +1455,14 @@ declare class RLMClient {
|
|
|
1439
1455
|
createClientProject(options: CreateClientProjectOptions): Promise<Record<string, unknown>>;
|
|
1440
1456
|
syncDocuments(documents: SyncDocumentInput[], deleteMissing?: boolean): Promise<Record<string, unknown>>;
|
|
1441
1457
|
syncProjectPolicyLedger(artifacts: ProjectPolicyLedgerSyncArtifactInput[]): Promise<Record<string, unknown>>;
|
|
1458
|
+
diffHostedContextControl(input: {
|
|
1459
|
+
manifestHash: string;
|
|
1460
|
+
sources: HostedContextControlSource[];
|
|
1461
|
+
}): Promise<HostedContextControlDiffResponse>;
|
|
1462
|
+
applyHostedContextControl(input: {
|
|
1463
|
+
plan: HostedContextControlPlan;
|
|
1464
|
+
approval?: unknown;
|
|
1465
|
+
}): Promise<HostedContextControlApplyResponse>;
|
|
1442
1466
|
reindex(options: {
|
|
1443
1467
|
kind?: "doc" | "code";
|
|
1444
1468
|
mode?: "incremental" | "full";
|
|
@@ -2167,6 +2191,14 @@ interface RealityCheckCommandOptions {
|
|
|
2167
2191
|
declare function buildLocalProjectRealityCheck(options: RealityCheckCommandOptions): ProjectRealityCheckResult;
|
|
2168
2192
|
declare function realityCheckCommand(options: RealityCheckCommandOptions): Promise<void>;
|
|
2169
2193
|
|
|
2194
|
+
interface DecisionRequestWriteResult {
|
|
2195
|
+
status: "written" | "duplicate_pending" | "duplicate_resolved";
|
|
2196
|
+
requestId: string;
|
|
2197
|
+
fingerprint: string;
|
|
2198
|
+
path?: string;
|
|
2199
|
+
relativePath?: string;
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2170
2202
|
interface ContextControlPlanCommandOptions {
|
|
2171
2203
|
summary?: string;
|
|
2172
2204
|
target?: string;
|
|
@@ -2180,6 +2212,19 @@ interface ContextControlPlanCommandOptions {
|
|
|
2180
2212
|
interface ContextControlApplyCommandOptions {
|
|
2181
2213
|
plan: string;
|
|
2182
2214
|
allowStaleBase?: boolean;
|
|
2215
|
+
approved?: boolean;
|
|
2216
|
+
json?: boolean;
|
|
2217
|
+
}
|
|
2218
|
+
interface ContextControlHostedDiffCommandOptions {
|
|
2219
|
+
manifest?: string;
|
|
2220
|
+
output?: string;
|
|
2221
|
+
emitDecisionRequest?: boolean;
|
|
2222
|
+
json?: boolean;
|
|
2223
|
+
}
|
|
2224
|
+
interface ContextControlHostedApplyCommandOptions {
|
|
2225
|
+
plan: string;
|
|
2226
|
+
approval?: string;
|
|
2227
|
+
output?: string;
|
|
2183
2228
|
json?: boolean;
|
|
2184
2229
|
}
|
|
2185
2230
|
interface ContextControlDriftCommandOptions {
|
|
@@ -2219,14 +2264,8 @@ declare function contextControlPlanCommand(options: ContextControlPlanCommandOpt
|
|
|
2219
2264
|
declare function contextControlApplyCommand(options: ContextControlApplyCommandOptions): Promise<void>;
|
|
2220
2265
|
declare function contextControlDriftCommand(options: ContextControlDriftCommandOptions): Promise<void>;
|
|
2221
2266
|
declare function contextControlValidateCommand(options: ContextControlValidateCommandOptions): Promise<void>;
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
status: "written" | "duplicate_pending" | "duplicate_resolved";
|
|
2225
|
-
requestId: string;
|
|
2226
|
-
fingerprint: string;
|
|
2227
|
-
path?: string;
|
|
2228
|
-
relativePath?: string;
|
|
2229
|
-
}
|
|
2267
|
+
declare function contextControlHostedDiffCommand(options: ContextControlHostedDiffCommandOptions): Promise<void>;
|
|
2268
|
+
declare function contextControlHostedApplyCommand(options: ContextControlHostedApplyCommandOptions): Promise<void>;
|
|
2230
2269
|
|
|
2231
2270
|
interface MemoryHealthCommandOptions {
|
|
2232
2271
|
scope?: MemoryScope;
|
|
@@ -2357,7 +2396,7 @@ declare function memoryLocalCommand(options: LocalMemoryCommandOptions): Promise
|
|
|
2357
2396
|
declare function evalExportCommand(options: EvalExportOptions): Promise<void>;
|
|
2358
2397
|
declare function evalRunCommand(options: EvalRunOptions): Promise<void>;
|
|
2359
2398
|
|
|
2360
|
-
type AgentReadinessTarget = "codex" | "claude-code" | "cursor" | "orca" | "
|
|
2399
|
+
type AgentReadinessTarget = "codex" | "claude-code" | "cursor" | "orca" | "kimi" | "custom";
|
|
2361
2400
|
type AgentReadinessCheckStatus = "pass" | "warning" | "fail" | "manual";
|
|
2362
2401
|
type AgentReadinessGapSeverity = "low" | "medium" | "high" | "blocker";
|
|
2363
2402
|
type AgentReadinessScoreBand = "ready" | "mostly_ready" | "needs_hardening" | "blocked";
|
|
@@ -3507,7 +3546,7 @@ interface TeamSyncSweepExplanation {
|
|
|
3507
3546
|
remainingStaleCount: number;
|
|
3508
3547
|
message: string;
|
|
3509
3548
|
}
|
|
3510
|
-
type AgenticHandoffAdapterTarget = "codex" | "claude-code" | "cursor" | "orca" | "
|
|
3549
|
+
type AgenticHandoffAdapterTarget = "codex" | "claude-code" | "cursor" | "orca" | "kimi" | "custom";
|
|
3511
3550
|
type AgenticHandoffConflictPosture = "continue" | "wait" | "split_work" | "review_only" | "handoff";
|
|
3512
3551
|
interface AgenticHandoffAdapterPack {
|
|
3513
3552
|
version: "snipara.ade_adapter_pack.v1";
|
|
@@ -4867,4 +4906,4 @@ declare function installAutomationBundle(args: {
|
|
|
4867
4906
|
}): Promise<AutomationInstallResult>;
|
|
4868
4907
|
declare function getAutomationStatus(projectDir?: string): AutomationStatusResult;
|
|
4869
4908
|
|
|
4870
|
-
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, FINAL_COMMIT_REPORT_RELATIVE_PATH, FINAL_COMMIT_REPORT_VERSION, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, POLICY_LEDGER_SYNC_REPORT_VERSION, PRODUCER_LOOP_ARTIFACT_VERSION, PRODUCER_LOOP_RELATIVE_DIR, PRODUCER_LOOP_REPORT_VERSION, TEAM_SYNC_STATE_RELATIVE_PATH, WHY_OUTCOME_CAPTURE_VERSION, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, addLocalWorker, agentReadinessAuditCommand, appendActivityEvent, applyLocalContextMutationPlan, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCodingIntelligenceLedger, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCommitResultMetadata, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildFinalCommitReport, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextMutationPlan, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalProjectContextValidationReport, buildLocalProjectDriftReport, buildLocalProjectRealityCheck, buildLocalShortestPathResult, buildLocalSourceSnapshot, buildLocalSourceStatus, buildLocalSourceSyncResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildPolicyLedgerSyncReport, buildProducerLoopReport, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapBrief, buildSessionBootstrapQuality, buildSessionSnapshot, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWhyOutcomeCaptureReport, buildWorkerTrustCandidates, buildWorkflowImpactGate, buildWorkflowPhaseCommitReceipt, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, codingLedgerExportCommand, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectPolicyLedgerSyncArtifacts, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, compareLocalSourceSnapshots, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextControlApplyCommand, contextControlDriftCommand, contextControlPlanCommand, contextControlValidateCommand, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, controlledWorkerExecuteCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatFinalCommitReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getLocalSourceSnapshotPath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, hashWorkerProfile, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, memoryReviewsCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, readSessionSnapshot, readWorkerTrustEvent, realityCheckCommand, referencesIngestCommand, referencesScanCommand, resolveAutoWorkflowMode, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveLocalWorkerRoutingDefaults, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldFailCollaborationGuard, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, workerTrustCandidateCommand, workerTrustReviewCommand, workerTrustStatusCommand, workersLocalAddCommand, workersLocalListCommand, workersLocalProbePrintCommand, workersLocalRemoveCommand, workersLocalStatusCommand, workflowSyncPolicyLedgerCommand, writeFinalCommitReport, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeLocalSourceSnapshot, writeOrchestratorHandoff, writeProducerLoopArtifact, writeSessionSnapshot };
|
|
4909
|
+
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, FINAL_COMMIT_REPORT_RELATIVE_PATH, FINAL_COMMIT_REPORT_VERSION, ORCHESTRATOR_HANDOFF_RELATIVE_PATH, POLICY_LEDGER_SYNC_REPORT_VERSION, PRODUCER_LOOP_ARTIFACT_VERSION, PRODUCER_LOOP_RELATIVE_DIR, PRODUCER_LOOP_REPORT_VERSION, TEAM_SYNC_STATE_RELATIVE_PATH, WHY_OUTCOME_CAPTURE_VERSION, WORKFLOW_PLANS_RELATIVE_DIR, WORKFLOW_STATE_RELATIVE_PATH, addLocalWorker, agentReadinessAuditCommand, appendActivityEvent, applyLocalContextMutationPlan, archiveInactiveTeamSyncWork, attachLocalContextPackReceipts, autoArchiveTeamSyncState, buildAdaptiveWorkRoutingRecommendation, buildAgentReadinessAuditReport, buildAgenticHandoffMarkdown, buildAgenticTimeline, buildAgenticWorkStatus, buildAutomationInstallPlan, buildCanonicalEvent, buildCodeHooksInstallPlan, buildCodePromotionResult, buildCodeStatusResult, buildCodeSyncResult, buildCodingIntelligenceLedger, buildCollaborationActor, buildCollaborationGuardActionCards, buildCollaborationHooksInstallPlan, buildCommitResultMetadata, buildCompanionEngineeringLeadPlanReport, buildContextPackStats, buildEvalCaseArtifact, buildFinalCommitReport, buildGeneratedWorkflowPlanDocument, buildHostedCodeOverlayUploadPayload, buildHostedGuardPayload, buildJournalCheckpointEntry, buildLocalCallersResult, buildLocalCodeOverlay, buildLocalContextMutationPlan, buildLocalContextPackReceipt, buildLocalContextPackReceipts, buildLocalImpactResult, buildLocalImportsResult, buildLocalNeighborsResult, buildLocalProjectContextValidationReport, buildLocalProjectDriftReport, buildLocalProjectRealityCheck, buildLocalShortestPathResult, buildLocalSourceSnapshot, buildLocalSourceStatus, buildLocalSourceSyncResult, buildMemoryAudit, buildOnboardFolderManifest, buildOrchestratorHandoff, buildPolicyLedgerSyncReport, buildProducerLoopReport, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapBrief, buildSessionBootstrapQuality, buildSessionSnapshot, buildSyncDocumentsDryRun, buildTeamSyncHandoffRecord, buildTeamSyncStartWorkRecord, buildTeamSyncSummary, buildToolCallPayload, buildToolResultPayload, buildVerificationPlan, buildWhyOutcomeCaptureReport, buildWorkerTrustCandidates, buildWorkflowImpactGate, buildWorkflowPhaseCommitReceipt, buildWorkflowPhaseCommitSummary, buildWorkflowPlanScaffold, categoryFromGuardTag, classifyToolResult, cleanContextPacks, codingLedgerExportCommand, collaborationIdeStatusCommand, collectAgentReadinessLocalSignals, collectPolicyLedgerSyncArtifacts, collectSyncDocuments, collectSyncDocumentsInput, compactHostedGuardResources, compareLocalSourceSnapshots, completeTeamSyncStateFromEvidence, completeTeamSyncWorkFromEvidence, contextControlApplyCommand, contextControlDriftCommand, contextControlHostedApplyCommand, contextControlHostedDiffCommand, contextControlPlanCommand, contextControlValidateCommand, contextPackCleanCommand, contextPackPackCommand, contextPackRetrieveCommand, contextPackStatsCommand, controlledWorkerExecuteCommand, createClient, createEmptyCollaborationState, createEmptyTeamSyncState, createLocalQueryCache, deriveLocalCollaborationResourcesFromFiles, detectReleaseSurfacesFromFiles, detectRuntimeEnvironment, evalExportCommand, evalRunCommand, evaluateProjectPolicyGates, extractCommandFromToolInput, extractFilesFromToolInput, formatAgentReadinessAuditReport, formatCompanionEngineeringLeadPlanReport, formatFinalCommitReport, formatOrchestratorRecommendationReason, formatPolicyGateDecision, formatProjectJudgmentCard, formatStuckGuardDecision, getAutomationManifestPath, getAutomationStatus, getCollaborationStatePath, getConfigPath, getContextPackStoragePaths, getLocalCodeOverlayCachePath, getLocalCodePromotionStatePath, getLocalSourceSnapshotPath, getOrchestratorRecommendation, getPlanStepDisplayTitle, getStagedFiles, getStuckGuardInjection, getTeamSyncStatePath, hashWorkerProfile, ingestReferences, installAutomationBundle, leadPlanCommand, listProjectsForApiKey, loadAutomationManifest, loadCollaborationState, loadConfig, loadTeamSyncState, memoryAuditCommand, memoryCleanCandidatesCommand, memoryCompactCommand, memoryHealthCommand, memoryLocalCommand, memoryReviewsCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, readSessionSnapshot, readWorkerTrustEvent, realityCheckCommand, referencesIngestCommand, referencesScanCommand, resolveAutoWorkflowMode, resolveContextPackRecord, resolveFullWorkflowTokenBudget, resolveLocalWorkerRoutingDefaults, resolveQueryFromToolInput, retrieveContextPack, runMemoryGuardCheck, saveCollaborationState, saveConfig, saveTeamSyncState, scanReferences, shouldFailCollaborationGuard, shouldSuggestOrchestratorForWorkflow, shouldSuggestRuntimeForWorkflow, summarizeLocalCodeOverlay, teamSyncSweepCommand, validatePlanResult, verifyCommand, workerTrustCandidateCommand, workerTrustReviewCommand, workerTrustStatusCommand, workersLocalAddCommand, workersLocalListCommand, workersLocalProbePrintCommand, workersLocalRemoveCommand, workersLocalStatusCommand, workflowSyncPolicyLedgerCommand, writeFinalCommitReport, writeLocalCodeOverlayCache, writeLocalCodePromotionState, writeLocalSourceSnapshot, writeOrchestratorHandoff, writeProducerLoopArtifact, writeSessionSnapshot };
|
package/dist/index.js
CHANGED
|
@@ -142,6 +142,8 @@ __export(index_exports, {
|
|
|
142
142
|
completeTeamSyncWorkFromEvidence: () => completeTeamSyncWorkFromEvidence,
|
|
143
143
|
contextControlApplyCommand: () => contextControlApplyCommand,
|
|
144
144
|
contextControlDriftCommand: () => contextControlDriftCommand,
|
|
145
|
+
contextControlHostedApplyCommand: () => contextControlHostedApplyCommand,
|
|
146
|
+
contextControlHostedDiffCommand: () => contextControlHostedDiffCommand,
|
|
145
147
|
contextControlPlanCommand: () => contextControlPlanCommand,
|
|
146
148
|
contextControlValidateCommand: () => contextControlValidateCommand,
|
|
147
149
|
contextPackCleanCommand: () => contextPackCleanCommand,
|
|
@@ -271,7 +273,7 @@ var WORKSPACE_MARKERS = [
|
|
|
271
273
|
".snipara",
|
|
272
274
|
".claude",
|
|
273
275
|
".cursor",
|
|
274
|
-
".
|
|
276
|
+
".kimi-code",
|
|
275
277
|
".vibe",
|
|
276
278
|
"package.json",
|
|
277
279
|
"pnpm-workspace.yaml",
|
|
@@ -1609,6 +1611,26 @@ var RLMClient = class {
|
|
|
1609
1611
|
}
|
|
1610
1612
|
);
|
|
1611
1613
|
}
|
|
1614
|
+
async diffHostedContextControl(input) {
|
|
1615
|
+
return this.dashboardProjectRequest(
|
|
1616
|
+
"/context-control",
|
|
1617
|
+
{ method: "POST", body: { action: "diff", ...input } },
|
|
1618
|
+
{
|
|
1619
|
+
invalidMessage: "Invalid hosted Context Control diff response",
|
|
1620
|
+
validate: (data) => Boolean(data.project?.id && data.plan?.planHash)
|
|
1621
|
+
}
|
|
1622
|
+
);
|
|
1623
|
+
}
|
|
1624
|
+
async applyHostedContextControl(input) {
|
|
1625
|
+
return this.dashboardProjectRequest(
|
|
1626
|
+
"/context-control",
|
|
1627
|
+
{ method: "POST", body: { action: "apply", ...input } },
|
|
1628
|
+
{
|
|
1629
|
+
invalidMessage: "Invalid hosted Context Control apply response",
|
|
1630
|
+
validate: (data) => Boolean(data.project?.id && data.receipt?.receiptId)
|
|
1631
|
+
}
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1612
1634
|
async reindex(options) {
|
|
1613
1635
|
return this.mcpCall("snipara_reindex", {
|
|
1614
1636
|
...options.kind ? { kind: options.kind } : {},
|
|
@@ -1707,7 +1729,7 @@ var SUPPORTED_CLIENTS = /* @__PURE__ */ new Set([
|
|
|
1707
1729
|
"claude-code",
|
|
1708
1730
|
"cursor",
|
|
1709
1731
|
"continue",
|
|
1710
|
-
"
|
|
1732
|
+
"kimi",
|
|
1711
1733
|
"gemini",
|
|
1712
1734
|
"mistral",
|
|
1713
1735
|
"chatgpt",
|
|
@@ -1730,18 +1752,11 @@ var MERGEABLE_JSON_CONFIG_FILES = /* @__PURE__ */ new Set([
|
|
|
1730
1752
|
".cursor/hooks.json",
|
|
1731
1753
|
".cursor/mcp.json",
|
|
1732
1754
|
".gemini/settings.json",
|
|
1755
|
+
".kimi-code/mcp.json",
|
|
1733
1756
|
".vscode/mcp.json",
|
|
1734
|
-
".windsurf/cascade-hooks.json",
|
|
1735
|
-
".windsurf/mcp.json",
|
|
1736
1757
|
"mcp.json"
|
|
1737
1758
|
]);
|
|
1738
|
-
var NATIVE_HOOK_CAPABLE_CLIENTS = /* @__PURE__ */ new Set([
|
|
1739
|
-
"claude-code",
|
|
1740
|
-
"cursor",
|
|
1741
|
-
"windsurf",
|
|
1742
|
-
"gemini",
|
|
1743
|
-
"codex"
|
|
1744
|
-
]);
|
|
1759
|
+
var NATIVE_HOOK_CAPABLE_CLIENTS = /* @__PURE__ */ new Set(["claude-code", "cursor", "kimi", "gemini", "codex"]);
|
|
1745
1760
|
var LOCAL_API_KEY_LOADER = `API_KEY=""
|
|
1746
1761
|
if command -v node >/dev/null 2>&1; then
|
|
1747
1762
|
SNIPARA_CONFIG_ROOT="\${PROJECT_DIR:-$(pwd)}"
|
|
@@ -1809,7 +1824,8 @@ function ensureSupportedClient(client) {
|
|
|
1809
1824
|
}
|
|
1810
1825
|
function configuredAutomationClient(projectDir) {
|
|
1811
1826
|
const config = loadConfig({ cwd: projectDir });
|
|
1812
|
-
|
|
1827
|
+
const client = config.client === "windsurf" ? "custom" : config.client;
|
|
1828
|
+
return client && SUPPORTED_CLIENTS.has(client) ? client : void 0;
|
|
1813
1829
|
}
|
|
1814
1830
|
function resolveAutomationClient(args) {
|
|
1815
1831
|
const configuredClient = configuredAutomationClient(args.projectDir);
|
|
@@ -1975,7 +1991,7 @@ function withLocalApiKeyLoader(file) {
|
|
|
1975
1991
|
}
|
|
1976
1992
|
function isNativeHookFilePath(filePath) {
|
|
1977
1993
|
const normalized = normalizeRelativePath(filePath);
|
|
1978
|
-
return normalized.startsWith(".claude/hooks/") || normalized.startsWith(".cursor/hooks/") || normalized === ".cursor/hooks.json" || normalized.startsWith(".
|
|
1994
|
+
return normalized.startsWith(".claude/hooks/") || normalized.startsWith(".cursor/hooks/") || normalized === ".cursor/hooks.json" || normalized.startsWith(".kimi-code/snipara-plugin/") || normalized.startsWith(".gemini/hooks/") || normalized.startsWith(".codex/hooks/") || normalized === ".codex/hooks.json" || normalized.startsWith(".vscode/hooks/");
|
|
1979
1995
|
}
|
|
1980
1996
|
function assertBundleCompatibleWithClient(client, bundle) {
|
|
1981
1997
|
if (canInstallNativeHookBundle(client)) {
|
|
@@ -5479,7 +5495,7 @@ function appendDeviceFlowHints(url, hints) {
|
|
|
5479
5495
|
}
|
|
5480
5496
|
function setupClientToDeviceClientId(client) {
|
|
5481
5497
|
const normalized = typeof client === "string" ? client.trim().toLowerCase() : void 0;
|
|
5482
|
-
if (normalized === "claude-code" || normalized === "cursor" || normalized === "
|
|
5498
|
+
if (normalized === "claude-code" || normalized === "cursor" || normalized === "kimi" || normalized === "gemini" || normalized === "codex" || normalized === "mistral" || normalized === "continue") {
|
|
5483
5499
|
return normalized;
|
|
5484
5500
|
}
|
|
5485
5501
|
return PROJECT_DEVICE_CLIENT_ID;
|
|
@@ -5578,7 +5594,7 @@ async function runProjectDeviceAuthorization(args) {
|
|
|
5578
5594
|
var SETUP_CLIENTS = /* @__PURE__ */ new Set([
|
|
5579
5595
|
"claude-code",
|
|
5580
5596
|
"cursor",
|
|
5581
|
-
"
|
|
5597
|
+
"kimi",
|
|
5582
5598
|
"codex",
|
|
5583
5599
|
"gemini",
|
|
5584
5600
|
"mistral",
|
|
@@ -5594,13 +5610,13 @@ function maybeNormalizeClient(input) {
|
|
|
5594
5610
|
return SETUP_CLIENTS.has(input) ? input : void 0;
|
|
5595
5611
|
}
|
|
5596
5612
|
function isHookClient(client) {
|
|
5597
|
-
return client === "claude-code" || client === "cursor" || client === "
|
|
5613
|
+
return client === "claude-code" || client === "cursor" || client === "kimi" || client === "gemini" || client === "codex";
|
|
5598
5614
|
}
|
|
5599
5615
|
function canInstallNativeHookClient(client) {
|
|
5600
|
-
return client === "claude-code" || client === "cursor" || client === "
|
|
5616
|
+
return client === "claude-code" || client === "cursor" || client === "kimi" || client === "gemini" || client === "codex";
|
|
5601
5617
|
}
|
|
5602
5618
|
function canUseLegacyHookFallback(client) {
|
|
5603
|
-
return client === "claude-code" || client === "cursor"
|
|
5619
|
+
return client === "claude-code" || client === "cursor";
|
|
5604
5620
|
}
|
|
5605
5621
|
function getNativeHookBlockReason(client) {
|
|
5606
5622
|
if (canInstallNativeHookClient(client)) {
|
|
@@ -5619,7 +5635,7 @@ function formatClientName(client) {
|
|
|
5619
5635
|
const names = {
|
|
5620
5636
|
"claude-code": "Claude Code",
|
|
5621
5637
|
cursor: "Cursor",
|
|
5622
|
-
|
|
5638
|
+
kimi: "Kimi Code CLI",
|
|
5623
5639
|
codex: "OpenAI Codex",
|
|
5624
5640
|
gemini: "Gemini",
|
|
5625
5641
|
mistral: "Mistral Le Chat / Vibe",
|
|
@@ -5942,6 +5958,21 @@ env_http_headers = { "X-Snipara-Session-Id" = "SNIPARA_SESSION_ID" }
|
|
|
5942
5958
|
`;
|
|
5943
5959
|
}
|
|
5944
5960
|
function generateGenericMcpReferenceString(client, projectSlug) {
|
|
5961
|
+
if (client === "kimi") {
|
|
5962
|
+
return `${JSON.stringify(
|
|
5963
|
+
{
|
|
5964
|
+
mcpServers: {
|
|
5965
|
+
snipara: {
|
|
5966
|
+
url: `https://api.snipara.com/mcp/${projectSlug}`,
|
|
5967
|
+
bearerTokenEnvVar: "SNIPARA_API_KEY"
|
|
5968
|
+
}
|
|
5969
|
+
}
|
|
5970
|
+
},
|
|
5971
|
+
null,
|
|
5972
|
+
2
|
|
5973
|
+
)}
|
|
5974
|
+
`;
|
|
5975
|
+
}
|
|
5945
5976
|
if (client === "chatgpt") {
|
|
5946
5977
|
return `${JSON.stringify(
|
|
5947
5978
|
{
|
|
@@ -6090,10 +6121,16 @@ function generateHookConfigString(client, projectSlug = "YOUR_PROJECT_SLUG") {
|
|
|
6090
6121
|
if (client === "cursor") {
|
|
6091
6122
|
return JSON.stringify(generateCursorHookConfig(), null, 2);
|
|
6092
6123
|
}
|
|
6124
|
+
if (client === "kimi") {
|
|
6125
|
+
return generateGenericMcpReferenceString(client, projectSlug);
|
|
6126
|
+
}
|
|
6093
6127
|
if (!canInstallNativeHookClient(client)) {
|
|
6094
6128
|
return generateGenericMcpReferenceString(client, projectSlug);
|
|
6095
6129
|
}
|
|
6096
|
-
const config =
|
|
6130
|
+
const config = generateClaudeHookConfig({
|
|
6131
|
+
preserveOnCompaction: true,
|
|
6132
|
+
restoreOnSessionStart: true
|
|
6133
|
+
});
|
|
6097
6134
|
return JSON.stringify(config, null, 2);
|
|
6098
6135
|
}
|
|
6099
6136
|
function generateClaudeHookPreamble(description) {
|
|
@@ -6330,51 +6367,6 @@ else
|
|
|
6330
6367
|
fi
|
|
6331
6368
|
`;
|
|
6332
6369
|
}
|
|
6333
|
-
function generateWindsurfHookConfig() {
|
|
6334
|
-
return {
|
|
6335
|
-
hooks: {
|
|
6336
|
-
pre_read_code: { command: ".windsurf/hooks/pre-read.sh", timeout: 10 },
|
|
6337
|
-
post_read_code: { command: ".windsurf/hooks/post-read.sh", timeout: 5 },
|
|
6338
|
-
post_write_code: { command: ".windsurf/hooks/post-write.sh", timeout: 5 }
|
|
6339
|
-
}
|
|
6340
|
-
};
|
|
6341
|
-
}
|
|
6342
|
-
function generateWindsurfPreReadScript() {
|
|
6343
|
-
return `#!/bin/bash
|
|
6344
|
-
# Windsurf pre_read_code Hook for Snipara Context Injection
|
|
6345
|
-
|
|
6346
|
-
INPUT=$(cat)
|
|
6347
|
-
if [ -z "$INPUT" ]; then
|
|
6348
|
-
exit 0
|
|
6349
|
-
fi
|
|
6350
|
-
|
|
6351
|
-
snipara-companion pre-tool "$INPUT" || true
|
|
6352
|
-
`;
|
|
6353
|
-
}
|
|
6354
|
-
function generateWindsurfPostReadScript() {
|
|
6355
|
-
return `#!/bin/bash
|
|
6356
|
-
# Windsurf post_read_code Hook for Snipara File Tracking
|
|
6357
|
-
|
|
6358
|
-
INPUT=$(cat)
|
|
6359
|
-
if [ -z "$INPUT" ]; then
|
|
6360
|
-
exit 0
|
|
6361
|
-
fi
|
|
6362
|
-
|
|
6363
|
-
snipara-companion post-tool "$INPUT" || true
|
|
6364
|
-
`;
|
|
6365
|
-
}
|
|
6366
|
-
function generateWindsurfPostWriteScript() {
|
|
6367
|
-
return `#!/bin/bash
|
|
6368
|
-
# Windsurf post_write_code Hook for Snipara File Tracking
|
|
6369
|
-
|
|
6370
|
-
INPUT=$(cat)
|
|
6371
|
-
if [ -z "$INPUT" ]; then
|
|
6372
|
-
exit 0
|
|
6373
|
-
fi
|
|
6374
|
-
|
|
6375
|
-
snipara-companion post-tool "$INPUT" || true
|
|
6376
|
-
`;
|
|
6377
|
-
}
|
|
6378
6370
|
function installHooks(projectDir, projectId, _apiKey, client) {
|
|
6379
6371
|
try {
|
|
6380
6372
|
if (client === "cursor") {
|
|
@@ -6402,28 +6394,6 @@ function installHooks(projectDir, projectId, _apiKey, client) {
|
|
|
6402
6394
|
fs8.writeFileSync(hooksPath, JSON.stringify(generateCursorHookConfig(), null, 2));
|
|
6403
6395
|
return { success: true };
|
|
6404
6396
|
}
|
|
6405
|
-
if (client === "windsurf") {
|
|
6406
|
-
const windsurfDir = path8.join(projectDir, ".windsurf");
|
|
6407
|
-
const hooksDir2 = path8.join(windsurfDir, "hooks");
|
|
6408
|
-
const hooksPath = path8.join(windsurfDir, "cascade-hooks.json");
|
|
6409
|
-
if (!fs8.existsSync(windsurfDir)) {
|
|
6410
|
-
fs8.mkdirSync(windsurfDir, { recursive: true });
|
|
6411
|
-
}
|
|
6412
|
-
if (!fs8.existsSync(hooksDir2)) {
|
|
6413
|
-
fs8.mkdirSync(hooksDir2, { recursive: true });
|
|
6414
|
-
}
|
|
6415
|
-
const preReadPath = path8.join(hooksDir2, "pre-read.sh");
|
|
6416
|
-
fs8.writeFileSync(preReadPath, generateWindsurfPreReadScript());
|
|
6417
|
-
fs8.chmodSync(preReadPath, "755");
|
|
6418
|
-
const postReadPath = path8.join(hooksDir2, "post-read.sh");
|
|
6419
|
-
fs8.writeFileSync(postReadPath, generateWindsurfPostReadScript());
|
|
6420
|
-
fs8.chmodSync(postReadPath, "755");
|
|
6421
|
-
const postWritePath = path8.join(hooksDir2, "post-write.sh");
|
|
6422
|
-
fs8.writeFileSync(postWritePath, generateWindsurfPostWriteScript());
|
|
6423
|
-
fs8.chmodSync(postWritePath, "755");
|
|
6424
|
-
fs8.writeFileSync(hooksPath, JSON.stringify(generateWindsurfHookConfig(), null, 2));
|
|
6425
|
-
return { success: true };
|
|
6426
|
-
}
|
|
6427
6397
|
const claudeDir = path8.join(projectDir, ".claude");
|
|
6428
6398
|
const hooksDir = path8.join(claudeDir, "hooks");
|
|
6429
6399
|
const settingsPath = path8.join(claudeDir, "settings.json");
|
|
@@ -6682,9 +6652,11 @@ async function initCommand(options) {
|
|
|
6682
6652
|
console.log(
|
|
6683
6653
|
"Add this to .cursor/hooks.json, or rerun with --with-hooks to install the full bundle:\n"
|
|
6684
6654
|
);
|
|
6685
|
-
} else if (hookClient === "
|
|
6686
|
-
console.log("\n\u{1F4DD}
|
|
6687
|
-
console.log(
|
|
6655
|
+
} else if (hookClient === "kimi") {
|
|
6656
|
+
console.log("\n\u{1F4DD} Kimi Code CLI MCP Configuration\n");
|
|
6657
|
+
console.log(
|
|
6658
|
+
"Save this as .kimi-code/mcp.json, or rerun with --with-hooks for the plugin bundle:\n"
|
|
6659
|
+
);
|
|
6688
6660
|
} else if (hookClient === "codex") {
|
|
6689
6661
|
console.log("\n\u{1F4DD} OpenAI Codex MCP Configuration\n");
|
|
6690
6662
|
console.log("Merge this into ~/.codex/config.toml or project .codex/config.toml:\n");
|
|
@@ -6729,9 +6701,10 @@ async function initCommand(options) {
|
|
|
6729
6701
|
if (hookClient === "cursor") {
|
|
6730
6702
|
console.log(" 1. Restart Cursor to load the new MCP, rules, and hooks");
|
|
6731
6703
|
console.log(" 2. Verify with: cursor mcp list");
|
|
6732
|
-
} else if (hookClient === "
|
|
6733
|
-
console.log(" 1.
|
|
6734
|
-
console.log(" 2.
|
|
6704
|
+
} else if (hookClient === "kimi") {
|
|
6705
|
+
console.log(" 1. Review and install .kimi-code/snipara-plugin with /plugins install");
|
|
6706
|
+
console.log(" 2. Run /reload or start a new Kimi Code CLI session");
|
|
6707
|
+
console.log(" 3. Run /mcp and verify the Snipara Hosted MCP tools");
|
|
6735
6708
|
} else if (hookClient === "codex") {
|
|
6736
6709
|
console.log(" 1. Restart Codex to load the MCP config and hooks");
|
|
6737
6710
|
console.log(" 2. Verify the snipara MCP tools and /hooks are available in Codex");
|
|
@@ -6757,9 +6730,9 @@ async function initCommand(options) {
|
|
|
6757
6730
|
if (hookClient === "cursor") {
|
|
6758
6731
|
console.log(" 2. Add it to .cursor/hooks.json in your project");
|
|
6759
6732
|
console.log(" 3. Restart Cursor");
|
|
6760
|
-
} else if (hookClient === "
|
|
6761
|
-
console.log(" 2.
|
|
6762
|
-
console.log(" 3. Restart
|
|
6733
|
+
} else if (hookClient === "kimi") {
|
|
6734
|
+
console.log(" 2. Save it as .kimi-code/mcp.json in your project");
|
|
6735
|
+
console.log(" 3. Restart Kimi Code CLI and run /mcp");
|
|
6763
6736
|
} else if (hookClient === "codex") {
|
|
6764
6737
|
console.log(" 2. Add it to ~/.codex/config.toml or project .codex/config.toml");
|
|
6765
6738
|
console.log(" 3. Restart Codex");
|
|
@@ -11519,6 +11492,8 @@ var CONTEXT_MUTATION_APPLY_RECEIPT_VERSION = "snipara.context_mutation_apply_rec
|
|
|
11519
11492
|
var PROJECT_DRIFT_REPORT_VERSION = "snipara.project_drift_report.v0";
|
|
11520
11493
|
var PROJECT_CONTEXT_MANIFEST_VERSION = "snipara.project_context_manifest.v0";
|
|
11521
11494
|
var PROJECT_CONTEXT_VALIDATION_VERSION = "snipara.project_context_validation.v0";
|
|
11495
|
+
var HOSTED_CONTEXT_CONTROL_PLAN_VERSION = "snipara.hosted_context_control_plan.v1";
|
|
11496
|
+
var HOSTED_CONTEXT_CONTROL_APPLY_RECEIPT_VERSION = "snipara.hosted_context_control_apply_receipt.v1";
|
|
11522
11497
|
function buildContextMutationPlan(input) {
|
|
11523
11498
|
const operations = normalizeOperations(input.operations);
|
|
11524
11499
|
if (operations.length === 0) {
|
|
@@ -11637,6 +11612,14 @@ function validateProjectContextManifest(input) {
|
|
|
11637
11612
|
]
|
|
11638
11613
|
};
|
|
11639
11614
|
}
|
|
11615
|
+
function isHostedContextControlPlan(value) {
|
|
11616
|
+
if (!isRecord4(value)) return false;
|
|
11617
|
+
return value.schemaVersion === HOSTED_CONTEXT_CONTROL_PLAN_VERSION && typeof value.planId === "string" && typeof value.planHash === "string" && typeof value.createdAt === "string" && typeof value.projectId === "string" && typeof value.manifestHash === "string" && typeof value.approvalRequired === "boolean" && Array.isArray(value.sources) && Array.isArray(value.operations) && Array.isArray(value.unmanagedRemotePaths) && Array.isArray(value.warnings) && Array.isArray(value.caveats);
|
|
11618
|
+
}
|
|
11619
|
+
function isHostedContextControlApplyReceipt(value) {
|
|
11620
|
+
if (!isRecord4(value)) return false;
|
|
11621
|
+
return value.schemaVersion === HOSTED_CONTEXT_CONTROL_APPLY_RECEIPT_VERSION && typeof value.receiptId === "string" && typeof value.planId === "string" && typeof value.planHash === "string" && typeof value.projectId === "string" && typeof value.appliedAt === "string" && typeof value.status === "string" && Array.isArray(value.sources) && isRecord4(value.reindex) && Array.isArray(value.caveats);
|
|
11622
|
+
}
|
|
11640
11623
|
function hashContextMutationPlanContent(value) {
|
|
11641
11624
|
return hashDecisionJsonValue(value);
|
|
11642
11625
|
}
|
|
@@ -18370,10 +18353,10 @@ var ADAPTER_TARGETS = {
|
|
|
18370
18353
|
profile: "External ADE worker using portable MCP and receipt echo",
|
|
18371
18354
|
instruction: "Use the portable MCP plus companion handoff path, echo the receipt fields, and do not assume native hooks."
|
|
18372
18355
|
},
|
|
18373
|
-
|
|
18374
|
-
label: "
|
|
18375
|
-
profile: "
|
|
18376
|
-
instruction: "
|
|
18356
|
+
kimi: {
|
|
18357
|
+
label: "Kimi Code CLI",
|
|
18358
|
+
profile: "CLI coding agent with project MCP and an explicit Companion plugin",
|
|
18359
|
+
instruction: "Load the project MCP config, install the generated Snipara plugin, keep hook failures fail-open, and return evidence through companion handoff."
|
|
18377
18360
|
},
|
|
18378
18361
|
custom: {
|
|
18379
18362
|
label: "Custom worker",
|
|
@@ -30725,9 +30708,9 @@ var TARGETS = {
|
|
|
30725
30708
|
label: "Orca",
|
|
30726
30709
|
posture: "Use MCP plus companion handoffs; avoid assuming native Snipara task control."
|
|
30727
30710
|
},
|
|
30728
|
-
|
|
30729
|
-
label: "
|
|
30730
|
-
posture: "Use
|
|
30711
|
+
kimi: {
|
|
30712
|
+
label: "Kimi Code CLI",
|
|
30713
|
+
posture: "Use project-local MCP plus the explicit Snipara plugin for fail-open hooks, resume state, and proof gates."
|
|
30731
30714
|
},
|
|
30732
30715
|
custom: {
|
|
30733
30716
|
label: "Custom worker",
|
|
@@ -31214,7 +31197,7 @@ var TARGET_LABELS = {
|
|
|
31214
31197
|
"claude-code": "Claude Code",
|
|
31215
31198
|
cursor: "Cursor",
|
|
31216
31199
|
orca: "Orca",
|
|
31217
|
-
|
|
31200
|
+
kimi: "Kimi Code CLI",
|
|
31218
31201
|
custom: "Custom worker"
|
|
31219
31202
|
};
|
|
31220
31203
|
function normalizeTarget2(target) {
|
|
@@ -35237,6 +35220,24 @@ function applyLocalContextMutationPlan(options) {
|
|
|
35237
35220
|
});
|
|
35238
35221
|
return { plan, receipt: receipt2, writtenFiles: [] };
|
|
35239
35222
|
}
|
|
35223
|
+
if (plan.approvalRequired && !options.approved) {
|
|
35224
|
+
const receipt2 = buildContextMutationApplyReceipt({
|
|
35225
|
+
plan,
|
|
35226
|
+
appliedAt: options.now,
|
|
35227
|
+
status: "blocked",
|
|
35228
|
+
baseRevisionAtApply: resolveGitBaseRevision(cwd),
|
|
35229
|
+
skippedOperations: plan.operations.map((operation) => ({
|
|
35230
|
+
opId: operation.opId,
|
|
35231
|
+
kind: operation.kind,
|
|
35232
|
+
target: operation.target,
|
|
35233
|
+
status: "skipped",
|
|
35234
|
+
contentHash: operation.contentHash,
|
|
35235
|
+
message: "Explicit --approve acknowledgement was not provided."
|
|
35236
|
+
})),
|
|
35237
|
+
caveats: ["Re-run context-control apply with --approve after reviewing the plan."]
|
|
35238
|
+
});
|
|
35239
|
+
return { plan, receipt: receipt2, writtenFiles: [] };
|
|
35240
|
+
}
|
|
35240
35241
|
const currentRevision = resolveGitBaseRevision(cwd);
|
|
35241
35242
|
const staleBase = Boolean(plan.baseRevision.headSha && currentRevision.headSha) && plan.baseRevision.headSha !== currentRevision.headSha;
|
|
35242
35243
|
if (staleBase && !options.allowStaleBase) {
|
|
@@ -35758,6 +35759,155 @@ async function contextControlValidateCommand(options) {
|
|
|
35758
35759
|
process.exitCode = 1;
|
|
35759
35760
|
}
|
|
35760
35761
|
}
|
|
35762
|
+
function resolveHostedContextSources(cwd, manifestPath, report) {
|
|
35763
|
+
if (!report.manifest || report.status === "invalid") {
|
|
35764
|
+
throw new Error("ProjectContext manifest is invalid; run context-control validate first.");
|
|
35765
|
+
}
|
|
35766
|
+
const workspaceRoot2 = fs33.realpathSync(cwd);
|
|
35767
|
+
return report.manifest.sources.map((source2) => {
|
|
35768
|
+
const candidate = path33.resolve(cwd, source2.path);
|
|
35769
|
+
if (!fs33.existsSync(candidate)) {
|
|
35770
|
+
throw new Error(`ProjectContext source is missing: ${source2.path}`);
|
|
35771
|
+
}
|
|
35772
|
+
if (fs33.lstatSync(candidate).isSymbolicLink()) {
|
|
35773
|
+
throw new Error(`ProjectContext source symlinks are not allowed: ${source2.path}`);
|
|
35774
|
+
}
|
|
35775
|
+
const canonical = fs33.realpathSync(candidate);
|
|
35776
|
+
if (canonical !== workspaceRoot2 && !canonical.startsWith(`${workspaceRoot2}${path33.sep}`)) {
|
|
35777
|
+
throw new Error(`ProjectContext source escapes the workspace: ${source2.path}`);
|
|
35778
|
+
}
|
|
35779
|
+
if (!fs33.statSync(canonical).isFile()) {
|
|
35780
|
+
throw new Error(`ProjectContext source must be a file: ${source2.path}`);
|
|
35781
|
+
}
|
|
35782
|
+
const content = fs33.readFileSync(canonical, "utf8");
|
|
35783
|
+
if (Buffer.byteLength(content, "utf8") > 1e6) {
|
|
35784
|
+
throw new Error(`ProjectContext source exceeds 1 MB: ${source2.path}`);
|
|
35785
|
+
}
|
|
35786
|
+
return { ...source2, content };
|
|
35787
|
+
});
|
|
35788
|
+
}
|
|
35789
|
+
async function contextControlHostedDiffCommand(options) {
|
|
35790
|
+
const cwd = process.cwd();
|
|
35791
|
+
const manifestPath = resolveManifestPath(cwd, options.manifest);
|
|
35792
|
+
const report = buildLocalProjectContextValidationReport({ cwd, manifest: manifestPath });
|
|
35793
|
+
const sources = resolveHostedContextSources(cwd, manifestPath, report);
|
|
35794
|
+
const response = await createClient(6e4, { cwd }).diffHostedContextControl({
|
|
35795
|
+
manifestHash: report.manifestHash,
|
|
35796
|
+
sources
|
|
35797
|
+
});
|
|
35798
|
+
const result = {
|
|
35799
|
+
project: response.project,
|
|
35800
|
+
plan: response.plan
|
|
35801
|
+
};
|
|
35802
|
+
if (options.output) {
|
|
35803
|
+
const planPath = path33.resolve(cwd, options.output);
|
|
35804
|
+
writeStableJsonFile(planPath, response.plan);
|
|
35805
|
+
result.planPath = toProjectRelativePath4(planPath, cwd);
|
|
35806
|
+
}
|
|
35807
|
+
if (options.emitDecisionRequest && response.plan.approvalRequired) {
|
|
35808
|
+
if (response.plan.operations.some((operation) => operation.action === "blocked")) {
|
|
35809
|
+
throw new Error("Blocked hosted operations must be removed before requesting approval.");
|
|
35810
|
+
}
|
|
35811
|
+
const request = buildDecisionRequest({
|
|
35812
|
+
producer: {
|
|
35813
|
+
kind: "hosted_context_control",
|
|
35814
|
+
command: "context-control hosted-diff --emit-decision-request",
|
|
35815
|
+
sourceRef: response.plan.planId
|
|
35816
|
+
},
|
|
35817
|
+
decision: "Apply reviewed ProjectContext sources to hosted context",
|
|
35818
|
+
question: `Approve hosted Context Control plan ${response.plan.planId}?`,
|
|
35819
|
+
evidence: {
|
|
35820
|
+
summary: `${response.plan.operations.filter((operation) => operation.action === "create").length} create, ${response.plan.operations.filter((operation) => operation.action === "update").length} update, zero deletes.`,
|
|
35821
|
+
refs: [response.plan.planHash, toProjectRelativePath4(manifestPath, cwd)],
|
|
35822
|
+
items: [
|
|
35823
|
+
{
|
|
35824
|
+
ref: response.plan.planId,
|
|
35825
|
+
title: "Hosted Context Control plan",
|
|
35826
|
+
kind: "hosted_context_control_plan",
|
|
35827
|
+
metadata: {
|
|
35828
|
+
planHash: response.plan.planHash,
|
|
35829
|
+
projectId: response.plan.projectId
|
|
35830
|
+
}
|
|
35831
|
+
}
|
|
35832
|
+
],
|
|
35833
|
+
reasonCodes: ["hosted_context_control_apply", "human_approval_required", "no_delete"],
|
|
35834
|
+
files: response.plan.sources.map((source2) => source2.path),
|
|
35835
|
+
applyPath: "context-control hosted-apply",
|
|
35836
|
+
applyCommand: `snipara-companion context-control hosted-apply --plan ${options.output ?? "<plan.json>"} --approval <resolved-decision.json>`
|
|
35837
|
+
},
|
|
35838
|
+
options: ["approve_hosted_apply", "reject_hosted_apply"],
|
|
35839
|
+
recommendation: "approve_hosted_apply",
|
|
35840
|
+
rationale: "The plan is bounded to reviewed add/update operations and contains no deletes.",
|
|
35841
|
+
blocking: true,
|
|
35842
|
+
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1e3),
|
|
35843
|
+
fingerprintParts: [
|
|
35844
|
+
"hosted_context_control",
|
|
35845
|
+
response.plan.projectId,
|
|
35846
|
+
response.plan.planHash,
|
|
35847
|
+
response.plan.operations.map((operation) => ({
|
|
35848
|
+
path: operation.path,
|
|
35849
|
+
action: operation.action,
|
|
35850
|
+
contentHash: operation.contentHash,
|
|
35851
|
+
previousHash: operation.previousHash ?? null
|
|
35852
|
+
}))
|
|
35853
|
+
]
|
|
35854
|
+
});
|
|
35855
|
+
result.decisionRequest = writeDecisionRequest(request, cwd);
|
|
35856
|
+
}
|
|
35857
|
+
if (options.json) {
|
|
35858
|
+
console.log(JSON.stringify(result, null, 2));
|
|
35859
|
+
return;
|
|
35860
|
+
}
|
|
35861
|
+
console.log(import_chalk13.default.bold("Hosted Context Control Diff"));
|
|
35862
|
+
console.log(`Project: ${response.project.name} (${response.project.id})`);
|
|
35863
|
+
console.log(`Plan: ${response.plan.planId}`);
|
|
35864
|
+
console.log(`Hash: ${response.plan.planHash}`);
|
|
35865
|
+
for (const operation of response.plan.operations) {
|
|
35866
|
+
console.log(`- ${operation.action} ${operation.path}`);
|
|
35867
|
+
}
|
|
35868
|
+
if (result.planPath) console.log(`Plan written: ${result.planPath}`);
|
|
35869
|
+
if (result.decisionRequest?.relativePath) {
|
|
35870
|
+
console.log(`Decision Request: ${result.decisionRequest.relativePath}`);
|
|
35871
|
+
}
|
|
35872
|
+
}
|
|
35873
|
+
async function contextControlHostedApplyCommand(options) {
|
|
35874
|
+
const cwd = process.cwd();
|
|
35875
|
+
const rawPlan = readJsonFile4(path33.resolve(cwd, options.plan));
|
|
35876
|
+
if (!isHostedContextControlPlan(rawPlan)) {
|
|
35877
|
+
throw new Error(`Invalid hosted Context Control plan: ${options.plan}`);
|
|
35878
|
+
}
|
|
35879
|
+
const approval = options.approval ? readJsonFile4(path33.resolve(cwd, options.approval)) : void 0;
|
|
35880
|
+
const response = await createClient(12e4, { cwd }).applyHostedContextControl({
|
|
35881
|
+
plan: rawPlan,
|
|
35882
|
+
approval
|
|
35883
|
+
});
|
|
35884
|
+
if (!isHostedContextControlApplyReceipt(response.receipt)) {
|
|
35885
|
+
throw new Error("Hosted Context Control apply returned an invalid receipt.");
|
|
35886
|
+
}
|
|
35887
|
+
const result = {
|
|
35888
|
+
project: response.project,
|
|
35889
|
+
receipt: response.receipt
|
|
35890
|
+
};
|
|
35891
|
+
if (options.output) {
|
|
35892
|
+
const receiptPath = path33.resolve(cwd, options.output);
|
|
35893
|
+
writeStableJsonFile(receiptPath, response.receipt);
|
|
35894
|
+
result.receiptPath = toProjectRelativePath4(receiptPath, cwd);
|
|
35895
|
+
}
|
|
35896
|
+
if (options.json) {
|
|
35897
|
+
console.log(JSON.stringify(result, null, 2));
|
|
35898
|
+
return;
|
|
35899
|
+
}
|
|
35900
|
+
console.log(import_chalk13.default.bold("Hosted Context Control Apply"));
|
|
35901
|
+
console.log(`Status: ${response.receipt.status}`);
|
|
35902
|
+
console.log(`Receipt: ${response.receipt.receiptId}`);
|
|
35903
|
+
for (const source2 of response.receipt.sources) {
|
|
35904
|
+
console.log(`- ${source2.action} ${source2.path}`);
|
|
35905
|
+
}
|
|
35906
|
+
if (result.receiptPath) console.log(`Receipt written: ${result.receiptPath}`);
|
|
35907
|
+
if (response.receipt.reindex.warning) {
|
|
35908
|
+
console.log(import_chalk13.default.yellow(`Reindex warning: ${response.receipt.reindex.warning}`));
|
|
35909
|
+
}
|
|
35910
|
+
}
|
|
35761
35911
|
function uniqueStrings22(values) {
|
|
35762
35912
|
return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
|
|
35763
35913
|
}
|
|
@@ -37881,7 +38031,7 @@ program.command("login").description("Authenticate this workspace through the Sn
|
|
|
37881
38031
|
});
|
|
37882
38032
|
program.command("init").description("Initialize Snipara companion configuration").option("-k, --api-key <key>", "API key").option("-p, --project <project>", "Project slug or ID").option("--project-id <id>", "Project slug or ID (deprecated alias)").option(
|
|
37883
38033
|
"-c, --client <client>",
|
|
37884
|
-
"Client type (claude-code|cursor|
|
|
38034
|
+
"Client type (claude-code|cursor|kimi|codex|gemini|mistral|chatgpt|vscode|continue|custom)"
|
|
37885
38035
|
).option("-f, --force", "Force overwrite existing configuration").option("-w, --with-hooks", "Install hooks automatically").option("-d, --dir <directory>", "Project directory for hooks (default: current)").action(async (options) => {
|
|
37886
38036
|
await initCommand({
|
|
37887
38037
|
...options,
|
|
@@ -37907,7 +38057,7 @@ program.command("timeline").description("Show recent workflow phase commits, che
|
|
|
37907
38057
|
});
|
|
37908
38058
|
program.command("handoff").description("Create an agent-ready handoff artifact and persist Team Sync continuity").option("--summary <summary>", "What changed in this session").option("--next <next>", "Recommended next action").option("--files <files...>", "Relevant files").option("--attention <attention>", "Attention level (note|watch|review|proof)").option("--risk <risk>", "Compatibility alias for --attention").option("--actor <actor>", "Actor or agent name").option("--adapter-pack", "Attach an ADE Adapter Pack V1 to the handoff artifact").option(
|
|
37909
38059
|
"--target <target>",
|
|
37910
|
-
"ADE adapter-pack target (codex|claude-code|cursor|orca|
|
|
38060
|
+
"ADE adapter-pack target (codex|claude-code|cursor|orca|kimi|custom)"
|
|
37911
38061
|
).option("--context <refs...>", "Context references for the adapter pack").option("--proof <proof...>", "Proof gates expected from the receiving agent").option("--acceptance <criteria...>", "Acceptance criteria for the receiving agent").option(
|
|
37912
38062
|
"--conflict-posture <posture>",
|
|
37913
38063
|
"Conflict posture (continue|wait|split_work|review_only|handoff)"
|
|
@@ -37948,7 +38098,7 @@ program.command("agent-readiness").description("Audit whether a repo/task is rea
|
|
|
37948
38098
|
"Create a local readiness report with proof gaps and a service-pack recommendation"
|
|
37949
38099
|
).option(
|
|
37950
38100
|
"--target <target>",
|
|
37951
|
-
"Target agent or ADE (codex|claude-code|cursor|orca|
|
|
38101
|
+
"Target agent or ADE (codex|claude-code|cursor|orca|kimi|custom)"
|
|
37952
38102
|
).option("--task <task>", "Delegated task summary").option("--changed-files <files...>", "Changed or relevant files").option("--context <refs...>", "Context references, decisions, docs, or source facts").option("--proof <proof...>", "Required proof gates or verification evidence").option("--acceptance <criteria...>", "Acceptance criteria for the delegated work").option("--risk <risks...>", "Known risks or caveats").option("-d, --dir <directory>", "Project directory (default: current)").option("-o, --output <file>", "Write Markdown or JSON report").option("--json", "Print raw JSON").action(async (options) => {
|
|
37953
38103
|
await agentReadinessAuditCommand({
|
|
37954
38104
|
target: options.target,
|
|
@@ -38004,10 +38154,7 @@ program.command("outcome-capture").description("Extract review-pending why/outco
|
|
|
38004
38154
|
});
|
|
38005
38155
|
})
|
|
38006
38156
|
);
|
|
38007
|
-
program.command("lead-plan").description("Create a fail-closed Companion Engineering Lead Plan").option("--task <task>", "Current task or work package summary").option(
|
|
38008
|
-
"--target <target>",
|
|
38009
|
-
"Target agent or ADE (codex|claude-code|cursor|orca|windsurf|custom)"
|
|
38010
|
-
).option("--changed-files <files...>", "Changed or relevant files").option("--context <refs...>", "Context references, decisions, docs, or source facts").option("--proof <proof...>", "Required proof gates or verification evidence").option("--acceptance <criteria...>", "Acceptance criteria for the delegated work").option("--risk <risks...>", "Known risks or caveats").option("--from-cockpit <file>", "Read a Project Health cockpit JSON export").option("--from-plan <file>", "Read a Companion or Project Health Engineering Lead Plan JSON").option("--reconcile", "Reconcile an imported lead plan against current local Companion signals").option("-d, --dir <directory>", "Project directory (default: current)").option("-o, --output <file>", "Write Markdown or JSON report").option("--out <file>", "Alias for --output").option("--json", "Print raw JSON").action(async (options) => {
|
|
38157
|
+
program.command("lead-plan").description("Create a fail-closed Companion Engineering Lead Plan").option("--task <task>", "Current task or work package summary").option("--target <target>", "Target agent or ADE (codex|claude-code|cursor|orca|kimi|custom)").option("--changed-files <files...>", "Changed or relevant files").option("--context <refs...>", "Context references, decisions, docs, or source facts").option("--proof <proof...>", "Required proof gates or verification evidence").option("--acceptance <criteria...>", "Acceptance criteria for the delegated work").option("--risk <risks...>", "Known risks or caveats").option("--from-cockpit <file>", "Read a Project Health cockpit JSON export").option("--from-plan <file>", "Read a Companion or Project Health Engineering Lead Plan JSON").option("--reconcile", "Reconcile an imported lead plan against current local Companion signals").option("-d, --dir <directory>", "Project directory (default: current)").option("-o, --output <file>", "Write Markdown or JSON report").option("--out <file>", "Alias for --output").option("--json", "Print raw JSON").action(async (options) => {
|
|
38011
38158
|
await leadPlanCommand({
|
|
38012
38159
|
task: options.task,
|
|
38013
38160
|
target: options.target,
|
|
@@ -38171,7 +38318,7 @@ program.command("htask").description(
|
|
|
38171
38318
|
program.command("automations").description("Install and inspect dashboard-generated automation hook bundles").addCommand(
|
|
38172
38319
|
new import_commander.Command("install").description("Fetch and install the project automation bundle").option(
|
|
38173
38320
|
"-c, --client <client>",
|
|
38174
|
-
"Client type (claude-code|cursor|
|
|
38321
|
+
"Client type (claude-code|cursor|kimi|codex|gemini|mistral|chatgpt|vscode|continue|custom)"
|
|
38175
38322
|
).option("-d, --dir <directory>", "Project directory (default: current)").option("-f, --force", "Overwrite local files even when they differ").option("--dry-run", "Preview writes without changing files").action(async (options) => {
|
|
38176
38323
|
await automationsInstallCommand({
|
|
38177
38324
|
client: options.client,
|
|
@@ -38674,13 +38821,33 @@ contextControl.command("plan").description("Create a previewable local context m
|
|
|
38674
38821
|
json: Boolean(options.json)
|
|
38675
38822
|
});
|
|
38676
38823
|
});
|
|
38677
|
-
contextControl.command("apply").description("Apply a saved local context mutation plan idempotently").requiredOption("--plan <file>", "Plan JSON produced by context-control plan").option("--allow-stale-base", "Apply even when Git HEAD changed since planning").option("--json", "Print raw JSON").action(async (options) => {
|
|
38824
|
+
contextControl.command("apply").description("Apply a saved local context mutation plan idempotently").requiredOption("--plan <file>", "Plan JSON produced by context-control plan").option("--approve", "Acknowledge manual review when the local plan requires approval").option("--allow-stale-base", "Apply even when Git HEAD changed since planning").option("--json", "Print raw JSON").action(async (options) => {
|
|
38678
38825
|
await contextControlApplyCommand({
|
|
38679
38826
|
plan: options.plan,
|
|
38827
|
+
approved: Boolean(options.approve),
|
|
38680
38828
|
allowStaleBase: Boolean(options.allowStaleBase),
|
|
38681
38829
|
json: Boolean(options.json)
|
|
38682
38830
|
});
|
|
38683
38831
|
});
|
|
38832
|
+
contextControl.command("hosted-diff").description("Compare a local ProjectContext manifest with tenant-scoped hosted context").option("--manifest <file>", "ProjectContext manifest path", "snipara.project-context.json").option("-o, --output <file>", "Write the immutable hosted plan JSON").option(
|
|
38833
|
+
"--emit-decision-request",
|
|
38834
|
+
"Write a pending Decision Request bound to the hosted plan hash"
|
|
38835
|
+
).option("--json", "Print raw JSON").action(async (options) => {
|
|
38836
|
+
await contextControlHostedDiffCommand({
|
|
38837
|
+
manifest: options.manifest,
|
|
38838
|
+
output: options.output,
|
|
38839
|
+
emitDecisionRequest: Boolean(options.emitDecisionRequest),
|
|
38840
|
+
json: Boolean(options.json)
|
|
38841
|
+
});
|
|
38842
|
+
});
|
|
38843
|
+
contextControl.command("hosted-apply").description("Apply an approved add/update-only hosted Context Control plan").requiredOption("--plan <file>", "Plan JSON produced by context-control hosted-diff").option("--approval <file>", "Resolved Decision Request artifact for mutating plans").option("-o, --output <file>", "Write the hosted apply receipt JSON").option("--json", "Print raw JSON").action(async (options) => {
|
|
38844
|
+
await contextControlHostedApplyCommand({
|
|
38845
|
+
plan: options.plan,
|
|
38846
|
+
approval: options.approval,
|
|
38847
|
+
output: options.output,
|
|
38848
|
+
json: Boolean(options.json)
|
|
38849
|
+
});
|
|
38850
|
+
});
|
|
38684
38851
|
contextControl.command("drift").description("Report local project drift across git, workflow, decisions, and context plans").option("--json", "Print raw JSON").action(async (options) => {
|
|
38685
38852
|
await contextControlDriftCommand({ json: Boolean(options.json) });
|
|
38686
38853
|
});
|
|
@@ -40138,6 +40305,8 @@ if (require.main === module) {
|
|
|
40138
40305
|
completeTeamSyncWorkFromEvidence,
|
|
40139
40306
|
contextControlApplyCommand,
|
|
40140
40307
|
contextControlDriftCommand,
|
|
40308
|
+
contextControlHostedApplyCommand,
|
|
40309
|
+
contextControlHostedDiffCommand,
|
|
40141
40310
|
contextControlPlanCommand,
|
|
40142
40311
|
contextControlValidateCommand,
|
|
40143
40312
|
contextPackCleanCommand,
|
package/docs/FULL_REFERENCE.md
CHANGED
|
@@ -233,7 +233,7 @@ snipara-companion workflow producer-report
|
|
|
233
233
|
snipara-companion workflow producer-review --latest --outcome useful --reviewer alice
|
|
234
234
|
snipara-companion workflow run --adaptive-routing-dry-run --route-local-workers "document a scoped change"
|
|
235
235
|
snipara-companion context-control plan --summary "record reviewed context state" --output .snipara/context-control/plans/demo.json
|
|
236
|
-
snipara-companion context-control apply --plan .snipara/context-control/plans/demo.json
|
|
236
|
+
snipara-companion context-control apply --plan .snipara/context-control/plans/demo.json --approve
|
|
237
237
|
snipara-companion context-control drift
|
|
238
238
|
snipara-companion context-control validate --manifest snipara.project-context.json
|
|
239
239
|
snipara-companion lead-plan --task "ship auth hardening" --changed-files src/auth.ts --proof "pnpm test auth" --acceptance "auth tests pass"
|
|
@@ -339,8 +339,9 @@ snipara-companion workflow resume --include-session-context
|
|
|
339
339
|
- `context-control plan` writes a content-hashed local Context Mutation Plan V0
|
|
340
340
|
for a bounded operation. The plan records the Git base and remains a preview
|
|
341
341
|
until `context-control apply` writes the exact planned state.
|
|
342
|
-
- `context-control apply --plan <file
|
|
343
|
-
Git bases by default, writes only under
|
|
342
|
+
- `context-control apply --plan <file> --approve` verifies the plan hash, records
|
|
343
|
+
explicit review, rejects stale Git bases by default, writes only under
|
|
344
|
+
`.snipara/context-control/`, and emits
|
|
344
345
|
an apply receipt linked to the plan hash.
|
|
345
346
|
- `context-control drift` is a read-only Project Drift V0 report. It checks Git
|
|
346
347
|
upstream state, scoped Git dirty files, managed workflow state, pending
|
|
@@ -352,9 +353,21 @@ snipara-companion workflow resume --include-session-context
|
|
|
352
353
|
`IN_SYNC`.
|
|
353
354
|
- `context-control validate --manifest snipara.project-context.json` validates
|
|
354
355
|
Context as Code V0. The manifest is JSON metadata declaring context sources,
|
|
355
|
-
tiers, authority, freshness, and review policies.
|
|
356
|
-
|
|
357
|
-
|
|
356
|
+
tiers, authority, freshness, and review policies. Validation itself does not
|
|
357
|
+
upload content or mutate hosted state.
|
|
358
|
+
- Context Control V1 uses `context-control hosted-diff` to produce a
|
|
359
|
+
tenant-scoped immutable plan and optional Decision Request, then
|
|
360
|
+
`context-control hosted-apply` to apply the resolved plan. The server rechecks
|
|
361
|
+
remote hashes atomically, allows only create/update, never deletes unmanaged
|
|
362
|
+
remote paths, blocks managed authority promotions, requires EDITOR API-key
|
|
363
|
+
access, and returns a per-source receipt plus reindex status.
|
|
364
|
+
|
|
365
|
+
```text
|
|
366
|
+
$ snipara-companion context-control hosted-diff --manifest snipara.project-context.json --output .snipara/context-control/plans/hosted.json --emit-decision-request
|
|
367
|
+
$ snipara-companion workflow decide <request-id> --choose approve_hosted_apply --reviewer <name>
|
|
368
|
+
$ snipara-companion context-control hosted-apply --plan .snipara/context-control/plans/hosted.json --approval .snipara/decisions/resolved/<request-id>.json
|
|
369
|
+
```
|
|
370
|
+
|
|
358
371
|
- `lead-plan` turns local workflow state, Team Sync, file scope, context refs,
|
|
359
372
|
proof gates, and acceptance criteria into an advisory Engineering Lead Plan.
|
|
360
373
|
It emits worker recommendations and handoff contracts, keeps
|
|
@@ -690,7 +703,7 @@ Output includes:
|
|
|
690
703
|
## Agent Readiness Audits
|
|
691
704
|
|
|
692
705
|
Use `agent-readiness audit` when a team wants to know whether a task can be
|
|
693
|
-
delegated safely to Codex, Claude Code, Cursor, Orca,
|
|
706
|
+
delegated safely to Codex, Claude Code, Cursor, Orca, Kimi Code CLI, or a custom
|
|
694
707
|
worker:
|
|
695
708
|
|
|
696
709
|
```bash
|
|
@@ -770,7 +783,7 @@ Project Policy.
|
|
|
770
783
|
## ADE Adapter Pack Handoffs
|
|
771
784
|
|
|
772
785
|
Use `handoff --adapter-pack` when the receiving execution cockpit is Codex,
|
|
773
|
-
Claude Code, Cursor, Orca,
|
|
786
|
+
Claude Code, Cursor, Orca, Kimi Code CLI, or a custom worker:
|
|
774
787
|
|
|
775
788
|
```bash
|
|
776
789
|
snipara-companion handoff \
|
|
@@ -800,7 +813,7 @@ The built-in `init` and `automations` flows share these client names:
|
|
|
800
813
|
|
|
801
814
|
- `claude-code`
|
|
802
815
|
- `cursor`
|
|
803
|
-
- `
|
|
816
|
+
- `kimi`
|
|
804
817
|
- `codex`
|
|
805
818
|
- `gemini`
|
|
806
819
|
- `mistral`
|
|
@@ -809,7 +822,7 @@ The built-in `init` and `automations` flows share these client names:
|
|
|
809
822
|
- `continue`
|
|
810
823
|
- `custom`
|
|
811
824
|
|
|
812
|
-
Claude Code, Cursor,
|
|
825
|
+
Claude Code, Cursor, Kimi Code CLI, Codex, and Gemini have native or generated hook
|
|
813
826
|
surfaces. Mistral, ChatGPT, VS Code, Continue, and custom clients are MCP-first presets: companion
|
|
814
827
|
prints the hosted MCP config/reference and installs dashboard-generated
|
|
815
828
|
automation files only when the hosted project exposes a bundle for that client.
|
|
@@ -828,12 +841,21 @@ npx -y snipara-companion@latest init --with-hooks --client claude-code
|
|
|
828
841
|
npx -y snipara-companion@latest init --with-hooks --client cursor
|
|
829
842
|
```
|
|
830
843
|
|
|
831
|
-
###
|
|
844
|
+
### Kimi Code CLI
|
|
832
845
|
|
|
833
846
|
```bash
|
|
834
|
-
npx -y snipara-companion@latest init --with-hooks --client
|
|
847
|
+
npx -y snipara-companion@latest init --with-hooks --client kimi
|
|
848
|
+
npx -y snipara-companion@latest automations install --client kimi
|
|
849
|
+
# In Kimi Code, after reviewing the generated files:
|
|
850
|
+
/plugins install .kimi-code/snipara-plugin
|
|
835
851
|
```
|
|
836
852
|
|
|
853
|
+
Kimi reads `.kimi-code/mcp.json` and resolves `SNIPARA_API_KEY` from the launch
|
|
854
|
+
environment. Its plugin hooks are fail-open, so keep manual approval for risky
|
|
855
|
+
tools and treat Hosted MCP tenant checks plus Companion guards as the hard
|
|
856
|
+
boundary. Kimi installs plugins per user; the generated handler no-ops outside
|
|
857
|
+
workspaces carrying a Snipara project or Companion marker.
|
|
858
|
+
|
|
837
859
|
### Codex
|
|
838
860
|
|
|
839
861
|
```bash
|
|
@@ -858,7 +880,7 @@ bundle generated by Project Automation in the dashboard:
|
|
|
858
880
|
```bash
|
|
859
881
|
npx -y snipara-companion@latest automations install --client claude-code
|
|
860
882
|
npx -y snipara-companion@latest automations install --client cursor
|
|
861
|
-
npx -y snipara-companion@latest automations install --client
|
|
883
|
+
npx -y snipara-companion@latest automations install --client kimi
|
|
862
884
|
npx -y snipara-companion@latest automations install --client codex
|
|
863
885
|
npx -y snipara-companion@latest automations status
|
|
864
886
|
npx -y snipara-companion@latest automations diff
|
|
@@ -876,7 +898,7 @@ unless you pass `--force`.
|
|
|
876
898
|
Agent instruction files are always merged, not replaced. Existing `AGENTS.md`,
|
|
877
899
|
`CLAUDE.md`, `GEMINI.md`, `.cursorrules`, and Copilot instructions keep their
|
|
878
900
|
local content while Snipara adds or refreshes a marked Snipara section. Known
|
|
879
|
-
client JSON configs for Claude, Cursor, Continue.dev,
|
|
901
|
+
client JSON configs for Claude, Cursor, Continue.dev, Kimi, Gemini, VS Code,
|
|
880
902
|
and root `mcp.json` are deep-merged so existing servers and hooks are preserved.
|
|
881
903
|
Mistral generates MCP-first files (`MISTRAL.md`, Vibe config, Le Chat connector
|
|
882
904
|
reference, and LangChain `ChatMistralAI.bindTools` snippets); Mistral request
|
|
@@ -912,7 +934,7 @@ Options:
|
|
|
912
934
|
- `--api-key <key>` - Skip prompt for API key
|
|
913
935
|
- `--project <project>` - Skip prompt for project slug or ID
|
|
914
936
|
- `--project-id <id>` - Deprecated alias for `--project`
|
|
915
|
-
- `--client <client>` - `claude-code`, `cursor`, `
|
|
937
|
+
- `--client <client>` - `claude-code`, `cursor`, `kimi`, `codex`, `gemini`, `mistral`, `chatgpt`, `vscode`, `continue`, or `custom`
|
|
916
938
|
- `--with-hooks` - Install hooks automatically
|
|
917
939
|
- `--force` - Overwrite existing generated files
|
|
918
940
|
- `--dir <directory>` - Target directory for generated files
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snipara-companion",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.2",
|
|
4
4
|
"description": "Local-first CLI that asks your repo what breaks before an AI coding agent edits it.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"llm",
|
|
32
32
|
"claude",
|
|
33
33
|
"cursor",
|
|
34
|
-
"
|
|
34
|
+
"kimi",
|
|
35
35
|
"codex",
|
|
36
36
|
"gemini",
|
|
37
37
|
"mistral",
|