snipara-companion 3.2.2 → 3.2.3
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 +12 -3
- package/dist/index.d.ts +14 -2
- package/dist/index.js +538 -82
- package/docs/FULL_REFERENCE.md +14 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,7 @@ npx -y snipara-companion workflow producer-triage
|
|
|
71
71
|
npx -y snipara-companion workflow decisions
|
|
72
72
|
npx -y snipara-companion workflow decide decision-abc123 --choose accept_all --reviewer alice
|
|
73
73
|
npx -y snipara-companion workflow timeline
|
|
74
|
+
npx -y snipara-companion workflow timeline --export md
|
|
74
75
|
npx -y snipara-companion workflow session --json
|
|
75
76
|
npx -y snipara-companion workflow producer-report
|
|
76
77
|
npx -y snipara-companion workflow producer-review --latest --outcome useful --reviewer alice
|
|
@@ -84,8 +85,14 @@ verification hints.
|
|
|
84
85
|
`workflow timeline` reads the append-only activity log at
|
|
85
86
|
`.snipara/activity/timeline.jsonl`. `workflow session` derives
|
|
86
87
|
`.snipara/activity/session.json` for fast local resume and Orchestrator dogfood;
|
|
87
|
-
Session Snapshot V0
|
|
88
|
-
|
|
88
|
+
Session Snapshot V0 includes latest activity, risk reasons, touched files, a
|
|
89
|
+
next action, and advisory Intent Detection V0. Intent Detection V0 reports the
|
|
90
|
+
inferred intent, confidence, reason-code signals, local evidence counts, and a
|
|
91
|
+
suggested workflow mode hint for the human or agent to consider. It is
|
|
92
|
+
observational and keeps `hardRoutingAllowed=false` until explicit routing policy
|
|
93
|
+
and receipts exist.
|
|
94
|
+
`workflow timeline --export md` prints a compact redacted Markdown timeline for
|
|
95
|
+
handoff or publication.
|
|
89
96
|
|
|
90
97
|
Workflow `phase-commit` and `final-commit` also emit Producer Loop artifacts
|
|
91
98
|
under `.snipara/producer-loop/`. These are local review evidence backed by the
|
|
@@ -116,7 +123,9 @@ Other producers such as `outcome-capture preview --emit-decisions`,
|
|
|
116
123
|
paths declared; they do not write canonical memory directly. `memory reviews`
|
|
117
124
|
is the hosted-memory review connector: it reads review queue, cleanup, and
|
|
118
125
|
duplicate candidate surfaces, summarizes the items for the LLM, and only writes
|
|
119
|
-
local Decision Requests when `--emit-decisions` is passed.
|
|
126
|
+
local Decision Requests when `--emit-decisions` is passed. Its JSON output
|
|
127
|
+
includes `emittedCount`, `emittedRequestIds`, and an `emitted` summary so an
|
|
128
|
+
agent can continue without re-listing pending requests.
|
|
120
129
|
|
|
121
130
|
## Local First, Hosted When Useful
|
|
122
131
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { ProjectRealityCheckResult, ProjectIntelligenceEngineeringLeadPlanSummary } from '@snipara/project-intelligence-contracts';
|
|
2
|
+
import { ProjectIntentDetectionResult, ProjectRealityCheckResult, ProjectIntelligenceEngineeringLeadPlanSummary } from '@snipara/project-intelligence-contracts';
|
|
3
3
|
|
|
4
4
|
declare function resolveQueryFromToolInput(toolInput?: string, tool?: string): string | null;
|
|
5
5
|
|
|
@@ -1563,6 +1563,16 @@ interface SessionSnapshot {
|
|
|
1563
1563
|
handoffCount: number;
|
|
1564
1564
|
latestHandoffAt?: string;
|
|
1565
1565
|
};
|
|
1566
|
+
summary: {
|
|
1567
|
+
latestActivityAt?: string;
|
|
1568
|
+
latestActivityTitle?: string;
|
|
1569
|
+
latestActivityKind?: string;
|
|
1570
|
+
risk: "none" | "watch" | "risk";
|
|
1571
|
+
riskReasons: string[];
|
|
1572
|
+
touchedFiles: string[];
|
|
1573
|
+
recommendedNextAction: string;
|
|
1574
|
+
};
|
|
1575
|
+
intentDetection: ProjectIntentDetectionResult;
|
|
1566
1576
|
routing: {
|
|
1567
1577
|
hardRoutingAllowed: false;
|
|
1568
1578
|
reason: string;
|
|
@@ -1600,6 +1610,7 @@ declare function writeSessionSnapshot(options?: {
|
|
|
1600
1610
|
cwd?: string;
|
|
1601
1611
|
limit?: number;
|
|
1602
1612
|
}): SessionSnapshot;
|
|
1613
|
+
declare function readSessionSnapshot(cwd?: string): SessionSnapshot | null;
|
|
1603
1614
|
|
|
1604
1615
|
type LocalCodeOverlayMode = "working_tree" | "local_commit";
|
|
1605
1616
|
type LocalCodeOverlayKind = "none" | "local_commit" | "working_tree" | "mixed";
|
|
@@ -2017,6 +2028,7 @@ interface ProjectIntelligenceBrief {
|
|
|
2017
2028
|
memoryHealth?: Record<string, unknown>;
|
|
2018
2029
|
codeImpact?: Record<string, unknown>;
|
|
2019
2030
|
codeImpactSourceSelection?: CodeGraphSourceSelection;
|
|
2031
|
+
localSessionSnapshot?: SessionSnapshot;
|
|
2020
2032
|
verificationPlan?: VerificationPlan;
|
|
2021
2033
|
judgmentCard?: ProjectIntelligenceJudgmentCard;
|
|
2022
2034
|
errors: Array<{
|
|
@@ -4212,4 +4224,4 @@ declare function buildOrchestratorHandoff(options: OrchestratorHandoffOptions):
|
|
|
4212
4224
|
declare function buildAdaptiveWorkRoutingRecommendation(options: AdaptiveWorkRoutingOptions): AdaptiveWorkRoutingRecommendation;
|
|
4213
4225
|
declare function writeOrchestratorHandoff(options: OrchestratorHandoffOptions): WrittenOrchestratorHandoff;
|
|
4214
4226
|
|
|
4215
|
-
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, 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, 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, buildProducerLoopReport, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapQuality, buildSessionSnapshot, 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, memoryReviewsCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, 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, writeProducerLoopArtifact, writeSessionSnapshot };
|
|
4227
|
+
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, 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, 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, buildProducerLoopReport, buildProjectIntelligenceBrief, buildProjectIntelligenceRun, buildProjectJudgmentCard, buildSessionBootstrapQuality, buildSessionSnapshot, 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, memoryReviewsCommand, normalizeCollaborationFiles, normalizeGuardTag, normalizeWorkflowPlanInput, outcomeCapturePreviewCommand, packContext, parseCollaborationResources, projectIntelligenceBriefCommand, projectIntelligenceRunCommand, readActivityTimeline, readLocalCodeOverlayCache, readLocalCodePromotionState, readLocalSourceSnapshot, readLocalWorkersConfig, readSessionSnapshot, 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, writeProducerLoopArtifact, writeSessionSnapshot };
|
package/dist/index.js
CHANGED
|
@@ -188,6 +188,7 @@ __export(index_exports, {
|
|
|
188
188
|
readLocalCodePromotionState: () => readLocalCodePromotionState,
|
|
189
189
|
readLocalSourceSnapshot: () => readLocalSourceSnapshot,
|
|
190
190
|
readLocalWorkersConfig: () => readLocalWorkersConfig,
|
|
191
|
+
readSessionSnapshot: () => readSessionSnapshot,
|
|
191
192
|
realityCheckCommand: () => realityCheckCommand,
|
|
192
193
|
referencesIngestCommand: () => referencesIngestCommand,
|
|
193
194
|
referencesScanCommand: () => referencesScanCommand,
|
|
@@ -10139,6 +10140,231 @@ function sortJsonValue(value) {
|
|
|
10139
10140
|
return value;
|
|
10140
10141
|
}
|
|
10141
10142
|
|
|
10143
|
+
// ../project-intelligence-contracts/src/intent-detection.ts
|
|
10144
|
+
var INTENT_DETECTION_VERSION = "snipara.intent_detection.v0";
|
|
10145
|
+
var PROJECT_INTENT_DETECTION_INTENTS = [
|
|
10146
|
+
"debugging",
|
|
10147
|
+
"implementing_feature",
|
|
10148
|
+
"refactoring",
|
|
10149
|
+
"reviewing",
|
|
10150
|
+
"investigating",
|
|
10151
|
+
"release_deploy",
|
|
10152
|
+
"unknown"
|
|
10153
|
+
];
|
|
10154
|
+
var PROJECT_INTENT_DETECTION_ACTIONS = [
|
|
10155
|
+
"read",
|
|
10156
|
+
"write",
|
|
10157
|
+
"test",
|
|
10158
|
+
"build",
|
|
10159
|
+
"deploy",
|
|
10160
|
+
"review",
|
|
10161
|
+
"decision",
|
|
10162
|
+
"handoff",
|
|
10163
|
+
"unknown"
|
|
10164
|
+
];
|
|
10165
|
+
var INTENT_PRIORITY = {
|
|
10166
|
+
release_deploy: 60,
|
|
10167
|
+
debugging: 50,
|
|
10168
|
+
implementing_feature: 40,
|
|
10169
|
+
refactoring: 30,
|
|
10170
|
+
reviewing: 20,
|
|
10171
|
+
investigating: 10,
|
|
10172
|
+
unknown: 0
|
|
10173
|
+
};
|
|
10174
|
+
function textMatches(text, patterns) {
|
|
10175
|
+
return patterns.some((pattern) => pattern.test(text));
|
|
10176
|
+
}
|
|
10177
|
+
function uniqueStrings5(values) {
|
|
10178
|
+
return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
|
|
10179
|
+
}
|
|
10180
|
+
function compactSignals(signals) {
|
|
10181
|
+
const byCode = /* @__PURE__ */ new Map();
|
|
10182
|
+
for (const signal of signals) {
|
|
10183
|
+
const existing = byCode.get(signal.code);
|
|
10184
|
+
if (!existing || signal.weight > existing.weight) {
|
|
10185
|
+
byCode.set(signal.code, signal);
|
|
10186
|
+
}
|
|
10187
|
+
}
|
|
10188
|
+
return [...byCode.values()];
|
|
10189
|
+
}
|
|
10190
|
+
function metadataString(metadata, key) {
|
|
10191
|
+
const value = metadata?.[key];
|
|
10192
|
+
return typeof value === "string" ? value : "";
|
|
10193
|
+
}
|
|
10194
|
+
function inferAction(event) {
|
|
10195
|
+
const explicitAction = metadataString(event.metadata, "action");
|
|
10196
|
+
if (PROJECT_INTENT_DETECTION_ACTIONS.includes(explicitAction)) {
|
|
10197
|
+
return explicitAction;
|
|
10198
|
+
}
|
|
10199
|
+
const text = [event.kind, event.source, event.title, event.summary, event.detail, event.outcome].filter(Boolean).join(" ").toLowerCase();
|
|
10200
|
+
if (textMatches(text, [/\b(test|tests|spec|vitest|jest|pytest|node --test)\b/i])) return "test";
|
|
10201
|
+
if (textMatches(text, [/\b(build|type-?check|lint|compile)\b/i])) return "build";
|
|
10202
|
+
if (textMatches(text, [/\b(deploy|release|publish|rollout|production)\b/i])) return "deploy";
|
|
10203
|
+
if (textMatches(text, [/\b(review|audit|inspect|read|look(ed)? at|rg|grep)\b/i])) return "read";
|
|
10204
|
+
if (textMatches(text, [/\b(decision|decide|policy suggestion|manual apply)\b/i]))
|
|
10205
|
+
return "decision";
|
|
10206
|
+
if (textMatches(text, [/\b(handoff|resume|final-commit|phase-commit)\b/i])) return "handoff";
|
|
10207
|
+
if (textMatches(text, [/\b(edit|write|add(ed)?|implement|fix|refactor|change(d)?)\b/i])) {
|
|
10208
|
+
return "write";
|
|
10209
|
+
}
|
|
10210
|
+
return "unknown";
|
|
10211
|
+
}
|
|
10212
|
+
function normalizeEvent(event) {
|
|
10213
|
+
return {
|
|
10214
|
+
text: [event.kind, event.source, event.title, event.summary, event.detail, event.outcome].filter(Boolean).join(" ").toLowerCase(),
|
|
10215
|
+
files: uniqueStrings5(event.files ?? []),
|
|
10216
|
+
action: inferAction(event),
|
|
10217
|
+
outcome: event.outcome?.toLowerCase()
|
|
10218
|
+
};
|
|
10219
|
+
}
|
|
10220
|
+
function actionCount(events, action) {
|
|
10221
|
+
return events.filter((event) => event.action === action).length;
|
|
10222
|
+
}
|
|
10223
|
+
function addSignal(scores, intent, code2, weight, detail) {
|
|
10224
|
+
const signals = scores.get(intent) ?? [];
|
|
10225
|
+
signals.push({ code: code2, intent, weight, ...detail ? { detail } : {} });
|
|
10226
|
+
scores.set(intent, signals);
|
|
10227
|
+
}
|
|
10228
|
+
function confidenceFor(score, signalCount) {
|
|
10229
|
+
if (score >= 7 && signalCount >= 3) return "high";
|
|
10230
|
+
if (score >= 4 && signalCount >= 2) return "medium";
|
|
10231
|
+
return "low";
|
|
10232
|
+
}
|
|
10233
|
+
function suggestedModeFor(intent, confidence, files) {
|
|
10234
|
+
if (intent === "release_deploy") return "full";
|
|
10235
|
+
if (intent === "refactoring" && (confidence !== "low" || files.length >= 5)) return "full";
|
|
10236
|
+
if (intent === "debugging" && confidence === "high") return "standard";
|
|
10237
|
+
if (intent === "investigating" || intent === "reviewing") return "lite";
|
|
10238
|
+
return files.length >= 5 ? "standard" : "lite";
|
|
10239
|
+
}
|
|
10240
|
+
function buildIntentDetectionFromTimeline(events) {
|
|
10241
|
+
const normalized = events.map(normalizeEvent);
|
|
10242
|
+
const text = normalized.map((event) => event.text).join("\n");
|
|
10243
|
+
const files = uniqueStrings5(normalized.flatMap((event) => event.files));
|
|
10244
|
+
const testFiles2 = files.filter((file) => /(test|spec)\.|__tests__|tests?\//i.test(file));
|
|
10245
|
+
const docsFiles = files.filter((file) => /(^|\/)(docs?|README|CHANGELOG)|\.md$/i.test(file));
|
|
10246
|
+
const packageFiles = files.filter(
|
|
10247
|
+
(file) => /package\.json|CHANGELOG|README|pyproject|setup\.py|publish/i.test(file)
|
|
10248
|
+
);
|
|
10249
|
+
const sourceFiles = files.filter((file) => /\.(ts|tsx|js|jsx|py|go|rs|java|rb)$/i.test(file));
|
|
10250
|
+
const failureEvents = normalized.filter(
|
|
10251
|
+
(event) => event.outcome === "failed" || textMatches(event.text, [/\b(fail(ed|ure)?|error|timeout|retry|regression)\b/i])
|
|
10252
|
+
);
|
|
10253
|
+
const scores = /* @__PURE__ */ new Map();
|
|
10254
|
+
if (failureEvents.length > 0) {
|
|
10255
|
+
addSignal(scores, "debugging", "failure_signal", 3, `${failureEvents.length} failure event(s)`);
|
|
10256
|
+
}
|
|
10257
|
+
if (testFiles2.length > 0 && (failureEvents.length > 0 || actionCount(normalized, "test") > 0)) {
|
|
10258
|
+
addSignal(scores, "debugging", "test_loop_signal", 3, `${testFiles2.length} test file(s)`);
|
|
10259
|
+
}
|
|
10260
|
+
if (failureEvents.length > 0 && actionCount(normalized, "write") > 0 && files.some((file) => failureEvents.some((event) => event.files.includes(file)))) {
|
|
10261
|
+
addSignal(scores, "debugging", "same_file_edited_after_failure", 2);
|
|
10262
|
+
}
|
|
10263
|
+
if (textMatches(text, [/\b(deploy|deployment|release|publish|production|rollout)\b/i])) {
|
|
10264
|
+
addSignal(scores, "release_deploy", "release_or_deploy_terms", 3);
|
|
10265
|
+
}
|
|
10266
|
+
if (packageFiles.length > 0) {
|
|
10267
|
+
addSignal(scores, "release_deploy", "package_or_release_files", 2);
|
|
10268
|
+
}
|
|
10269
|
+
if (docsFiles.length > 0 && packageFiles.length > 0) {
|
|
10270
|
+
addSignal(scores, "release_deploy", "docs_plus_package_surface", 2);
|
|
10271
|
+
}
|
|
10272
|
+
if (actionCount(normalized, "deploy") > 0) {
|
|
10273
|
+
addSignal(scores, "release_deploy", "deploy_action", 3);
|
|
10274
|
+
}
|
|
10275
|
+
if (textMatches(text, [/\b(feature|implement(ed|ing)?|add(ed|s)?|new behavior|ship)\b/i])) {
|
|
10276
|
+
addSignal(scores, "implementing_feature", "feature_language", 3);
|
|
10277
|
+
}
|
|
10278
|
+
if (testFiles2.length > 0 && sourceFiles.length > 0) {
|
|
10279
|
+
addSignal(scores, "implementing_feature", "tests_plus_product_files", 2);
|
|
10280
|
+
}
|
|
10281
|
+
if (actionCount(normalized, "write") > 0 && sourceFiles.length > 0) {
|
|
10282
|
+
addSignal(scores, "implementing_feature", "source_write_signal", 2);
|
|
10283
|
+
}
|
|
10284
|
+
if (textMatches(text, [/\b(refactor|restructure|cleanup|rename|dedupe|simplif(y|ied))\b/i])) {
|
|
10285
|
+
addSignal(scores, "refactoring", "refactor_language", 3);
|
|
10286
|
+
}
|
|
10287
|
+
if (files.length >= 5 && !textMatches(text, [/\b(feature|deploy|release|publish)\b/i])) {
|
|
10288
|
+
addSignal(scores, "refactoring", "broad_change_without_feature_or_release_terms", 2);
|
|
10289
|
+
}
|
|
10290
|
+
if (sourceFiles.length >= 4 && testFiles2.length === 0) {
|
|
10291
|
+
addSignal(scores, "refactoring", "many_source_files_without_tests", 1);
|
|
10292
|
+
}
|
|
10293
|
+
if (textMatches(text, [/\b(review|audit|inspect|triage|assessment|verdict)\b/i])) {
|
|
10294
|
+
addSignal(scores, "reviewing", "review_language", 3);
|
|
10295
|
+
}
|
|
10296
|
+
if (actionCount(normalized, "decision") > 0) {
|
|
10297
|
+
addSignal(scores, "reviewing", "decision_review_signal", 2);
|
|
10298
|
+
}
|
|
10299
|
+
if (textMatches(text, [/\b(policy suggestion|manual apply|required|reject|approve)\b/i])) {
|
|
10300
|
+
addSignal(scores, "reviewing", "human_decision_signal", 2);
|
|
10301
|
+
}
|
|
10302
|
+
if (textMatches(text, [/\b(investigat(e|ing)|look into|find out|read|rg|grep|search)\b/i])) {
|
|
10303
|
+
addSignal(scores, "investigating", "investigation_language", 3);
|
|
10304
|
+
}
|
|
10305
|
+
if (actionCount(normalized, "read") >= 2 && actionCount(normalized, "write") === 0) {
|
|
10306
|
+
addSignal(scores, "investigating", "read_heavy_no_write_signal", 2);
|
|
10307
|
+
}
|
|
10308
|
+
if (events.length > 0 && files.length === 0) {
|
|
10309
|
+
addSignal(scores, "investigating", "activity_without_file_changes", 1);
|
|
10310
|
+
}
|
|
10311
|
+
const ranked = PROJECT_INTENT_DETECTION_INTENTS.map((intent2) => {
|
|
10312
|
+
const signals = compactSignals(scores.get(intent2) ?? []);
|
|
10313
|
+
return {
|
|
10314
|
+
intent: intent2,
|
|
10315
|
+
signals,
|
|
10316
|
+
score: signals.reduce((sum, signal) => sum + signal.weight, 0)
|
|
10317
|
+
};
|
|
10318
|
+
}).sort((left, right) => {
|
|
10319
|
+
if (right.score !== left.score) return right.score - left.score;
|
|
10320
|
+
return INTENT_PRIORITY[right.intent] - INTENT_PRIORITY[left.intent];
|
|
10321
|
+
});
|
|
10322
|
+
const best = ranked[0];
|
|
10323
|
+
const intent = best.score > 0 ? best.intent : "unknown";
|
|
10324
|
+
const signalDetails = best.score > 0 ? best.signals : [{ code: "insufficient_timeline_signals", intent: "unknown", weight: 0 }];
|
|
10325
|
+
const confidence = confidenceFor(best.score, signalDetails.length);
|
|
10326
|
+
const actionCounts = PROJECT_INTENT_DETECTION_ACTIONS.reduce((counts, action) => {
|
|
10327
|
+
const count = actionCount(normalized, action);
|
|
10328
|
+
if (count > 0) counts[action] = count;
|
|
10329
|
+
return counts;
|
|
10330
|
+
}, {});
|
|
10331
|
+
const suggestedWorkflowMode = suggestedModeFor(intent, confidence, files);
|
|
10332
|
+
const reasonCodes = uniqueStrings5([
|
|
10333
|
+
...signalDetails.map((signal) => signal.code),
|
|
10334
|
+
`intent_${intent}`,
|
|
10335
|
+
`confidence_${confidence}`
|
|
10336
|
+
]);
|
|
10337
|
+
return {
|
|
10338
|
+
version: INTENT_DETECTION_VERSION,
|
|
10339
|
+
intent,
|
|
10340
|
+
confidence,
|
|
10341
|
+
signals: signalDetails.map((signal) => signal.code),
|
|
10342
|
+
signalDetails,
|
|
10343
|
+
reasonCodes,
|
|
10344
|
+
evidence: {
|
|
10345
|
+
eventCount: events.length,
|
|
10346
|
+
fileCount: files.length,
|
|
10347
|
+
uniqueTouchedFiles: files,
|
|
10348
|
+
actionCounts
|
|
10349
|
+
},
|
|
10350
|
+
advisoryRouting: {
|
|
10351
|
+
hardRoutingAllowed: false,
|
|
10352
|
+
suggestedWorkflowMode,
|
|
10353
|
+
reasonCodes,
|
|
10354
|
+
caveats: [
|
|
10355
|
+
"Suggested workflow mode is advisory only.",
|
|
10356
|
+
"Explicit user choice, policy, and receipts are required before routing work."
|
|
10357
|
+
]
|
|
10358
|
+
},
|
|
10359
|
+
hardRoutingAllowed: false,
|
|
10360
|
+
caveats: [
|
|
10361
|
+
"Intent Detection V0 is advisory only.",
|
|
10362
|
+
"It must not trigger workers, merges, canonical memory writes, or blocking gates by itself.",
|
|
10363
|
+
"Confidence is heuristic and derived from local timeline evidence."
|
|
10364
|
+
]
|
|
10365
|
+
};
|
|
10366
|
+
}
|
|
10367
|
+
|
|
10142
10368
|
// src/commands/decision-requests.ts
|
|
10143
10369
|
var fs12 = __toESM(require("fs"));
|
|
10144
10370
|
var path11 = __toESM(require("path"));
|
|
@@ -10469,7 +10695,7 @@ function memoryEvidenceItem(value, options) {
|
|
|
10469
10695
|
summary: options.summary,
|
|
10470
10696
|
kind: options.kind,
|
|
10471
10697
|
status: options.status,
|
|
10472
|
-
files:
|
|
10698
|
+
files: uniqueStrings6(evidenceRefs),
|
|
10473
10699
|
metadata: compactObject({
|
|
10474
10700
|
source: options.source,
|
|
10475
10701
|
bucket: options.bucket,
|
|
@@ -10510,7 +10736,7 @@ function reviewQueueItems(result) {
|
|
|
10510
10736
|
action: "review_queue_item",
|
|
10511
10737
|
options: ["accept", "reject", "archive", "invalidate", "keep_pending"],
|
|
10512
10738
|
recommendation: reviewStatus === "approved" || status === "active" ? "keep_pending" : "accept",
|
|
10513
|
-
reasonCodes:
|
|
10739
|
+
reasonCodes: uniqueStrings6(["memory_review_queue", reason ?? "", status ?? ""]),
|
|
10514
10740
|
evidenceItem: memoryEvidenceItem(item, {
|
|
10515
10741
|
ref: `memory:${memoryId}`,
|
|
10516
10742
|
title: `Review memory ${memoryId}`,
|
|
@@ -10549,7 +10775,7 @@ function cleanCandidateItems(result) {
|
|
|
10549
10775
|
action: `${bucket}_candidate`,
|
|
10550
10776
|
options,
|
|
10551
10777
|
recommendation,
|
|
10552
|
-
reasonCodes:
|
|
10778
|
+
reasonCodes: uniqueStrings6(["memory_clean_candidates", bucket, reason]),
|
|
10553
10779
|
evidenceItem: memoryEvidenceItem(candidate, {
|
|
10554
10780
|
ref: `memory:${memoryId}`,
|
|
10555
10781
|
title: `${bucket.replace(/_/g, " ")} memory candidate ${memoryId}`,
|
|
@@ -10586,7 +10812,7 @@ function duplicateCandidateItems(result) {
|
|
|
10586
10812
|
action: "duplicate_candidate",
|
|
10587
10813
|
options: ["merge", "supersede", "keep", "inspect"],
|
|
10588
10814
|
recommendation: keepMemoryId ? "supersede" : "inspect",
|
|
10589
|
-
reasonCodes:
|
|
10815
|
+
reasonCodes: uniqueStrings6(["memory_duplicate_candidates", `group_${index + 1}`]),
|
|
10590
10816
|
evidenceItem: memoryEvidenceItem(candidate, {
|
|
10591
10817
|
ref: `memory:${memoryId}`,
|
|
10592
10818
|
title: `Duplicate memory candidate ${memoryId}`,
|
|
@@ -10645,6 +10871,9 @@ async function buildMemoryReviewConnector(options) {
|
|
|
10645
10871
|
items: [],
|
|
10646
10872
|
requests: [],
|
|
10647
10873
|
writes: [],
|
|
10874
|
+
emitted: { enabled: Boolean(options.emitDecisions), count: 0, requestIds: [] },
|
|
10875
|
+
emittedCount: 0,
|
|
10876
|
+
emittedRequestIds: [],
|
|
10648
10877
|
caveats: [
|
|
10649
10878
|
"Read-only connector: hosted memory tools are queried, but no memory is mutated.",
|
|
10650
10879
|
"Emitted decision requests must still be resolved explicitly; no timeout/default applies.",
|
|
@@ -10711,6 +10940,13 @@ async function buildMemoryReviewConnector(options) {
|
|
|
10711
10940
|
result.requests = result.items.map(buildMemoryReviewDecisionRequest);
|
|
10712
10941
|
if (options.emitDecisions) {
|
|
10713
10942
|
result.writes = result.requests.map((request) => writeDecisionRequest(request));
|
|
10943
|
+
result.emittedRequestIds = result.writes.map((write) => write.requestId);
|
|
10944
|
+
result.emittedCount = result.emittedRequestIds.length;
|
|
10945
|
+
result.emitted = {
|
|
10946
|
+
enabled: true,
|
|
10947
|
+
count: result.emittedCount,
|
|
10948
|
+
requestIds: result.emittedRequestIds
|
|
10949
|
+
};
|
|
10714
10950
|
}
|
|
10715
10951
|
return result;
|
|
10716
10952
|
}
|
|
@@ -10806,10 +11042,10 @@ function buildMemoryAuditSummary(audit) {
|
|
|
10806
11042
|
cleanupCandidateCounts,
|
|
10807
11043
|
...typeof compactDryRun.mutated === "boolean" ? { compactDryRunMutated: compactDryRun.mutated } : {},
|
|
10808
11044
|
...compactDryRunPlannedActions !== void 0 ? { compactDryRunPlannedActions } : {},
|
|
10809
|
-
recommendedActions:
|
|
11045
|
+
recommendedActions: uniqueStrings6(recommendedActions)
|
|
10810
11046
|
};
|
|
10811
11047
|
}
|
|
10812
|
-
function
|
|
11048
|
+
function uniqueStrings6(values) {
|
|
10813
11049
|
return Array.from(new Set(values));
|
|
10814
11050
|
}
|
|
10815
11051
|
function printMemoryAuditSummary(summary) {
|
|
@@ -11024,7 +11260,7 @@ async function memoryAuditCommand(options) {
|
|
|
11024
11260
|
var fs13 = __toESM(require("fs"));
|
|
11025
11261
|
var path12 = __toESM(require("path"));
|
|
11026
11262
|
var import_node_child_process2 = require("child_process");
|
|
11027
|
-
function
|
|
11263
|
+
function uniqueStrings7(values) {
|
|
11028
11264
|
return Array.from(new Set((values ?? []).map((value) => value.trim()).filter(Boolean)));
|
|
11029
11265
|
}
|
|
11030
11266
|
function slugify(value, fallback) {
|
|
@@ -11032,7 +11268,7 @@ function slugify(value, fallback) {
|
|
|
11032
11268
|
return slug2 || fallback;
|
|
11033
11269
|
}
|
|
11034
11270
|
function keywordHints(value) {
|
|
11035
|
-
return
|
|
11271
|
+
return uniqueStrings7(
|
|
11036
11272
|
value.split(/[^A-Za-z0-9_.:/-]+/).map((part) => part.trim()).filter((part) => part.length >= 4).slice(0, 8)
|
|
11037
11273
|
);
|
|
11038
11274
|
}
|
|
@@ -11078,17 +11314,17 @@ function expectedItems(section, values, files) {
|
|
|
11078
11314
|
}
|
|
11079
11315
|
function buildEvalCaseArtifact(options = {}) {
|
|
11080
11316
|
const rootDir = path12.resolve(options.dir ?? process.cwd());
|
|
11081
|
-
const files =
|
|
11082
|
-
const commandsRun =
|
|
11317
|
+
const files = uniqueStrings7(options.files);
|
|
11318
|
+
const commandsRun = uniqueStrings7(options.commandRun);
|
|
11083
11319
|
const summary = options.summary?.trim() || "Snipara companion local workflow evaluation";
|
|
11084
11320
|
const id = options.id?.trim() || slugify(summary, "snipara-companion-eval");
|
|
11085
11321
|
const expected = {};
|
|
11086
11322
|
const sectionInputs = {
|
|
11087
|
-
context:
|
|
11088
|
-
decisions:
|
|
11089
|
-
impact:
|
|
11090
|
-
verification:
|
|
11091
|
-
continuity:
|
|
11323
|
+
context: uniqueStrings7(options.context),
|
|
11324
|
+
decisions: uniqueStrings7(options.decision),
|
|
11325
|
+
impact: uniqueStrings7(options.impact),
|
|
11326
|
+
verification: uniqueStrings7(options.verification),
|
|
11327
|
+
continuity: uniqueStrings7(options.continuity)
|
|
11092
11328
|
};
|
|
11093
11329
|
for (const [section, values] of Object.entries(sectionInputs)) {
|
|
11094
11330
|
if (values.length > 0) {
|
|
@@ -12550,7 +12786,7 @@ var SESSION_SNAPSHOT_VERSION = "snipara.session_snapshot.v0";
|
|
|
12550
12786
|
var ACTIVITY_RELATIVE_DIR = path16.join(".snipara", "activity");
|
|
12551
12787
|
var ACTIVITY_TIMELINE_RELATIVE_PATH = path16.join(ACTIVITY_RELATIVE_DIR, "timeline.jsonl");
|
|
12552
12788
|
var SESSION_SNAPSHOT_RELATIVE_PATH = path16.join(ACTIVITY_RELATIVE_DIR, "session.json");
|
|
12553
|
-
function
|
|
12789
|
+
function uniqueStrings8(values) {
|
|
12554
12790
|
return Array.from(new Set(values.map((value) => value?.trim()).filter(Boolean)));
|
|
12555
12791
|
}
|
|
12556
12792
|
function stableJson(value) {
|
|
@@ -12623,8 +12859,8 @@ function appendActivityEvent(input) {
|
|
|
12623
12859
|
...input.phaseId ? { phaseId: input.phaseId } : {},
|
|
12624
12860
|
...input.actor ? { actor: input.actor } : {},
|
|
12625
12861
|
...input.outcome ? { outcome: input.outcome } : {},
|
|
12626
|
-
files:
|
|
12627
|
-
refs:
|
|
12862
|
+
files: uniqueStrings8(input.files ?? []),
|
|
12863
|
+
refs: uniqueStrings8(input.refs ?? []),
|
|
12628
12864
|
metadata: input.metadata ?? {}
|
|
12629
12865
|
};
|
|
12630
12866
|
const timelinePath = getActivityTimelinePath(cwd);
|
|
@@ -12705,6 +12941,37 @@ function teamSyncSnapshot(cwd) {
|
|
|
12705
12941
|
...latestHandoffAt ? { latestHandoffAt } : {}
|
|
12706
12942
|
};
|
|
12707
12943
|
}
|
|
12944
|
+
function deriveSessionSnapshotSummary(args) {
|
|
12945
|
+
const riskReasons = [];
|
|
12946
|
+
if (args.pendingDecisionCount > 0) {
|
|
12947
|
+
riskReasons.push(`${args.pendingDecisionCount} pending decision request(s)`);
|
|
12948
|
+
}
|
|
12949
|
+
if (args.producerLoop.unreviewedCount > 0) {
|
|
12950
|
+
riskReasons.push(`${args.producerLoop.unreviewedCount} unreviewed Producer Loop artifact(s)`);
|
|
12951
|
+
}
|
|
12952
|
+
if (args.teamSync.activeWorkCount > 0) {
|
|
12953
|
+
riskReasons.push(`${args.teamSync.activeWorkCount} active Team Sync work item(s)`);
|
|
12954
|
+
}
|
|
12955
|
+
if (args.workflow?.status === "blocked") {
|
|
12956
|
+
riskReasons.push("workflow is blocked");
|
|
12957
|
+
}
|
|
12958
|
+
const touchedFiles = uniqueStrings8(args.latestEvents.flatMap((event) => event.files)).slice(
|
|
12959
|
+
0,
|
|
12960
|
+
20
|
|
12961
|
+
);
|
|
12962
|
+
const latestActivity = args.latestEvents[0];
|
|
12963
|
+
const risk = riskReasons.length >= 2 ? "risk" : riskReasons.length === 1 ? "watch" : "none";
|
|
12964
|
+
const recommendedNextAction = args.workflow?.status === "completed" ? "Start the next managed workflow or export the timeline for handoff." : args.workflow?.currentPhaseId ? `Continue phase ${args.workflow.currentPhaseId} or commit it when verified.` : args.pendingDecisionCount > 0 ? "Resolve pending decision requests before applying follow-up actions." : "Review the latest activity and run the next verification command.";
|
|
12965
|
+
return {
|
|
12966
|
+
...latestActivity?.timestamp ? { latestActivityAt: latestActivity.timestamp } : {},
|
|
12967
|
+
...latestActivity?.title ? { latestActivityTitle: latestActivity.title } : {},
|
|
12968
|
+
...latestActivity?.kind ? { latestActivityKind: latestActivity.kind } : {},
|
|
12969
|
+
risk,
|
|
12970
|
+
riskReasons,
|
|
12971
|
+
touchedFiles,
|
|
12972
|
+
recommendedNextAction
|
|
12973
|
+
};
|
|
12974
|
+
}
|
|
12708
12975
|
function buildSessionSnapshot(options = {}) {
|
|
12709
12976
|
const startedAt = Date.now();
|
|
12710
12977
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -12712,6 +12979,9 @@ function buildSessionSnapshot(options = {}) {
|
|
|
12712
12979
|
const latestEvents = events.slice(0, options.limit && options.limit > 0 ? options.limit : 20);
|
|
12713
12980
|
const pendingDecisions = readJsonDir(path16.join(cwd, ".snipara", "decisions", "pending"));
|
|
12714
12981
|
const resolvedDecisions = readJsonDir(path16.join(cwd, ".snipara", "decisions", "resolved"));
|
|
12982
|
+
const workflow2 = workflowSnapshot(cwd);
|
|
12983
|
+
const producerLoop = producerLoopSummary(cwd);
|
|
12984
|
+
const teamSync2 = teamSyncSnapshot(cwd);
|
|
12715
12985
|
const snapshot = {
|
|
12716
12986
|
schemaVersion: SESSION_SNAPSHOT_VERSION,
|
|
12717
12987
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -12720,7 +12990,7 @@ function buildSessionSnapshot(options = {}) {
|
|
|
12720
12990
|
timelinePath: getActivityTimelinePath(cwd),
|
|
12721
12991
|
snapshotPath: getSessionSnapshotPath(cwd)
|
|
12722
12992
|
},
|
|
12723
|
-
workflow:
|
|
12993
|
+
workflow: workflow2,
|
|
12724
12994
|
activity: {
|
|
12725
12995
|
totalEvents: events.length,
|
|
12726
12996
|
...events[0]?.timestamp ? { latestEventAt: events[0].timestamp } : {},
|
|
@@ -12733,8 +13003,26 @@ function buildSessionSnapshot(options = {}) {
|
|
|
12733
13003
|
resolvedCount: resolvedDecisions.length,
|
|
12734
13004
|
recurringResolvedFingerprintCount: countDecisionFingerprintRepeats(resolvedDecisions)
|
|
12735
13005
|
},
|
|
12736
|
-
producerLoop
|
|
12737
|
-
teamSync:
|
|
13006
|
+
producerLoop,
|
|
13007
|
+
teamSync: teamSync2,
|
|
13008
|
+
summary: deriveSessionSnapshotSummary({
|
|
13009
|
+
workflow: workflow2,
|
|
13010
|
+
latestEvents,
|
|
13011
|
+
pendingDecisionCount: pendingDecisions.length,
|
|
13012
|
+
producerLoop,
|
|
13013
|
+
teamSync: teamSync2
|
|
13014
|
+
}),
|
|
13015
|
+
intentDetection: buildIntentDetectionFromTimeline(
|
|
13016
|
+
latestEvents.map((event) => ({
|
|
13017
|
+
kind: event.kind,
|
|
13018
|
+
source: event.source,
|
|
13019
|
+
title: event.title,
|
|
13020
|
+
summary: event.summary,
|
|
13021
|
+
outcome: event.outcome,
|
|
13022
|
+
files: event.files,
|
|
13023
|
+
metadata: event.metadata
|
|
13024
|
+
}))
|
|
13025
|
+
),
|
|
12738
13026
|
routing: {
|
|
12739
13027
|
hardRoutingAllowed: false,
|
|
12740
13028
|
reason: "Session Snapshot V0 is observational only; hard routing needs explicit policy and receipt gates."
|
|
@@ -12758,9 +13046,16 @@ function writeSessionSnapshot(options = {}) {
|
|
|
12758
13046
|
`, "utf8");
|
|
12759
13047
|
return snapshot;
|
|
12760
13048
|
}
|
|
13049
|
+
function readSessionSnapshot(cwd = process.cwd()) {
|
|
13050
|
+
const parsed = safeReadJson(getSessionSnapshotPath(cwd));
|
|
13051
|
+
if (parsed?.schemaVersion === SESSION_SNAPSHOT_VERSION && parsed.summary && parsed.intentDetection) {
|
|
13052
|
+
return parsed;
|
|
13053
|
+
}
|
|
13054
|
+
return null;
|
|
13055
|
+
}
|
|
12761
13056
|
|
|
12762
13057
|
// src/commands/journal.ts
|
|
12763
|
-
function
|
|
13058
|
+
function uniqueStrings9(values) {
|
|
12764
13059
|
if (!values) {
|
|
12765
13060
|
return [];
|
|
12766
13061
|
}
|
|
@@ -12788,7 +13083,7 @@ function buildJournalCheckpointEntry(payload) {
|
|
|
12788
13083
|
payload.actor ? `Actor: ${payload.actor}` : null,
|
|
12789
13084
|
payload.attention ? `Attention: ${payload.attention}` : null,
|
|
12790
13085
|
payload.next ? `Next: ${payload.next}` : null,
|
|
12791
|
-
|
|
13086
|
+
uniqueStrings9(payload.files).length > 0 ? `Files: ${uniqueStrings9(payload.files).join(", ")}` : null
|
|
12792
13087
|
].filter((line) => Boolean(line));
|
|
12793
13088
|
return {
|
|
12794
13089
|
text: lines.join("\n"),
|
|
@@ -12884,7 +13179,7 @@ function createRedactor(rootDir) {
|
|
|
12884
13179
|
patterns.add(item.name);
|
|
12885
13180
|
item.pattern.lastIndex = 0;
|
|
12886
13181
|
}
|
|
12887
|
-
const uniqueMatchedPatterns =
|
|
13182
|
+
const uniqueMatchedPatterns = uniqueStrings10(matchedPatterns);
|
|
12888
13183
|
if (uniqueMatchedPatterns.length > 0) {
|
|
12889
13184
|
redactedValueCount += 1;
|
|
12890
13185
|
}
|
|
@@ -12999,14 +13294,14 @@ function buildRepoState(input, options, rootDir, redactor) {
|
|
|
12999
13294
|
const inputRepo = inputRecord(input, "repoState", "repo_state", "repo");
|
|
13000
13295
|
const detected = detectGitState(rootDir);
|
|
13001
13296
|
const statusCounts = countGitStatus(detected.statusLines);
|
|
13002
|
-
const changedFiles =
|
|
13297
|
+
const changedFiles = uniqueStrings10([
|
|
13003
13298
|
...normalizeUnknownStringList(inputRepo.changedFiles),
|
|
13004
13299
|
...normalizeUnknownStringList(inputRepo.changed_files),
|
|
13005
13300
|
...normalizeUnknownStringList(input.changedFiles),
|
|
13006
13301
|
...normalizeUnknownStringList(input.changed_files),
|
|
13007
13302
|
...options.changedFiles ?? []
|
|
13008
13303
|
]).map((item) => redactor.redact(item).value);
|
|
13009
|
-
const recentFiles =
|
|
13304
|
+
const recentFiles = uniqueStrings10([
|
|
13010
13305
|
...normalizeUnknownStringList(inputRepo.recentFiles),
|
|
13011
13306
|
...normalizeUnknownStringList(inputRepo.recent_files),
|
|
13012
13307
|
...normalizeUnknownStringList(input.recentFiles),
|
|
@@ -13074,18 +13369,18 @@ function normalizeEvidenceItem(value, section, index, redactor) {
|
|
|
13074
13369
|
"command",
|
|
13075
13370
|
"check"
|
|
13076
13371
|
]) ?? fallbackSummary(value, section, index);
|
|
13077
|
-
const reasonCodes =
|
|
13372
|
+
const reasonCodes = uniqueStrings10([
|
|
13078
13373
|
`section_${section}`,
|
|
13079
13374
|
...normalizeUnknownStringList(value.reasonCodes),
|
|
13080
13375
|
...normalizeUnknownStringList(value.reason_codes)
|
|
13081
13376
|
]).map((item) => redactor.redact(item).value);
|
|
13082
|
-
const files =
|
|
13377
|
+
const files = uniqueStrings10([
|
|
13083
13378
|
...normalizeUnknownStringList(value.files),
|
|
13084
13379
|
...normalizeUnknownStringList(value.changedFiles),
|
|
13085
13380
|
...normalizeUnknownStringList(value.changed_files),
|
|
13086
13381
|
...normalizeUnknownStringList(value.file)
|
|
13087
13382
|
]).slice(0, MAX_LIST_ITEMS).map((item) => redactor.redact(item).value);
|
|
13088
|
-
const commands =
|
|
13383
|
+
const commands = uniqueStrings10([
|
|
13089
13384
|
...normalizeUnknownStringList(value.commands),
|
|
13090
13385
|
...normalizeUnknownStringList(value.command),
|
|
13091
13386
|
...normalizeUnknownStringList(value.checks),
|
|
@@ -13109,7 +13404,7 @@ function normalizeEvidenceItem(value, section, index, redactor) {
|
|
|
13109
13404
|
});
|
|
13110
13405
|
}
|
|
13111
13406
|
function collectReasonCodes(input, cliValues, items, redactor) {
|
|
13112
|
-
return
|
|
13407
|
+
return uniqueStrings10([
|
|
13113
13408
|
"coding_intelligence_ledger_v0",
|
|
13114
13409
|
...normalizeUnknownStringList(input.reasonCodes),
|
|
13115
13410
|
...normalizeUnknownStringList(input.reason_codes),
|
|
@@ -13140,13 +13435,13 @@ function buildCalibrationMetadata(input, cliValues, redactor) {
|
|
|
13140
13435
|
"calibration",
|
|
13141
13436
|
"calibration_metadata"
|
|
13142
13437
|
);
|
|
13143
|
-
const notes =
|
|
13438
|
+
const notes = uniqueStrings10([
|
|
13144
13439
|
...normalizeUnknownStringList(calibration.notes),
|
|
13145
13440
|
...normalizeUnknownStringList(calibration.note),
|
|
13146
13441
|
...normalizeUnknownStringList(input.calibrationNotes),
|
|
13147
13442
|
...cliValues ?? []
|
|
13148
13443
|
]).slice(0, MAX_LIST_ITEMS).map((item) => redactor.redact(item).value);
|
|
13149
|
-
const caveats =
|
|
13444
|
+
const caveats = uniqueStrings10([
|
|
13150
13445
|
...normalizeUnknownStringList(calibration.caveats),
|
|
13151
13446
|
...normalizeUnknownStringList(calibration.caveat),
|
|
13152
13447
|
...normalizeUnknownStringList(input.calibrationCaveats)
|
|
@@ -13343,7 +13638,7 @@ function validIso(value) {
|
|
|
13343
13638
|
const date = new Date(value);
|
|
13344
13639
|
return Number.isNaN(date.getTime()) ? void 0 : date.toISOString();
|
|
13345
13640
|
}
|
|
13346
|
-
function
|
|
13641
|
+
function uniqueStrings10(values) {
|
|
13347
13642
|
return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
|
|
13348
13643
|
}
|
|
13349
13644
|
function compactWhitespace(value) {
|
|
@@ -15254,16 +15549,16 @@ function upsertLocalAdaptiveRoutingPolicy(workerRole) {
|
|
|
15254
15549
|
mode: stringValue5(existing.mode) ?? "catalog",
|
|
15255
15550
|
plannerRetainsReasoning: existing.plannerRetainsReasoning !== false,
|
|
15256
15551
|
preferLocalWorkers: true,
|
|
15257
|
-
allowedEndpointTypes:
|
|
15552
|
+
allowedEndpointTypes: uniqueStrings11([
|
|
15258
15553
|
...normalizeStringList2(existing.allowedEndpointTypes),
|
|
15259
15554
|
"local",
|
|
15260
15555
|
"cloud"
|
|
15261
15556
|
]),
|
|
15262
|
-
preferredEndpointTypes:
|
|
15557
|
+
preferredEndpointTypes: uniqueStrings11([
|
|
15263
15558
|
"local",
|
|
15264
15559
|
...normalizeStringList2(existing.preferredEndpointTypes)
|
|
15265
15560
|
]),
|
|
15266
|
-
allowedWorkerClasses:
|
|
15561
|
+
allowedWorkerClasses: uniqueStrings11([
|
|
15267
15562
|
...normalizeStringList2(existing.allowedWorkerClasses),
|
|
15268
15563
|
workerRole,
|
|
15269
15564
|
"documentation",
|
|
@@ -15323,9 +15618,9 @@ function defaultCapabilitiesForWorker(workerRole) {
|
|
|
15323
15618
|
}
|
|
15324
15619
|
function normalizeStringList2(value) {
|
|
15325
15620
|
const values = Array.isArray(value) ? value : value === void 0 ? [] : [value];
|
|
15326
|
-
return
|
|
15621
|
+
return uniqueStrings11(values.map(stringValue5).filter((item) => Boolean(item)));
|
|
15327
15622
|
}
|
|
15328
|
-
function
|
|
15623
|
+
function uniqueStrings11(values) {
|
|
15329
15624
|
return Array.from(new Set(values));
|
|
15330
15625
|
}
|
|
15331
15626
|
function stringValue5(value) {
|
|
@@ -15483,7 +15778,7 @@ function numberValue3(value) {
|
|
|
15483
15778
|
const parsed = Number(text);
|
|
15484
15779
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
15485
15780
|
}
|
|
15486
|
-
function
|
|
15781
|
+
function uniqueStrings12(values) {
|
|
15487
15782
|
return Array.from(new Set(values.filter((value) => value.trim().length > 0)));
|
|
15488
15783
|
}
|
|
15489
15784
|
function normalizeEnum(value) {
|
|
@@ -16566,7 +16861,7 @@ function buildProducerLoopArtifact(options) {
|
|
|
16566
16861
|
workflowId ?? "unmanaged",
|
|
16567
16862
|
options.phase?.id ? `phase:${options.phase.id}` : "final"
|
|
16568
16863
|
].join(":");
|
|
16569
|
-
const reasonCodes =
|
|
16864
|
+
const reasonCodes = uniqueStrings12([
|
|
16570
16865
|
"producer_loop_v0",
|
|
16571
16866
|
options.kind,
|
|
16572
16867
|
`outcome_${options.outcome}`,
|
|
@@ -16758,8 +17053,8 @@ function summarizeProducerLoopArtifactFile(filePath, cwd) {
|
|
|
16758
17053
|
relativePath: relativePath2,
|
|
16759
17054
|
artifactHash: `sha256:${hashContent(content)}`,
|
|
16760
17055
|
ledgerHash: stringValue6(parsed.ledgerHash),
|
|
16761
|
-
reasonCodes:
|
|
16762
|
-
files:
|
|
17056
|
+
reasonCodes: uniqueStrings12(stringArrayValue(ledger?.reasonCodes)),
|
|
17057
|
+
files: uniqueStrings12(stringArrayValue(producer.files)),
|
|
16763
17058
|
calibrationStatus: stringValue6(calibration?.status),
|
|
16764
17059
|
reviewStatus,
|
|
16765
17060
|
reviewOutcome: stringValue6(review?.outcome),
|
|
@@ -16806,10 +17101,10 @@ function buildProducerLoopReport(options = {}) {
|
|
|
16806
17101
|
(left, right) => left.generatedAt === right.generatedAt ? left.relativePath.localeCompare(right.relativePath) : left.generatedAt.localeCompare(right.generatedAt)
|
|
16807
17102
|
);
|
|
16808
17103
|
const invalidArtifacts = summaries.map((entry) => entry.invalid).filter((entry) => Boolean(entry));
|
|
16809
|
-
const producerKinds =
|
|
17104
|
+
const producerKinds = uniqueStrings12(artifacts.map((artifact) => artifact.producerKind)).filter(
|
|
16810
17105
|
(kind) => isProducerLoopProducerKind(kind)
|
|
16811
17106
|
);
|
|
16812
|
-
const workflowIds =
|
|
17107
|
+
const workflowIds = uniqueStrings12(
|
|
16813
17108
|
artifacts.map((artifact) => artifact.workflowId).filter((id) => Boolean(id))
|
|
16814
17109
|
);
|
|
16815
17110
|
const reasonCodeCounts = countStringOccurrences(
|
|
@@ -16960,7 +17255,7 @@ function readProducerLoopArtifactForReview(filePath) {
|
|
|
16960
17255
|
return parsed;
|
|
16961
17256
|
}
|
|
16962
17257
|
function applyProducerLoopArtifactReview(artifact, options) {
|
|
16963
|
-
const reviewNotes =
|
|
17258
|
+
const reviewNotes = uniqueStrings12(options.notes ?? []);
|
|
16964
17259
|
const reviewNote = options.status === "sample_rejected" ? "Sample rejected by local operator review." : "Sample reviewed by local operator.";
|
|
16965
17260
|
const existingCalibration = artifact.calibration ?? {
|
|
16966
17261
|
status: "sample_unreviewed",
|
|
@@ -16975,7 +17270,7 @@ function applyProducerLoopArtifactReview(artifact, options) {
|
|
|
16975
17270
|
status: options.status,
|
|
16976
17271
|
sampleSize: 1,
|
|
16977
17272
|
hardGateReady: false,
|
|
16978
|
-
notes:
|
|
17273
|
+
notes: uniqueStrings12([
|
|
16979
17274
|
...stringArrayValue(existingCalibration.notes),
|
|
16980
17275
|
reviewNote,
|
|
16981
17276
|
...reviewNotes.map((note) => `Review note: ${note}`)
|
|
@@ -17185,7 +17480,7 @@ function applyDecisionRequestLocally(options) {
|
|
|
17185
17480
|
reject: isRejectChoice(options.choice),
|
|
17186
17481
|
outcome: isRejectChoice(options.choice) ? "false_positive" : "useful",
|
|
17187
17482
|
reviewer: options.reviewer,
|
|
17188
|
-
notes:
|
|
17483
|
+
notes: uniqueStrings12([
|
|
17189
17484
|
`decision_request:${request.requestId}`,
|
|
17190
17485
|
...options.note ? [options.note] : []
|
|
17191
17486
|
])
|
|
@@ -17199,12 +17494,17 @@ function applyDecisionRequestLocally(options) {
|
|
|
17199
17494
|
function recurringPolicySuggestionKey(record) {
|
|
17200
17495
|
return stableDecisionJsonStringify({
|
|
17201
17496
|
producer: record.request.producer.kind,
|
|
17202
|
-
decision: record.request.decision,
|
|
17203
17497
|
choice: record.response.choice,
|
|
17204
|
-
|
|
17205
|
-
reasonCodes: record.request.evidence.reasonCodes
|
|
17498
|
+
targetCategory: recurringPolicySuggestionTargetCategory(record.request)
|
|
17206
17499
|
});
|
|
17207
17500
|
}
|
|
17501
|
+
function recurringPolicySuggestionTargetCategory(request) {
|
|
17502
|
+
const evidenceCategories = request.evidence.items?.map((item) => {
|
|
17503
|
+
const metadata = isRecord8(item.metadata) ? item.metadata : void 0;
|
|
17504
|
+
return stringValue6(metadata?.category) ?? stringValue6(metadata?.type) ?? item.kind;
|
|
17505
|
+
}).filter((value) => Boolean(value)) ?? [];
|
|
17506
|
+
return uniqueStrings12(evidenceCategories).sort().join("|") || request.evidence.applyPath || request.decision;
|
|
17507
|
+
}
|
|
17208
17508
|
function buildRecurringDecisionPolicySuggestionRequest(resolvedRecords) {
|
|
17209
17509
|
const grouped = /* @__PURE__ */ new Map();
|
|
17210
17510
|
for (const record of resolvedRecords) {
|
|
@@ -17221,6 +17521,7 @@ function buildRecurringDecisionPolicySuggestionRequest(resolvedRecords) {
|
|
|
17221
17521
|
const refs = repeated.map((record) => record.request.requestId);
|
|
17222
17522
|
const note = compactWhitespace2(latest.response.note ?? "");
|
|
17223
17523
|
const policyTitle = note ? `Never ask twice for: ${note}` : `Never ask twice for ${latest.request.decision} -> ${latest.response.choice}`;
|
|
17524
|
+
const targetCategory = recurringPolicySuggestionTargetCategory(latest.request);
|
|
17224
17525
|
return buildDecisionRequest({
|
|
17225
17526
|
producer: {
|
|
17226
17527
|
kind: "policy_suggestion",
|
|
@@ -17240,12 +17541,12 @@ function buildRecurringDecisionPolicySuggestionRequest(resolvedRecords) {
|
|
|
17240
17541
|
status: record.response.choice,
|
|
17241
17542
|
files: record.request.evidence.files?.slice(0, 12)
|
|
17242
17543
|
})),
|
|
17243
|
-
reasonCodes:
|
|
17544
|
+
reasonCodes: uniqueStrings12([
|
|
17244
17545
|
"recurring_decision_receipts",
|
|
17245
17546
|
"never_ask_twice_candidate",
|
|
17246
17547
|
...latest.request.evidence.reasonCodes
|
|
17247
17548
|
]),
|
|
17248
|
-
files:
|
|
17549
|
+
files: uniqueStrings12(repeated.flatMap((record) => record.request.evidence.files ?? [])),
|
|
17249
17550
|
applyPath: "manual_context_review",
|
|
17250
17551
|
applyCommand: "Review the suggested rule and add it to the appropriate project policy or AGENTS.md section manually."
|
|
17251
17552
|
},
|
|
@@ -17255,10 +17556,9 @@ function buildRecurringDecisionPolicySuggestionRequest(resolvedRecords) {
|
|
|
17255
17556
|
fingerprintParts: [
|
|
17256
17557
|
"recurring_decision_policy_suggestion",
|
|
17257
17558
|
repeated.length,
|
|
17258
|
-
latest.request.
|
|
17559
|
+
latest.request.producer.kind,
|
|
17259
17560
|
latest.response.choice,
|
|
17260
|
-
|
|
17261
|
-
latest.request.evidence.reasonCodes
|
|
17561
|
+
targetCategory
|
|
17262
17562
|
]
|
|
17263
17563
|
});
|
|
17264
17564
|
}
|
|
@@ -17388,12 +17688,12 @@ function buildProducerTriageRequest(report) {
|
|
|
17388
17688
|
summary: `${candidates.length} unreviewed Producer Loop samples; ${report.invalidArtifacts.length} invalid artifacts; hardGateReady remains false.`,
|
|
17389
17689
|
refs,
|
|
17390
17690
|
items,
|
|
17391
|
-
reasonCodes:
|
|
17691
|
+
reasonCodes: uniqueStrings12([
|
|
17392
17692
|
"triage_rules_v0",
|
|
17393
17693
|
"producer_loop_report_valid",
|
|
17394
17694
|
...report.invalidArtifacts.length === 0 ? ["no_invalid_artifacts"] : ["invalid_artifacts_present"]
|
|
17395
17695
|
]),
|
|
17396
|
-
files:
|
|
17696
|
+
files: uniqueStrings12(candidates.flatMap((artifact) => artifact.files)),
|
|
17397
17697
|
applyPath: "workflow producer-review",
|
|
17398
17698
|
applyCommand: "snipara-companion workflow decide <request-id> --choose accept_all --reviewer <name>"
|
|
17399
17699
|
},
|
|
@@ -17454,7 +17754,7 @@ async function workflowDecisionProducerMemoryCommand(options) {
|
|
|
17454
17754
|
const request2 = buildMemoryReviewDecisionRequest({
|
|
17455
17755
|
...reviewItem,
|
|
17456
17756
|
action,
|
|
17457
|
-
recommendation: options.reviewerHint ??
|
|
17757
|
+
recommendation: options.reviewerHint ?? action,
|
|
17458
17758
|
options: action === "verify" ? ["verify", "keep_pending", "invalidate"] : action === "invalidate" ? ["invalidate", "keep", "inspect"] : reviewItem.options.includes(action) ? reviewItem.options : [action, ...reviewItem.options.filter((option) => option !== action)]
|
|
17459
17759
|
});
|
|
17460
17760
|
const write2 = writeDecisionRequest(request2);
|
|
@@ -19114,8 +19414,8 @@ async function enrichAdaptiveRoutingWithHostedCatalog(client, routing) {
|
|
|
19114
19414
|
runtimeCatalog: catalog,
|
|
19115
19415
|
routingCard: {
|
|
19116
19416
|
...routing.routingCard,
|
|
19117
|
-
reasons:
|
|
19118
|
-
warnings:
|
|
19417
|
+
reasons: uniqueStrings12(reasons),
|
|
19418
|
+
warnings: uniqueStrings12([...routing.routingCard.warnings, ...gatewayWarnings])
|
|
19119
19419
|
}
|
|
19120
19420
|
};
|
|
19121
19421
|
} catch (error) {
|
|
@@ -19132,7 +19432,7 @@ async function enrichAdaptiveRoutingWithHostedCatalog(client, routing) {
|
|
|
19132
19432
|
},
|
|
19133
19433
|
routingCard: {
|
|
19134
19434
|
...routing.routingCard,
|
|
19135
|
-
warnings:
|
|
19435
|
+
warnings: uniqueStrings12([...routing.routingCard.warnings, warning])
|
|
19136
19436
|
}
|
|
19137
19437
|
};
|
|
19138
19438
|
}
|
|
@@ -19298,7 +19598,7 @@ function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = proc
|
|
|
19298
19598
|
const approvalRequired = booleanValue3(
|
|
19299
19599
|
isRecord8(resolution?.policyDecision) ? resolution.policyDecision.approvalRequired : void 0
|
|
19300
19600
|
);
|
|
19301
|
-
const gatewayWarnings =
|
|
19601
|
+
const gatewayWarnings = uniqueStrings12([
|
|
19302
19602
|
...resolutionWarnings,
|
|
19303
19603
|
...selectedCandidate ? [] : ["Local orchestrator did not select a worker candidate and will fail closed."]
|
|
19304
19604
|
]);
|
|
@@ -19319,7 +19619,7 @@ function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = proc
|
|
|
19319
19619
|
...routing.routingCard,
|
|
19320
19620
|
...selectedCandidate?.workerClass ? { recommendedWorkerClass: selectedCandidate.workerClass } : {},
|
|
19321
19621
|
...approvalRequired !== void 0 ? { humanApprovalRequired: approvalRequired } : {},
|
|
19322
|
-
reasons:
|
|
19622
|
+
reasons: uniqueStrings12([
|
|
19323
19623
|
...routing.routingCard.reasons,
|
|
19324
19624
|
...resolutionReasons,
|
|
19325
19625
|
...selectedCandidate ? [
|
|
@@ -19328,7 +19628,7 @@ function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = proc
|
|
|
19328
19628
|
...stringValue6(selectedEndpoint?.model) ? [`selected local model ${String(selectedEndpoint?.model)}`] : []
|
|
19329
19629
|
] : ["local orchestrator could not resolve a concrete worker candidate"]
|
|
19330
19630
|
]),
|
|
19331
|
-
warnings:
|
|
19631
|
+
warnings: uniqueStrings12([...routing.routingCard.warnings, ...gatewayWarnings])
|
|
19332
19632
|
}
|
|
19333
19633
|
};
|
|
19334
19634
|
} catch (error) {
|
|
@@ -19345,7 +19645,7 @@ function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = proc
|
|
|
19345
19645
|
},
|
|
19346
19646
|
routingCard: {
|
|
19347
19647
|
...routing.routingCard,
|
|
19348
|
-
warnings:
|
|
19648
|
+
warnings: uniqueStrings12([...routing.routingCard.warnings, warning])
|
|
19349
19649
|
}
|
|
19350
19650
|
};
|
|
19351
19651
|
}
|
|
@@ -20215,7 +20515,7 @@ function scanOnboardFolder(options) {
|
|
|
20215
20515
|
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
20216
20516
|
return files;
|
|
20217
20517
|
}
|
|
20218
|
-
function
|
|
20518
|
+
function addSignal2(signals, signal) {
|
|
20219
20519
|
if (!signals.includes(signal)) {
|
|
20220
20520
|
signals.push(signal);
|
|
20221
20521
|
}
|
|
@@ -20229,7 +20529,7 @@ function classifyOnboardFolder(rootDir, files, overrideMode = "auto") {
|
|
|
20229
20529
|
let supportedPlainDocuments = 0;
|
|
20230
20530
|
if (fs21.existsSync(path20.join(rootDir, ".git"))) {
|
|
20231
20531
|
codeScore += 4;
|
|
20232
|
-
|
|
20532
|
+
addSignal2(codeSignals, ".git directory");
|
|
20233
20533
|
}
|
|
20234
20534
|
for (const file of files) {
|
|
20235
20535
|
const base = path20.basename(file.path);
|
|
@@ -20237,22 +20537,22 @@ function classifyOnboardFolder(rootDir, files, overrideMode = "auto") {
|
|
|
20237
20537
|
const firstSegment = firstPathSegment(file.path);
|
|
20238
20538
|
if (CODE_MARKER_FILES.has(base)) {
|
|
20239
20539
|
codeScore += 3;
|
|
20240
|
-
|
|
20540
|
+
addSignal2(codeSignals, base);
|
|
20241
20541
|
}
|
|
20242
20542
|
if (CODE_MARKER_DIRS.has(firstSegment)) {
|
|
20243
20543
|
codeScore += 1.5;
|
|
20244
|
-
|
|
20544
|
+
addSignal2(codeSignals, `${firstSegment}/ directory`);
|
|
20245
20545
|
}
|
|
20246
20546
|
if (CODE_SOURCE_EXTENSIONS.has(ext)) {
|
|
20247
20547
|
codeSourceFiles += 1;
|
|
20248
20548
|
}
|
|
20249
20549
|
if ([".docx", ".pdf", ".pptx", ".vsdx", ".xlsx", ".xls", ".csv", ".tsv"].includes(ext)) {
|
|
20250
20550
|
businessScore += 2;
|
|
20251
|
-
|
|
20551
|
+
addSignal2(businessSignals, `${ext} documents`);
|
|
20252
20552
|
}
|
|
20253
20553
|
if (hasBusinessKeyword(file.path)) {
|
|
20254
20554
|
businessScore += 2;
|
|
20255
|
-
|
|
20555
|
+
addSignal2(businessSignals, `business keyword in ${file.path}`);
|
|
20256
20556
|
}
|
|
20257
20557
|
if (file.supported && [".md", ".markdown", ".mdx", ".txt", ".rst", ".adoc"].includes(ext)) {
|
|
20258
20558
|
supportedPlainDocuments += 1;
|
|
@@ -20261,10 +20561,10 @@ function classifyOnboardFolder(rootDir, files, overrideMode = "auto") {
|
|
|
20261
20561
|
codeScore += Math.min(5, codeSourceFiles * 0.25);
|
|
20262
20562
|
businessScore += Math.min(3, supportedPlainDocuments * 0.35);
|
|
20263
20563
|
if (codeSourceFiles > 0) {
|
|
20264
|
-
|
|
20564
|
+
addSignal2(codeSignals, `${codeSourceFiles} source-looking files`);
|
|
20265
20565
|
}
|
|
20266
20566
|
if (supportedPlainDocuments > 0) {
|
|
20267
|
-
|
|
20567
|
+
addSignal2(businessSignals, `${supportedPlainDocuments} supported text documents`);
|
|
20268
20568
|
}
|
|
20269
20569
|
const codeStrong = codeScore >= 3;
|
|
20270
20570
|
const businessStrong = businessScore >= 2.5 || !codeStrong && files.some((file) => file.supported);
|
|
@@ -21148,8 +21448,8 @@ function buildWorkflowAdaptiveRouting(options, policy = null, intentWarnings = [
|
|
|
21148
21448
|
...routing,
|
|
21149
21449
|
routingCard: {
|
|
21150
21450
|
...routing.routingCard,
|
|
21151
|
-
reasons:
|
|
21152
|
-
warnings:
|
|
21451
|
+
reasons: uniqueStrings12([...routing.routingCard.reasons, ...policyReasons]),
|
|
21452
|
+
warnings: uniqueStrings12([...routing.routingCard.warnings, ...policyWarnings])
|
|
21153
21453
|
}
|
|
21154
21454
|
};
|
|
21155
21455
|
}
|
|
@@ -21165,7 +21465,7 @@ function normalizeAdaptiveRoutingMode(value) {
|
|
|
21165
21465
|
return normalized === "off" || normalized === "recommend" || normalized === "catalog" ? normalized : null;
|
|
21166
21466
|
}
|
|
21167
21467
|
function normalizeAdaptiveWorkerClasses(values) {
|
|
21168
|
-
return
|
|
21468
|
+
return uniqueStrings12((values ?? []).map(canonicalAdaptiveWorkerClass)).filter(
|
|
21169
21469
|
(value) => ["documentation", "tests", "review", "coding"].includes(value)
|
|
21170
21470
|
);
|
|
21171
21471
|
}
|
|
@@ -21601,12 +21901,80 @@ function printAgenticTimeline(timeline) {
|
|
|
21601
21901
|
}
|
|
21602
21902
|
console.log("");
|
|
21603
21903
|
}
|
|
21904
|
+
function escapeRegExp5(value) {
|
|
21905
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21906
|
+
}
|
|
21907
|
+
function localWorkspacePathAliases() {
|
|
21908
|
+
const cwd = process.cwd();
|
|
21909
|
+
const aliases = /* @__PURE__ */ new Set([cwd]);
|
|
21910
|
+
try {
|
|
21911
|
+
aliases.add(fs21.realpathSync(cwd));
|
|
21912
|
+
} catch {
|
|
21913
|
+
}
|
|
21914
|
+
for (const alias of [...aliases]) {
|
|
21915
|
+
if (alias.startsWith("/private/var/")) aliases.add(alias.replace(/^\/private/, ""));
|
|
21916
|
+
else if (alias.startsWith("/var/")) aliases.add(`/private${alias}`);
|
|
21917
|
+
}
|
|
21918
|
+
return [...aliases].filter(Boolean).sort((left, right) => right.length - left.length);
|
|
21919
|
+
}
|
|
21920
|
+
function redactTimelineText(value, maxLength = 180) {
|
|
21921
|
+
let text = toPreview(value, maxLength);
|
|
21922
|
+
for (const alias of localWorkspacePathAliases()) {
|
|
21923
|
+
text = text.replace(new RegExp(escapeRegExp5(alias), "g"), "[workspace]");
|
|
21924
|
+
}
|
|
21925
|
+
return text.replace(/\/Users\/[^/\s)]+/g, "[home]").replace(/\.snipara\/[^\s,)]+/g, "[local-state]").replace(/\b(api[_-]?key|token|secret|password)=\S+/gi, "$1=[redacted]");
|
|
21926
|
+
}
|
|
21927
|
+
function redactTimelineFile(file) {
|
|
21928
|
+
const workspaceAlias = localWorkspacePathAliases().find(
|
|
21929
|
+
(alias) => path20.isAbsolute(file) && file.startsWith(alias)
|
|
21930
|
+
);
|
|
21931
|
+
const relative8 = workspaceAlias ? path20.relative(workspaceAlias, file) : file;
|
|
21932
|
+
if (relative8.startsWith(".snipara/") || relative8 === ".snipara") {
|
|
21933
|
+
return "[local-state]";
|
|
21934
|
+
}
|
|
21935
|
+
return redactTimelineText(relative8, 120);
|
|
21936
|
+
}
|
|
21937
|
+
function formatAgenticTimelineMarkdown(timeline) {
|
|
21938
|
+
const lines = [
|
|
21939
|
+
"# Workflow Timeline",
|
|
21940
|
+
"",
|
|
21941
|
+
`Generated: ${timeline.generatedAt}`,
|
|
21942
|
+
`Events: ${timeline.events.length}`,
|
|
21943
|
+
"",
|
|
21944
|
+
"> Redacted local export. Absolute paths, local state paths, and secret-like fragments are removed.",
|
|
21945
|
+
""
|
|
21946
|
+
];
|
|
21947
|
+
for (const event of timeline.events) {
|
|
21948
|
+
lines.push(`## ${redactTimelineText(event.time, 40)} - ${redactTimelineText(event.kind, 80)}`);
|
|
21949
|
+
lines.push("");
|
|
21950
|
+
lines.push(`- Source: ${redactTimelineText(event.source, 80)}`);
|
|
21951
|
+
lines.push(`- Title: ${redactTimelineText(event.title, 180)}`);
|
|
21952
|
+
if (event.detail) {
|
|
21953
|
+
lines.push(`- Summary: ${redactTimelineText(event.detail, 220)}`);
|
|
21954
|
+
}
|
|
21955
|
+
if (event.files?.length) {
|
|
21956
|
+
lines.push(
|
|
21957
|
+
`- Files: ${event.files.slice(0, 6).map(redactTimelineFile).join(", ")}${event.files.length > 6 ? ` (+${event.files.length - 6})` : ""}`
|
|
21958
|
+
);
|
|
21959
|
+
}
|
|
21960
|
+
lines.push("");
|
|
21961
|
+
}
|
|
21962
|
+
return `${lines.join("\n").trimEnd()}
|
|
21963
|
+
`;
|
|
21964
|
+
}
|
|
21604
21965
|
async function workflowTimelineCommand(options) {
|
|
21605
21966
|
const timeline = buildAgenticTimeline({ limit: options.limit });
|
|
21606
21967
|
if (options.json) {
|
|
21607
21968
|
printJson2(timeline);
|
|
21608
21969
|
return;
|
|
21609
21970
|
}
|
|
21971
|
+
if (options.exportFormat) {
|
|
21972
|
+
if (options.exportFormat !== "md") {
|
|
21973
|
+
throw new Error("Unsupported workflow timeline export format. Use --export md.");
|
|
21974
|
+
}
|
|
21975
|
+
process.stdout.write(formatAgenticTimelineMarkdown(timeline));
|
|
21976
|
+
return;
|
|
21977
|
+
}
|
|
21610
21978
|
printAgenticTimeline(timeline);
|
|
21611
21979
|
}
|
|
21612
21980
|
async function workflowSessionCommand(options) {
|
|
@@ -21638,6 +22006,17 @@ async function workflowSessionCommand(options) {
|
|
|
21638
22006
|
printKeyValue2("Resolved decisions:", snapshot.decisions.resolvedCount);
|
|
21639
22007
|
printKeyValue2("Producer artifacts:", snapshot.producerLoop.artifactCount);
|
|
21640
22008
|
printKeyValue2("Team Sync active work:", snapshot.teamSync.activeWorkCount);
|
|
22009
|
+
printKeyValue2(
|
|
22010
|
+
"Intent:",
|
|
22011
|
+
`${snapshot.intentDetection.intent} (${snapshot.intentDetection.confidence})`
|
|
22012
|
+
);
|
|
22013
|
+
printKeyValue2(
|
|
22014
|
+
"Suggested mode:",
|
|
22015
|
+
`${snapshot.intentDetection.advisoryRouting.suggestedWorkflowMode} (advisory)`
|
|
22016
|
+
);
|
|
22017
|
+
if (snapshot.intentDetection.signals.length > 0) {
|
|
22018
|
+
console.log(`Intent signals: ${snapshot.intentDetection.signals.slice(0, 5).join(", ")}`);
|
|
22019
|
+
}
|
|
21641
22020
|
printKeyValue2("Hard routing allowed:", String(snapshot.routing.hardRoutingAllowed));
|
|
21642
22021
|
console.log(`Reason: ${snapshot.routing.reason}`);
|
|
21643
22022
|
printKeyValue2("Snapshot:", snapshot.source.snapshotPath);
|
|
@@ -21864,10 +22243,12 @@ async function workflowResumeCommand(options) {
|
|
|
21864
22243
|
});
|
|
21865
22244
|
const teamSyncResume = await loadWorkflowTeamSyncResume(state);
|
|
21866
22245
|
const runtimeResume = await loadWorkflowRuntimeResumePlan(state);
|
|
22246
|
+
const localSessionSnapshot = writeSessionSnapshot({ limit: 8 });
|
|
21867
22247
|
if (options.json) {
|
|
21868
22248
|
printJson2({
|
|
21869
22249
|
workflow: state,
|
|
21870
22250
|
pending_decision_count: safeDecisionPendingCount(),
|
|
22251
|
+
local_session_snapshot: localSessionSnapshot,
|
|
21871
22252
|
session_bootstrap: bootstrap,
|
|
21872
22253
|
session_bootstrap_quality: bootstrapQuality,
|
|
21873
22254
|
team_sync_resume: teamSyncResume?.data ?? null,
|
|
@@ -21887,6 +22268,7 @@ async function workflowResumeCommand(options) {
|
|
|
21887
22268
|
includeSessionContext: resolvedContextTokens > 0
|
|
21888
22269
|
});
|
|
21889
22270
|
printSessionBootstrapQuality(bootstrapQuality);
|
|
22271
|
+
printWorkflowLocalSessionSnapshot(localSessionSnapshot);
|
|
21890
22272
|
printWorkflowTeamSyncResume(teamSyncResume);
|
|
21891
22273
|
printWorkflowRuntimeResumePlan(runtimeResume);
|
|
21892
22274
|
printManagedWorkflowResumeBoundary();
|
|
@@ -21914,6 +22296,37 @@ async function loadWorkflowTeamSyncResume(state) {
|
|
|
21914
22296
|
};
|
|
21915
22297
|
}
|
|
21916
22298
|
}
|
|
22299
|
+
function printWorkflowLocalSessionSnapshot(snapshot) {
|
|
22300
|
+
console.log("");
|
|
22301
|
+
console.log(import_chalk6.default.bold("Local Session Snapshot"));
|
|
22302
|
+
if (snapshot.summary.latestActivityAt) {
|
|
22303
|
+
printKeyValue2("Latest activity:", snapshot.summary.latestActivityAt);
|
|
22304
|
+
}
|
|
22305
|
+
if (snapshot.summary.latestActivityTitle) {
|
|
22306
|
+
printKeyValue2("Latest title:", toPreview(snapshot.summary.latestActivityTitle, 160));
|
|
22307
|
+
}
|
|
22308
|
+
printKeyValue2("Risk:", snapshot.summary.risk);
|
|
22309
|
+
if (snapshot.summary.riskReasons.length > 0) {
|
|
22310
|
+
console.log(`Risk reasons: ${snapshot.summary.riskReasons.slice(0, 3).join("; ")}`);
|
|
22311
|
+
}
|
|
22312
|
+
if (snapshot.summary.touchedFiles.length > 0) {
|
|
22313
|
+
console.log(`Touched files: ${snapshot.summary.touchedFiles.slice(0, 8).join(", ")}`);
|
|
22314
|
+
}
|
|
22315
|
+
printKeyValue2(
|
|
22316
|
+
"Intent:",
|
|
22317
|
+
`${snapshot.intentDetection.intent} (${snapshot.intentDetection.confidence})`
|
|
22318
|
+
);
|
|
22319
|
+
printKeyValue2(
|
|
22320
|
+
"Suggested mode:",
|
|
22321
|
+
`${snapshot.intentDetection.advisoryRouting.suggestedWorkflowMode} (advisory)`
|
|
22322
|
+
);
|
|
22323
|
+
if (snapshot.intentDetection.signals.length > 0) {
|
|
22324
|
+
console.log(`Intent signals: ${snapshot.intentDetection.signals.slice(0, 5).join(", ")}`);
|
|
22325
|
+
}
|
|
22326
|
+
printKeyValue2("Hard routing allowed:", String(snapshot.intentDetection.hardRoutingAllowed));
|
|
22327
|
+
printKeyValue2("Next action:", snapshot.summary.recommendedNextAction);
|
|
22328
|
+
printKeyValue2("Snapshot:", snapshot.source.snapshotPath);
|
|
22329
|
+
}
|
|
21917
22330
|
function printWorkflowTeamSyncResume(result) {
|
|
21918
22331
|
if (!result) {
|
|
21919
22332
|
return;
|
|
@@ -25262,7 +25675,7 @@ function normalizeCaptureEvent(event, now, index) {
|
|
|
25262
25675
|
const reasons = normalizeStringList3(event.reason).map(redactText);
|
|
25263
25676
|
const evidence = normalizeStringList3(event.evidence).map(redactText);
|
|
25264
25677
|
const commands = normalizeStringList3(event.commands).map(redactText);
|
|
25265
|
-
const redactionPatterns =
|
|
25678
|
+
const redactionPatterns = uniqueStrings13([
|
|
25266
25679
|
...summary.patterns,
|
|
25267
25680
|
...outcome.patterns,
|
|
25268
25681
|
...status.patterns,
|
|
@@ -25295,7 +25708,7 @@ function normalizeEventKind(value) {
|
|
|
25295
25708
|
return "feedback";
|
|
25296
25709
|
}
|
|
25297
25710
|
function reasonCodesForEvent(event, kind, status) {
|
|
25298
|
-
return
|
|
25711
|
+
return uniqueStrings13([
|
|
25299
25712
|
"why_outcome_capture_v1",
|
|
25300
25713
|
"review_pending_authority",
|
|
25301
25714
|
`source_${event.kind}`,
|
|
@@ -25360,7 +25773,7 @@ function readEventsFromFile(filePath) {
|
|
|
25360
25773
|
function stableHash2(parts) {
|
|
25361
25774
|
return (0, import_node_crypto7.createHash)("sha256").update(parts.join("\0")).digest("hex");
|
|
25362
25775
|
}
|
|
25363
|
-
function
|
|
25776
|
+
function uniqueStrings13(values) {
|
|
25364
25777
|
return Array.from(new Set(values.filter(Boolean)));
|
|
25365
25778
|
}
|
|
25366
25779
|
function compactWhitespace3(value) {
|
|
@@ -26652,6 +27065,14 @@ async function buildProjectIntelligenceBrief(options) {
|
|
|
26652
27065
|
diffSummary: options.diffSummary
|
|
26653
27066
|
})
|
|
26654
27067
|
};
|
|
27068
|
+
try {
|
|
27069
|
+
brief.localSessionSnapshot = readSessionSnapshot() ?? buildSessionSnapshot({ limit: 8 });
|
|
27070
|
+
} catch (error) {
|
|
27071
|
+
errors.push({
|
|
27072
|
+
surface: "local_session_snapshot",
|
|
27073
|
+
message: error instanceof Error ? error.message : String(error)
|
|
27074
|
+
});
|
|
27075
|
+
}
|
|
26655
27076
|
try {
|
|
26656
27077
|
brief.resumeContext = await client.callTool("snipara_resume_context", {
|
|
26657
27078
|
...branch ? { branch } : {},
|
|
@@ -26750,6 +27171,36 @@ function printResumeContext(result) {
|
|
|
26750
27171
|
}
|
|
26751
27172
|
}
|
|
26752
27173
|
}
|
|
27174
|
+
function printLocalSessionSnapshot(snapshot) {
|
|
27175
|
+
if (!snapshot) {
|
|
27176
|
+
console.log(import_chalk9.default.yellow("Unavailable"));
|
|
27177
|
+
return;
|
|
27178
|
+
}
|
|
27179
|
+
if (snapshot.summary.latestActivityAt) {
|
|
27180
|
+
console.log(`Latest activity: ${snapshot.summary.latestActivityAt}`);
|
|
27181
|
+
}
|
|
27182
|
+
if (snapshot.summary.latestActivityTitle) {
|
|
27183
|
+
console.log(`Latest title: ${preview3(snapshot.summary.latestActivityTitle, 220)}`);
|
|
27184
|
+
}
|
|
27185
|
+
console.log(`Risk: ${snapshot.summary.risk}`);
|
|
27186
|
+
if (snapshot.summary.riskReasons.length > 0) {
|
|
27187
|
+
console.log(`Risk reasons: ${snapshot.summary.riskReasons.slice(0, 3).join("; ")}`);
|
|
27188
|
+
}
|
|
27189
|
+
if (snapshot.summary.touchedFiles.length > 0) {
|
|
27190
|
+
console.log(`Touched files: ${snapshot.summary.touchedFiles.slice(0, 8).join(", ")}`);
|
|
27191
|
+
}
|
|
27192
|
+
console.log(
|
|
27193
|
+
`Intent: ${snapshot.intentDetection.intent} (${snapshot.intentDetection.confidence})`
|
|
27194
|
+
);
|
|
27195
|
+
console.log(
|
|
27196
|
+
`Suggested mode: ${snapshot.intentDetection.advisoryRouting.suggestedWorkflowMode} (advisory)`
|
|
27197
|
+
);
|
|
27198
|
+
if (snapshot.intentDetection.signals.length > 0) {
|
|
27199
|
+
console.log(`Intent signals: ${snapshot.intentDetection.signals.slice(0, 5).join(", ")}`);
|
|
27200
|
+
}
|
|
27201
|
+
console.log(`Hard routing allowed: ${snapshot.intentDetection.hardRoutingAllowed}`);
|
|
27202
|
+
console.log(`Next action: ${snapshot.summary.recommendedNextAction}`);
|
|
27203
|
+
}
|
|
26753
27204
|
function printMemoryHealth2(result) {
|
|
26754
27205
|
if (!result) {
|
|
26755
27206
|
console.log(import_chalk9.default.yellow("Skipped or unavailable"));
|
|
@@ -26824,6 +27275,9 @@ async function projectIntelligenceBriefCommand(options) {
|
|
|
26824
27275
|
console.log(import_chalk9.default.bold("Continuity"));
|
|
26825
27276
|
printResumeContext(brief.resumeContext);
|
|
26826
27277
|
console.log("");
|
|
27278
|
+
console.log(import_chalk9.default.bold("Local Session"));
|
|
27279
|
+
printLocalSessionSnapshot(brief.localSessionSnapshot);
|
|
27280
|
+
console.log("");
|
|
26827
27281
|
console.log(import_chalk9.default.bold("Memory Authority And Health"));
|
|
26828
27282
|
printMemoryHealth2(brief.memoryHealth);
|
|
26829
27283
|
console.log("");
|
|
@@ -29531,7 +29985,7 @@ function mergeManagedCollaborationHookBlock(hookName, currentContent, block) {
|
|
|
29531
29985
|
const startMarker = collaborationHookBlockMarker(hookName, "start");
|
|
29532
29986
|
const endMarker = collaborationHookBlockMarker(hookName, "end");
|
|
29533
29987
|
const managedBlockPattern = new RegExp(
|
|
29534
|
-
`${
|
|
29988
|
+
`${escapeRegExp6(startMarker)}[\\s\\S]*?${escapeRegExp6(endMarker)}\\n?`,
|
|
29535
29989
|
"m"
|
|
29536
29990
|
);
|
|
29537
29991
|
const base = currentContent && currentContent.trim() ? currentContent : "#!/usr/bin/env sh\n";
|
|
@@ -30077,7 +30531,7 @@ function safeUsername() {
|
|
|
30077
30531
|
function formatError2(error) {
|
|
30078
30532
|
return error instanceof Error ? error.message : String(error);
|
|
30079
30533
|
}
|
|
30080
|
-
function
|
|
30534
|
+
function escapeRegExp6(value) {
|
|
30081
30535
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
30082
30536
|
}
|
|
30083
30537
|
function ensureTrailingNewline3(value) {
|
|
@@ -31151,9 +31605,10 @@ workflow.command("start").description(
|
|
|
31151
31605
|
workflow.command("status").description("Show the current local Snipara workflow state").option("--json", "Print raw JSON").action(async (options) => {
|
|
31152
31606
|
await workflowStatusCommand({ json: options.json });
|
|
31153
31607
|
});
|
|
31154
|
-
workflow.command("timeline").description("Show the append-only local activity timeline for this workflow session").option("-l, --limit <number>", "Maximum number of events", "20").option("--json", "Print raw JSON").action(async (options) => {
|
|
31608
|
+
workflow.command("timeline").description("Show the append-only local activity timeline for this workflow session").option("-l, --limit <number>", "Maximum number of events", "20").option("--export <format>", "Export redacted timeline artifact (md)").option("--json", "Print raw JSON").action(async (options) => {
|
|
31155
31609
|
await workflowTimelineCommand({
|
|
31156
31610
|
limit: parseInt(options.limit, 10),
|
|
31611
|
+
exportFormat: options.export,
|
|
31157
31612
|
json: Boolean(options.json)
|
|
31158
31613
|
});
|
|
31159
31614
|
});
|
|
@@ -32353,6 +32808,7 @@ if (require.main === module) {
|
|
|
32353
32808
|
readLocalCodePromotionState,
|
|
32354
32809
|
readLocalSourceSnapshot,
|
|
32355
32810
|
readLocalWorkersConfig,
|
|
32811
|
+
readSessionSnapshot,
|
|
32356
32812
|
realityCheckCommand,
|
|
32357
32813
|
referencesIngestCommand,
|
|
32358
32814
|
referencesScanCommand,
|
package/docs/FULL_REFERENCE.md
CHANGED
|
@@ -177,6 +177,7 @@ snipara-companion brief --task "ship auth hardening" --changed-files src/auth.ts
|
|
|
177
177
|
snipara-companion reality-check --task "ship auth hardening" --changed-files src/auth.ts --enforce
|
|
178
178
|
snipara-companion timeline
|
|
179
179
|
snipara-companion workflow timeline
|
|
180
|
+
snipara-companion workflow timeline --export md
|
|
180
181
|
snipara-companion workflow session --json
|
|
181
182
|
snipara-companion workflow phase-commit build --summary "tests green"
|
|
182
183
|
snipara-companion workflow impact-gate
|
|
@@ -218,11 +219,15 @@ snipara-companion workflow resume --include-session-context
|
|
|
218
219
|
commits, final commits, and Team Sync handoffs.
|
|
219
220
|
- `workflow timeline` reads the append-only local activity log at
|
|
220
221
|
`.snipara/activity/timeline.jsonl`, enriched by workflow, Producer Loop,
|
|
221
|
-
Decision Request, Team Sync, and journal-adjacent events.
|
|
222
|
+
Decision Request, Team Sync, and journal-adjacent events. Add `--export md`
|
|
223
|
+
for a compact redacted Markdown artifact suitable for handoff or publication.
|
|
222
224
|
- `workflow session` writes `.snipara/activity/session.json`, a fast Session
|
|
223
|
-
Snapshot V0 for local resume and Orchestrator dogfood. It
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
Snapshot V0 for local resume and Orchestrator dogfood. It includes latest
|
|
226
|
+
activity, risk reasons, touched files, next action, and advisory Intent
|
|
227
|
+
Detection V0. Intent Detection V0 reports intent, confidence, evidence
|
|
228
|
+
counts, reason-code signals, and an advisory suggested workflow mode. It is
|
|
229
|
+
observational only and reports `hardRoutingAllowed=false` until explicit
|
|
230
|
+
policy and receipts allow harder routing.
|
|
226
231
|
- `workflow impact-gate` audits committed local workflow phases that are ahead
|
|
227
232
|
of upstream but not pushed. It does not push, and dirty working-tree files are
|
|
228
233
|
reported separately from the committed diff.
|
|
@@ -244,6 +249,8 @@ snipara-companion workflow resume --include-session-context
|
|
|
244
249
|
- `memory reviews --scope project --emit-decisions` reads hosted memory review
|
|
245
250
|
queue, clean-candidate, and duplicate-candidate surfaces, summarizes each item,
|
|
246
251
|
and writes local Decision Request artifacts without mutating hosted memory.
|
|
252
|
+
JSON output includes `emittedCount`, `emittedRequestIds`, and an `emitted`
|
|
253
|
+
summary for direct agent follow-up.
|
|
247
254
|
- `workflow producer-report` scans local Producer Loop artifacts emitted by
|
|
248
255
|
workflow phase/final commits or exported PR Answer Pack decision-capture
|
|
249
256
|
producers, then reports adoption, producer kinds, workflow ids, reason-code
|
|
@@ -1101,10 +1108,10 @@ Semantics:
|
|
|
1101
1108
|
- `snipara-companion brief` = short alias for `snipara-companion intelligence brief`
|
|
1102
1109
|
- `snipara-companion reality-check` = local Project Reality Check plus Intent Ledger and Unknown Registry coverage for supplied or Git-derived changed files; `--enforce` is an opt-in strict mode for calibrated hooks
|
|
1103
1110
|
- `snipara-companion timeline` = local timeline of workflow starts, phase starts, phase commits, final commits, and Team Sync handoffs
|
|
1104
|
-
- `snipara-companion workflow timeline` = append-only activity timeline from `.snipara/activity/timeline.jsonl`, including workflow, Producer Loop, Decision Request, and Team Sync events emitted by Companion commands
|
|
1105
|
-
- `snipara-companion workflow session` = writes and prints Session Snapshot V0 at `.snipara/activity/session.json` with workflow/session counts, Producer Loop calibration, decision counts, Team Sync counts, and `hardRoutingAllowed=false`
|
|
1111
|
+
- `snipara-companion workflow timeline` = append-only activity timeline from `.snipara/activity/timeline.jsonl`, including workflow, Producer Loop, Decision Request, and Team Sync events emitted by Companion commands; add `--export md` for a redacted Markdown artifact
|
|
1112
|
+
- `snipara-companion workflow session` = writes and prints Session Snapshot V0 at `.snipara/activity/session.json` with latest activity, risk, touched files, next action, advisory Intent Detection V0 intent/confidence/signals/suggested mode, workflow/session counts, Producer Loop calibration, decision counts, Team Sync counts, and `hardRoutingAllowed=false`
|
|
1106
1113
|
- `snipara-companion handoff` = top-level agent-ready Markdown/JSON handoff artifact plus the same local/hosted Team Sync handoff persistence
|
|
1107
|
-
- `snipara-companion intelligence brief` = one local Project Intelligence brief that combines resume context, memory health, and code impact for a task
|
|
1114
|
+
- `snipara-companion intelligence brief` = one local Project Intelligence brief that combines local Session Snapshot, hosted resume context, memory health, and code impact for a task
|
|
1108
1115
|
- `snipara-companion intelligence reality-check` = Project Intelligence namespace alias for the same local Reality Check gate
|
|
1109
1116
|
- `snipara-companion intelligence ledger-export` = structured redacted Coding Intelligence Ledger JSON for replay, review, and commercial proof assets without dumping raw transcripts
|
|
1110
1117
|
- `snipara-companion run` = production Project Intelligence flow that combines the brief, guard action cards, package review, verification hints, and a final weighted Judgment Card
|