snipara-companion 2.0.1 → 2.0.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 CHANGED
@@ -72,6 +72,12 @@ blocked by default; use `--allow-sensitive` only when you intentionally need an
72
72
  exact local recovery artifact, and prefer the exact pack ID over `latest` in
73
73
  handoffs.
74
74
 
75
+ Metadata-only context-pack receipts include token economy fields:
76
+ `baseline_tokens`, `packed_tokens`, `retrieved_tokens`, and `saved_tokens`.
77
+ Pack/reference receipts can claim saved tokens because only receipt metadata is
78
+ uploaded; retrieve receipts set retrieved tokens to the local baseline so they
79
+ do not overstate savings.
80
+
75
81
  ```mermaid
76
82
  flowchart LR
77
83
  Project["Local project"] --> Companion["snipara-companion"]
@@ -244,6 +250,15 @@ Project owners can configure Adaptive Work Routing in Project > Automation:
244
250
  `off`, `recommend`, or `catalog`; approval; planner-retained reasoning; allowed
245
251
  endpoint types (`cloud`, `local`, `self_hosted`); worker classes; and budget
246
252
  hints. `workflow run` reads that hosted policy and CLI flags cannot broaden it.
253
+ Companion passes policy budgets into provider-neutral model requirements; the
254
+ hosted gateway enforces project and provider daily/monthly budgets when receipt
255
+ history is available.
256
+
257
+ Approval is an MCP contract, not a dashboard-only UX path. When project policy
258
+ requires approval, a coding agent calls `snipara_adaptive_routing_approve` with
259
+ the routing card or handoff subject, approved write scopes, endpoint types, a
260
+ stable `idempotency_key`, and optional cost/expiry bounds. Companion dry-runs
261
+ surface the approval requirement but do not auto-approve or spawn workers.
247
262
  Project credentials stay server-side behind the hosted gateway; local endpoints
248
263
  such as Ollama, LM Studio, AnythingLLM, or other OpenAI-compatible servers must
249
264
  be reachable from the worker execution environment.
package/dist/index.d.ts CHANGED
@@ -160,6 +160,10 @@ interface LocalContextPackReceiptPayload {
160
160
  tags: string[];
161
161
  bytes: number;
162
162
  line_count: number;
163
+ baseline_tokens?: number;
164
+ packed_tokens?: number;
165
+ retrieved_tokens?: number;
166
+ saved_tokens?: number;
163
167
  payload_digest?: string;
164
168
  sensitive: boolean;
165
169
  created_at: string;
@@ -537,6 +541,41 @@ interface EmitEventResult {
537
541
  sessionIds: string[];
538
542
  events: AutomationCheckpointSummary[];
539
543
  }
544
+ type AdvisorInfluenceAgentDecision = "accepted" | "modified" | "ignored" | "blocked";
545
+ type AdvisorInfluenceOutcomeLinkStatus = "pending" | "linked" | "missed" | "unevaluated";
546
+ interface AdvisorInfluenceRecommendationInput {
547
+ id: string;
548
+ version?: "advisor-recommendation-v0";
549
+ source: string;
550
+ severity: string;
551
+ title: string;
552
+ rationale: string;
553
+ reasonCodes: string[];
554
+ historicalImpactSummary?: string | null;
555
+ reasonCodeReliability?: number | null;
556
+ recommendedVerification: string[];
557
+ expectedBehaviorChange: string;
558
+ evidence?: unknown[];
559
+ caveats?: string[];
560
+ }
561
+ interface RecordAdvisorInfluenceReceiptInput {
562
+ servedJudgmentId: string;
563
+ recommendation: AdvisorInfluenceRecommendationInput;
564
+ agentDecision: AdvisorInfluenceAgentDecision;
565
+ behaviorChange: string;
566
+ verificationExecuted: string[];
567
+ outcomeLinkStatus?: AdvisorInfluenceOutcomeLinkStatus;
568
+ metadata?: Record<string, unknown>;
569
+ }
570
+ interface RecordAdvisorInfluenceReceiptResult {
571
+ project: {
572
+ id: string;
573
+ name: string;
574
+ slug: string;
575
+ };
576
+ receipt: Record<string, unknown>;
577
+ advisorInfluence: Record<string, unknown>;
578
+ }
540
579
  interface AutomationConfigFile {
541
580
  path: string;
542
581
  content: string;
@@ -1175,6 +1214,7 @@ declare class RLMClient {
1175
1214
  privacy_level: "standard" | "sensitive" | "restricted";
1176
1215
  payload?: Record<string, unknown>;
1177
1216
  }): Promise<EmitEventResult>;
1217
+ recordAdvisorInfluenceReceipt(input: RecordAdvisorInfluenceReceiptInput): Promise<RecordAdvisorInfluenceReceiptResult>;
1178
1218
  getAutomationEvents(args?: {
1179
1219
  sessionId?: string;
1180
1220
  limit?: number;
@@ -2000,6 +2040,8 @@ interface ProjectRunCommandOptions {
2000
2040
  skipMemoryHealth?: boolean;
2001
2041
  skipGuard?: boolean;
2002
2042
  skipPackageReview?: boolean;
2043
+ servedJudgmentId?: string;
2044
+ skipAdvisorReceipts?: boolean;
2003
2045
  json?: boolean;
2004
2046
  }
2005
2047
  interface ProjectRunGuardResult {
@@ -2017,6 +2059,20 @@ interface ProjectRunPackageReview {
2017
2059
  data?: unknown;
2018
2060
  error?: string;
2019
2061
  }
2062
+ interface ProjectRunAdvisorReceiptWrite {
2063
+ advisorRecommendationId: string;
2064
+ status: "recorded" | "error";
2065
+ result?: RecordAdvisorInfluenceReceiptResult;
2066
+ error?: string;
2067
+ }
2068
+ interface ProjectRunAdvisorReceiptCapture {
2069
+ status: "skipped" | "recorded" | "partial" | "error";
2070
+ servedJudgmentId?: string;
2071
+ attemptedCount: number;
2072
+ recordedCount: number;
2073
+ writes: ProjectRunAdvisorReceiptWrite[];
2074
+ reason?: string;
2075
+ }
2020
2076
  interface ProjectIntelligenceRunResult {
2021
2077
  version: "project-intelligence.production-run.v1";
2022
2078
  generatedAt: string;
@@ -2024,6 +2080,7 @@ interface ProjectIntelligenceRunResult {
2024
2080
  brief: ProjectIntelligenceBrief;
2025
2081
  guard?: ProjectRunGuardResult;
2026
2082
  packageReview?: ProjectRunPackageReview;
2083
+ advisorReceiptCapture?: ProjectRunAdvisorReceiptCapture;
2027
2084
  judgmentCard: ProjectIntelligenceJudgmentCard;
2028
2085
  suggestedCommands: string[];
2029
2086
  }
@@ -3017,6 +3074,8 @@ interface AdaptiveModelRequirements {
3017
3074
  preferredEndpointTypes?: string[];
3018
3075
  allowedEndpointTypes?: string[];
3019
3076
  catalogLimit?: number;
3077
+ dailyBudgetCents?: number;
3078
+ monthlyBudgetCents?: number;
3020
3079
  fallback: "main_agent";
3021
3080
  }
3022
3081
  interface AdaptiveRoutingCostEstimate {
@@ -3062,6 +3121,8 @@ interface AdaptiveWorkRoutingOptions {
3062
3121
  workerRole?: string;
3063
3122
  plannerRetainsReasoning?: boolean;
3064
3123
  catalogLimit?: number;
3124
+ dailyBudgetCents?: number;
3125
+ monthlyBudgetCents?: number;
3065
3126
  }
3066
3127
  interface OrchestratorHandoffArtifact {
3067
3128
  schemaVersion: "snipara.orchestrator.handoff.v1";
package/dist/index.js CHANGED
@@ -953,6 +953,19 @@ var RLMClient = class {
953
953
  clearTimeout(timeoutId);
954
954
  }
955
955
  }
956
+ async recordAdvisorInfluenceReceipt(input) {
957
+ return this.dashboardProjectRequest(
958
+ "/project-intelligence/advisor-influence",
959
+ {
960
+ method: "POST",
961
+ body: input
962
+ },
963
+ {
964
+ invalidMessage: "Advisor influence receipt write failed",
965
+ validate: (data) => Boolean(data.receipt && data.advisorInfluence)
966
+ }
967
+ );
968
+ }
956
969
  async getAutomationEvents(args) {
957
970
  if (!this.config.apiKey) {
958
971
  throw new Error("API key not configured. Run 'npx -y snipara-companion@latest init' first.");
@@ -2683,9 +2696,19 @@ async function contextPackCleanCommand(options = {}) {
2683
2696
  function uniqueStrings2(values) {
2684
2697
  return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
2685
2698
  }
2699
+ function estimateTokensFromBytes(bytes) {
2700
+ if (!Number.isFinite(bytes) || bytes <= 0) {
2701
+ return 0;
2702
+ }
2703
+ return Math.ceil(bytes / 4);
2704
+ }
2705
+ function estimateReceiptTokens(value) {
2706
+ return estimateTokensFromBytes(Buffer.byteLength(JSON.stringify(value), "utf8"));
2707
+ }
2686
2708
  function buildLocalContextPackReceipt(record, options = {}) {
2687
2709
  const operation = options.operation ?? "reference";
2688
- return {
2710
+ const baselineTokens = estimateTokensFromBytes(record.bytes);
2711
+ const baseReceipt = {
2689
2712
  version: "snipara.context_pack.receipt.v1",
2690
2713
  receipt_id: `${record.id}:${operation}:${record.updatedAt}`,
2691
2714
  pack_id: record.id,
@@ -2708,6 +2731,16 @@ function buildLocalContextPackReceipt(record, options = {}) {
2708
2731
  manifest_relative_path: record.storage.manifestRelativePath
2709
2732
  }
2710
2733
  };
2734
+ const packedTokens = estimateReceiptTokens(baseReceipt);
2735
+ const retrievedTokens = operation === "retrieve" ? baselineTokens : 0;
2736
+ const savedTokens = Math.max(0, baselineTokens - packedTokens - retrievedTokens);
2737
+ return {
2738
+ ...baseReceipt,
2739
+ baseline_tokens: baselineTokens,
2740
+ packed_tokens: packedTokens,
2741
+ retrieved_tokens: retrievedTokens,
2742
+ saved_tokens: savedTokens
2743
+ };
2711
2744
  }
2712
2745
  function buildLocalContextPackReceipts(options) {
2713
2746
  return uniqueStrings2(options.ids).slice(0, 20).map((id) => {
@@ -11543,6 +11576,158 @@ function outputPreview(value) {
11543
11576
  return `${value.slice(0, RAW_OUTPUT_PREVIEW_BYTES)}
11544
11577
  ...[truncated]`;
11545
11578
  }
11579
+ function stringValue4(value) {
11580
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
11581
+ }
11582
+ function servedJudgmentIdFromUnknown(value, depth = 0) {
11583
+ if (depth > 5 || value === null || value === void 0) {
11584
+ return void 0;
11585
+ }
11586
+ if (!isRecord7(value)) {
11587
+ if (Array.isArray(value)) {
11588
+ for (const item of value.slice(0, 12)) {
11589
+ const found = servedJudgmentIdFromUnknown(item, depth + 1);
11590
+ if (found) return found;
11591
+ }
11592
+ }
11593
+ return void 0;
11594
+ }
11595
+ const direct = stringValue4(value.servedJudgmentId) ?? stringValue4(value.served_judgment_id);
11596
+ if (direct) {
11597
+ return direct;
11598
+ }
11599
+ for (const key of [
11600
+ "projectIntelligence",
11601
+ "project_intelligence",
11602
+ "brief",
11603
+ "judgment",
11604
+ "resumeContext",
11605
+ "resume_context",
11606
+ "data"
11607
+ ]) {
11608
+ const found = servedJudgmentIdFromUnknown(value[key], depth + 1);
11609
+ if (found) return found;
11610
+ }
11611
+ return void 0;
11612
+ }
11613
+ function servedJudgmentIdForRun(options, brief) {
11614
+ return stringValue4(options.servedJudgmentId) ?? servedJudgmentIdFromUnknown(brief.resumeContext) ?? servedJudgmentIdFromUnknown(brief.verificationPlan);
11615
+ }
11616
+ function normalizeAdvisorSource(value) {
11617
+ if (value === "judgment" || value === "outcome_calibration" || value === "historical_impact" || value === "safety" || value === "verification" || value === "context_quality") {
11618
+ return value;
11619
+ }
11620
+ return "judgment";
11621
+ }
11622
+ function normalizeAdvisorSeverity2(value) {
11623
+ if (value === "info" || value === "watch" || value === "risk" || value === "block") {
11624
+ return value;
11625
+ }
11626
+ return "watch";
11627
+ }
11628
+ function advisorReceiptRecommendation(recommendation) {
11629
+ return {
11630
+ id: recommendation.id,
11631
+ version: "advisor-recommendation-v0",
11632
+ source: normalizeAdvisorSource(recommendation.source),
11633
+ severity: normalizeAdvisorSeverity2(recommendation.severity),
11634
+ title: recommendation.title,
11635
+ rationale: recommendation.rationale ?? recommendation.expectedBehaviorChange ?? `Snipara recommended ${recommendation.title}.`,
11636
+ reasonCodes: recommendation.reasonCodes,
11637
+ historicalImpactSummary: recommendation.historicalImpactSummary ?? null,
11638
+ reasonCodeReliability: recommendation.reasonCodeReliability ?? null,
11639
+ recommendedVerification: recommendation.recommendedVerification,
11640
+ expectedBehaviorChange: recommendation.expectedBehaviorChange ?? `Adapt the visible plan according to ${recommendation.title}.`,
11641
+ evidence: [],
11642
+ caveats: ["First-party companion receipt records plan adaptation, not outcome proof."]
11643
+ };
11644
+ }
11645
+ function advisorReceiptDecision(recommendation, judgmentCard) {
11646
+ if (recommendation.severity === "block" && judgmentCard.canProceed === "block") {
11647
+ return "blocked";
11648
+ }
11649
+ return "modified";
11650
+ }
11651
+ function advisorReceiptBehaviorChange(recommendation, judgmentCard) {
11652
+ const verification = recommendation.recommendedVerification.slice(0, 3).join("; ");
11653
+ const mode = recommendation.severity === "block" || recommendation.severity === "risk" ? "required action" : "advisory action";
11654
+ return [
11655
+ `snipara-companion run added a ${mode} from Project Advisor: ${recommendation.title}.`,
11656
+ recommendation.expectedBehaviorChange ? `Expected adaptation: ${recommendation.expectedBehaviorChange}.` : null,
11657
+ verification ? `Recommended verification to perform: ${verification}.` : null,
11658
+ `Judgment state after adaptation: ${judgmentCard.state}.`
11659
+ ].filter(Boolean).join(" ");
11660
+ }
11661
+ async function recordFirstPartyAdvisorReceipts(args) {
11662
+ if (args.options.skipAdvisorReceipts) {
11663
+ return {
11664
+ status: "skipped",
11665
+ attemptedCount: 0,
11666
+ recordedCount: 0,
11667
+ writes: [],
11668
+ reason: "advisor receipt capture was explicitly skipped"
11669
+ };
11670
+ }
11671
+ if (args.judgmentCard.advisorRecommendations.length === 0) {
11672
+ return void 0;
11673
+ }
11674
+ const servedJudgmentId = servedJudgmentIdForRun(args.options, args.brief);
11675
+ if (!servedJudgmentId) {
11676
+ return {
11677
+ status: "skipped",
11678
+ attemptedCount: 0,
11679
+ recordedCount: 0,
11680
+ writes: [],
11681
+ reason: "no served judgment id was available for first-party advisor receipts"
11682
+ };
11683
+ }
11684
+ const client = createClient(1e4);
11685
+ const recommendations = args.judgmentCard.advisorRecommendations.slice(0, 6);
11686
+ const writes = await Promise.all(
11687
+ recommendations.map(async (recommendation) => {
11688
+ try {
11689
+ const result = await client.recordAdvisorInfluenceReceipt({
11690
+ servedJudgmentId,
11691
+ recommendation: advisorReceiptRecommendation(recommendation),
11692
+ agentDecision: advisorReceiptDecision(recommendation, args.judgmentCard),
11693
+ behaviorChange: advisorReceiptBehaviorChange(recommendation, args.judgmentCard),
11694
+ verificationExecuted: [],
11695
+ outcomeLinkStatus: "pending",
11696
+ metadata: {
11697
+ source: "snipara-companion:run",
11698
+ firstParty: true,
11699
+ runVersion: "project-intelligence.production-run.v1",
11700
+ generatedAt: args.judgmentCard.generatedAt,
11701
+ release: Boolean(args.options.release),
11702
+ branch: args.brief.branch ?? args.options.branch ?? null,
11703
+ changedFiles: args.brief.changedFiles,
11704
+ judgmentState: args.judgmentCard.state,
11705
+ canProceed: args.judgmentCard.canProceed
11706
+ }
11707
+ });
11708
+ return {
11709
+ advisorRecommendationId: recommendation.id,
11710
+ status: "recorded",
11711
+ result
11712
+ };
11713
+ } catch (error) {
11714
+ return {
11715
+ advisorRecommendationId: recommendation.id,
11716
+ status: "error",
11717
+ error: error instanceof Error ? error.message : String(error)
11718
+ };
11719
+ }
11720
+ })
11721
+ );
11722
+ const recordedCount = writes.filter((write) => write.status === "recorded").length;
11723
+ return {
11724
+ status: recordedCount === writes.length ? "recorded" : recordedCount > 0 ? "partial" : "error",
11725
+ servedJudgmentId,
11726
+ attemptedCount: writes.length,
11727
+ recordedCount,
11728
+ writes
11729
+ };
11730
+ }
11546
11731
  function runGuard(options, changedFiles) {
11547
11732
  const cliPath = process.argv[1] || "snipara-companion";
11548
11733
  const args = [
@@ -11658,6 +11843,11 @@ async function buildProjectIntelligenceRun(options) {
11658
11843
  packageReview,
11659
11844
  errors: runErrors
11660
11845
  });
11846
+ const advisorReceiptCapture = await recordFirstPartyAdvisorReceipts({
11847
+ options,
11848
+ brief,
11849
+ judgmentCard
11850
+ });
11661
11851
  const suggestedCommands = [
11662
11852
  ...brief.suggestedCommands,
11663
11853
  ...options.release ? [
@@ -11672,6 +11862,7 @@ async function buildProjectIntelligenceRun(options) {
11672
11862
  brief,
11673
11863
  ...guard ? { guard } : {},
11674
11864
  ...packageReview ? { packageReview } : {},
11865
+ ...advisorReceiptCapture ? { advisorReceiptCapture } : {},
11675
11866
  judgmentCard,
11676
11867
  suggestedCommands: [...new Set(suggestedCommands)]
11677
11868
  };
@@ -11712,6 +11903,20 @@ async function projectIntelligenceRunCommand(options) {
11712
11903
  }
11713
11904
  console.log("");
11714
11905
  }
11906
+ if (result.advisorReceiptCapture) {
11907
+ console.log(import_chalk8.default.bold("Advisor Receipts"));
11908
+ console.log(`Status: ${result.advisorReceiptCapture.status}`);
11909
+ if (result.advisorReceiptCapture.servedJudgmentId) {
11910
+ console.log(`Served judgment: ${result.advisorReceiptCapture.servedJudgmentId}`);
11911
+ }
11912
+ console.log(
11913
+ `Recorded: ${result.advisorReceiptCapture.recordedCount}/${result.advisorReceiptCapture.attemptedCount}`
11914
+ );
11915
+ if (result.advisorReceiptCapture.reason) {
11916
+ console.log(result.advisorReceiptCapture.reason);
11917
+ }
11918
+ console.log("");
11919
+ }
11715
11920
  console.log(import_chalk8.default.bold("Suggested Commands"));
11716
11921
  for (const command of result.suggestedCommands.slice(0, 8)) {
11717
11922
  console.log(command);
@@ -11853,6 +12058,8 @@ function buildAdaptiveWorkRoutingRecommendation(options) {
11853
12058
  preferredEndpointTypes,
11854
12059
  allowedEndpointTypes,
11855
12060
  catalogLimit: options.catalogLimit,
12061
+ dailyBudgetCents: options.dailyBudgetCents,
12062
+ monthlyBudgetCents: options.monthlyBudgetCents,
11856
12063
  fallback: "main_agent"
11857
12064
  });
11858
12065
  const warnings = [
@@ -11980,7 +12187,7 @@ function inferAdaptiveEvidenceRequirements(query, risk) {
11980
12187
  function normalizeEndpointTypes(values) {
11981
12188
  return Array.from(
11982
12189
  new Set(
11983
- (values ?? []).map((value) => stringValue4(value)?.toLowerCase()).filter((value) => Boolean(value))
12190
+ (values ?? []).map((value) => stringValue5(value)?.toLowerCase()).filter((value) => Boolean(value))
11984
12191
  )
11985
12192
  ).sort();
11986
12193
  }
@@ -12016,24 +12223,24 @@ function readWorkflowState(rootDir) {
12016
12223
  const runtimeBindings = Array.isArray(parsed.runtime?.sandbox?.bindings) ? parsed.runtime?.sandbox?.bindings.filter(isRecord8) : [];
12017
12224
  const runtimeSandboxPhases = phases.filter((phase) => phase.needsRuntime).map((phase) => {
12018
12225
  const binding = runtimeBindings.find(
12019
- (candidate) => stringValue4(candidate.phaseId) === phase.id
12226
+ (candidate) => stringValue5(candidate.phaseId) === phase.id
12020
12227
  );
12021
12228
  const checkpoint = isRecord8(binding?.lastCheckpoint) ? binding.lastCheckpoint : void 0;
12022
12229
  return {
12023
12230
  phaseId: phase.id,
12024
12231
  title: phase.title,
12025
- bootstrapQuery: stringValue4(binding?.bootstrapQuery) ?? phase.query,
12232
+ bootstrapQuery: stringValue5(binding?.bootstrapQuery) ?? phase.query,
12026
12233
  files: phase.files,
12027
12234
  artifacts: normalizeStringList3(
12028
12235
  Array.isArray(binding?.artifacts) ? binding.artifacts : Array.isArray(checkpoint?.artifacts) ? checkpoint.artifacts : void 0
12029
12236
  ),
12030
12237
  contextPacks: normalizeContextPackIds(checkpoint?.contextPackReceipts),
12031
- sessionId: stringValue4(binding?.sessionId) ?? null,
12032
- environment: stringValue4(binding?.environment) ?? stringValue4(checkpoint?.environment) ?? null,
12033
- profile: stringValue4(binding?.profile) ?? stringValue4(checkpoint?.profile) ?? null,
12238
+ sessionId: stringValue5(binding?.sessionId) ?? null,
12239
+ environment: stringValue5(binding?.environment) ?? stringValue5(checkpoint?.environment) ?? null,
12240
+ profile: stringValue5(binding?.profile) ?? stringValue5(checkpoint?.profile) ?? null,
12034
12241
  hasCheckpoint: Boolean(checkpoint),
12035
- checkpointSummary: stringValue4(checkpoint?.summary) ?? null,
12036
- checkpointCapturedAt: stringValue4(checkpoint?.capturedAt) ?? null
12242
+ checkpointSummary: stringValue5(checkpoint?.summary) ?? null,
12243
+ checkpointCapturedAt: stringValue5(checkpoint?.capturedAt) ?? null
12037
12244
  };
12038
12245
  });
12039
12246
  return {
@@ -12049,18 +12256,18 @@ function normalizeContextPackIds(value) {
12049
12256
  return [];
12050
12257
  }
12051
12258
  return normalizeStringList3(
12052
- value.filter(isRecord8).map((receipt) => stringValue4(receipt.pack_id)).filter((packId) => Boolean(packId))
12259
+ value.filter(isRecord8).map((receipt) => stringValue5(receipt.pack_id)).filter((packId) => Boolean(packId))
12053
12260
  );
12054
12261
  }
12055
12262
  function normalizeWorkflowPhase(phase, index) {
12056
- const id = stringValue4(phase.id) ?? `phase-${index + 1}`;
12057
- const title = stringValue4(phase.title) ?? id;
12263
+ const id = stringValue5(phase.id) ?? `phase-${index + 1}`;
12264
+ const title = stringValue5(phase.title) ?? id;
12058
12265
  return {
12059
12266
  id,
12060
12267
  title,
12061
- query: stringValue4(phase.query) ?? title,
12062
- status: stringValue4(phase.status) ?? "pending",
12063
- ...stringValue4(phase.acceptance) ? { acceptance: stringValue4(phase.acceptance) } : {},
12268
+ query: stringValue5(phase.query) ?? title,
12269
+ status: stringValue5(phase.status) ?? "pending",
12270
+ ...stringValue5(phase.acceptance) ? { acceptance: stringValue5(phase.acceptance) } : {},
12064
12271
  files: normalizeStringList3(Array.isArray(phase.files) ? phase.files : void 0),
12065
12272
  gates: normalizeStringList3(Array.isArray(phase.gates) ? phase.gates : void 0),
12066
12273
  needsRuntime: Boolean(phase.needsRuntime)
@@ -12069,7 +12276,7 @@ function normalizeWorkflowPhase(phase, index) {
12069
12276
  function isRecord8(value) {
12070
12277
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
12071
12278
  }
12072
- function stringValue4(value) {
12279
+ function stringValue5(value) {
12073
12280
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
12074
12281
  }
12075
12282
  function readGitValue(rootDir, args) {
@@ -12086,7 +12293,7 @@ function readGitValue(rootDir, args) {
12086
12293
  function normalizeStringList3(values) {
12087
12294
  return Array.from(
12088
12295
  new Set(
12089
- (values ?? []).map((value) => stringValue4(value)).filter((value) => Boolean(value))
12296
+ (values ?? []).map((value) => stringValue5(value)).filter((value) => Boolean(value))
12090
12297
  )
12091
12298
  ).sort();
12092
12299
  }
@@ -15284,7 +15491,7 @@ function printKeyValue(label, value) {
15284
15491
  function isRecord9(value) {
15285
15492
  return typeof value === "object" && value !== null && !Array.isArray(value);
15286
15493
  }
15287
- function stringValue5(value) {
15494
+ function stringValue6(value) {
15288
15495
  if (value === null || value === void 0) {
15289
15496
  return void 0;
15290
15497
  }
@@ -15295,7 +15502,7 @@ function numberValue5(value) {
15295
15502
  if (typeof value === "number" && Number.isFinite(value)) {
15296
15503
  return value;
15297
15504
  }
15298
- const text = stringValue5(value);
15505
+ const text = stringValue6(value);
15299
15506
  if (!text) {
15300
15507
  return void 0;
15301
15508
  }
@@ -15306,10 +15513,10 @@ function uniqueStrings5(values) {
15306
15513
  return Array.from(new Set(values.filter((value) => value.trim().length > 0)));
15307
15514
  }
15308
15515
  function normalizeEnum(value) {
15309
- return stringValue5(value)?.replace(/[-\s]/g, "_").toUpperCase() ?? "";
15516
+ return stringValue6(value)?.replace(/[-\s]/g, "_").toUpperCase() ?? "";
15310
15517
  }
15311
15518
  function parseIsoDate(value) {
15312
- const text = stringValue5(value);
15519
+ const text = stringValue6(value);
15313
15520
  if (!text) {
15314
15521
  return void 0;
15315
15522
  }
@@ -15399,7 +15606,7 @@ function normalizeDocumentKind(value) {
15399
15606
  return void 0;
15400
15607
  }
15401
15608
  function normalizeDocumentFormat(value) {
15402
- return stringValue5(value)?.toLowerCase();
15609
+ return stringValue6(value)?.toLowerCase();
15403
15610
  }
15404
15611
  function isSupportedDocumentFormat(kind, format) {
15405
15612
  if (!kind || !format) {
@@ -15646,7 +15853,7 @@ function collectPlanFileHints(plan) {
15646
15853
  function buildPlanRelevanceWarnings(plan, options) {
15647
15854
  const warnings = [];
15648
15855
  const fileHints = collectPlanFileHints(plan);
15649
- const query = compactWhitespace(options.query ?? stringValue5(plan.query) ?? "");
15856
+ const query = compactWhitespace(options.query ?? stringValue6(plan.query) ?? "");
15650
15857
  if (fileHints.length === 0 || query.length === 0) {
15651
15858
  return warnings;
15652
15859
  }
@@ -15710,19 +15917,19 @@ function validatePlanResult(plan, options = {}) {
15710
15917
  issues.push(`Step ${index + 1} is not an object or string.`);
15711
15918
  return;
15712
15919
  }
15713
- const action = stringValue5(step.action);
15920
+ const action = stringValue6(step.action);
15714
15921
  if (action) {
15715
15922
  actions.push(action);
15716
15923
  if (isPlaceholderPlanLabel(action, index)) {
15717
15924
  issues.push(`Step ${index + 1} has a placeholder action.`);
15718
15925
  }
15719
15926
  }
15720
- const labelSource = stringValue5(step.title) ?? stringValue5(step.name) ?? action ?? stringValue5(step.goal) ?? stringValue5(step.query) ?? stringValue5(step.description);
15927
+ const labelSource = stringValue6(step.title) ?? stringValue6(step.name) ?? action ?? stringValue6(step.goal) ?? stringValue6(step.query) ?? stringValue6(step.description);
15721
15928
  if (!labelSource || isPlaceholderPlanLabel(labelSource, index)) {
15722
15929
  issues.push(`Step ${index + 1} is missing a useful title or action.`);
15723
15930
  }
15724
- const expectedOutput = stringValue5(step.expected_output);
15725
- if (!expectedOutput && !stringValue5(step.acceptance) && !stringValue5(step.verify)) {
15931
+ const expectedOutput = stringValue6(step.expected_output);
15932
+ if (!expectedOutput && !stringValue6(step.acceptance) && !stringValue6(step.verify)) {
15726
15933
  issues.push(`Step ${index + 1} is missing expected output or acceptance criteria.`);
15727
15934
  }
15728
15935
  const params = isRecord9(step.params) ? step.params : void 0;
@@ -15741,7 +15948,7 @@ function validatePlanResult(plan, options = {}) {
15741
15948
  warnings,
15742
15949
  stepCount: steps.length,
15743
15950
  actions,
15744
- ...stringValue5(plan.plan_id) ? { planId: stringValue5(plan.plan_id) } : {}
15951
+ ...stringValue6(plan.plan_id) ? { planId: stringValue6(plan.plan_id) } : {}
15745
15952
  };
15746
15953
  }
15747
15954
  function readBootstrapEntryText(entry) {
@@ -15810,7 +16017,7 @@ function normalizeStringArray3(value) {
15810
16017
  if (!raw) {
15811
16018
  return void 0;
15812
16019
  }
15813
- const items = raw.map((item) => stringValue5(item)).filter((item) => Boolean(item));
16020
+ const items = raw.map((item) => stringValue6(item)).filter((item) => Boolean(item));
15814
16021
  return items.length > 0 ? items : void 0;
15815
16022
  }
15816
16023
  function isUsableGeneratedStepQuery(value) {
@@ -15831,12 +16038,12 @@ function planStepToWorkflowStep(step, index, fallbackGoal) {
15831
16038
  };
15832
16039
  }
15833
16040
  const params = isRecord9(step.params) ? step.params : void 0;
15834
- const query = stringValue5(step.query) ?? stringValue5(step.goal) ?? stringValue5(step.description) ?? (isUsableGeneratedStepQuery(params?.query) ? params.query : void 0) ?? fallbackQuery;
15835
- const acceptance = stringValue5(step.acceptance) ?? stringValue5(step.expected_output) ?? stringValue5(step.done_when) ?? stringValue5(step.verify);
16041
+ const query = stringValue6(step.query) ?? stringValue6(step.goal) ?? stringValue6(step.description) ?? (isUsableGeneratedStepQuery(params?.query) ? params.query : void 0) ?? fallbackQuery;
16042
+ const acceptance = stringValue6(step.acceptance) ?? stringValue6(step.expected_output) ?? stringValue6(step.done_when) ?? stringValue6(step.verify);
15836
16043
  const likelyFiles = params && step.action === "implementation_map" ? normalizeStringArray3(params.likely_files) : normalizeStringArray3(step.files) ?? normalizeStringArray3(step.files_touched) ?? normalizeStringArray3(step.paths);
15837
16044
  return {
15838
16045
  id: sanitizeWorkflowId(
15839
- stringValue5(step.id) ?? stringValue5(step.phase_id) ?? stringValue5(step.key) ?? title,
16046
+ stringValue6(step.id) ?? stringValue6(step.phase_id) ?? stringValue6(step.key) ?? title,
15840
16047
  `phase-${index + 1}`
15841
16048
  ),
15842
16049
  title,
@@ -15847,7 +16054,7 @@ function planStepToWorkflowStep(step, index, fallbackGoal) {
15847
16054
  };
15848
16055
  }
15849
16056
  function buildGeneratedWorkflowPlanDocument(plan, fallbackGoal) {
15850
- const goal = stringValue5(plan.query) ?? fallbackGoal;
16057
+ const goal = stringValue6(plan.query) ?? fallbackGoal;
15851
16058
  const steps = findWorkflowSteps(plan).map(
15852
16059
  (step, index) => planStepToWorkflowStep(step, index, goal)
15853
16060
  );
@@ -15855,7 +16062,7 @@ function buildGeneratedWorkflowPlanDocument(plan, fallbackGoal) {
15855
16062
  mode: "full",
15856
16063
  goal,
15857
16064
  source: "snipara_plan",
15858
- ...stringValue5(plan.plan_id) ? { plan_id: stringValue5(plan.plan_id) } : {},
16065
+ ...stringValue6(plan.plan_id) ? { plan_id: stringValue6(plan.plan_id) } : {},
15859
16066
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
15860
16067
  steps
15861
16068
  };
@@ -15882,7 +16089,7 @@ function booleanValue(value) {
15882
16089
  if (typeof value === "boolean") {
15883
16090
  return value;
15884
16091
  }
15885
- const text = stringValue5(value)?.toLowerCase();
16092
+ const text = stringValue6(value)?.toLowerCase();
15886
16093
  if (!text) {
15887
16094
  return void 0;
15888
16095
  }
@@ -15900,7 +16107,7 @@ function uniqueStringList(values) {
15900
16107
  }
15901
16108
  const unique3 = Array.from(
15902
16109
  new Set(
15903
- values.map((value) => stringValue5(value)).filter((value) => Boolean(value))
16110
+ values.map((value) => stringValue6(value)).filter((value) => Boolean(value))
15904
16111
  )
15905
16112
  );
15906
16113
  return unique3.length > 0 ? unique3 : void 0;
@@ -15959,15 +16166,15 @@ function normalizeWorkflowPhase2(step, index, usedIds, fallbackGoal) {
15959
16166
  status: "pending"
15960
16167
  };
15961
16168
  }
15962
- const title = stringValue5(step.title) ?? stringValue5(step.name) ?? stringValue5(step.action) ?? stringValue5(step.goal) ?? `Phase ${index + 1}`;
15963
- const query = stringValue5(step.query) ?? stringValue5(step.goal) ?? stringValue5(step.description) ?? stringValue5(step.action) ?? `${fallbackGoal}: ${title}`;
16169
+ const title = stringValue6(step.title) ?? stringValue6(step.name) ?? stringValue6(step.action) ?? stringValue6(step.goal) ?? `Phase ${index + 1}`;
16170
+ const query = stringValue6(step.query) ?? stringValue6(step.goal) ?? stringValue6(step.description) ?? stringValue6(step.action) ?? `${fallbackGoal}: ${title}`;
15964
16171
  const id = uniquePhaseId(
15965
- stringValue5(step.id) ?? stringValue5(step.phase_id) ?? stringValue5(step.key) ?? title,
16172
+ stringValue6(step.id) ?? stringValue6(step.phase_id) ?? stringValue6(step.key) ?? title,
15966
16173
  index,
15967
16174
  usedIds
15968
16175
  );
15969
16176
  const files = normalizeStringArray3(step.files) ?? normalizeStringArray3(step.files_touched) ?? normalizeStringArray3(step.paths);
15970
- const acceptance = stringValue5(step.acceptance) ?? stringValue5(step.expected_output) ?? stringValue5(step.done_when) ?? stringValue5(step.verify);
16177
+ const acceptance = stringValue6(step.acceptance) ?? stringValue6(step.expected_output) ?? stringValue6(step.done_when) ?? stringValue6(step.verify);
15971
16178
  return {
15972
16179
  id,
15973
16180
  title,
@@ -16465,7 +16672,7 @@ function runtimeCheckpointEventPayload(event) {
16465
16672
  if (!payload) {
16466
16673
  return void 0;
16467
16674
  }
16468
- const toolName = stringValue5(payload.tool_name ?? payload.toolName ?? payload.tool);
16675
+ const toolName = stringValue6(payload.tool_name ?? payload.toolName ?? payload.tool);
16469
16676
  if (toolName !== "snipara_sandbox_runtime_checkpoint") {
16470
16677
  return void 0;
16471
16678
  }
@@ -16476,8 +16683,8 @@ function parseRuntimeCheckpointFromEvent(event, workflowId, phaseId) {
16476
16683
  if (!payload) {
16477
16684
  return void 0;
16478
16685
  }
16479
- const eventWorkflowId = stringValue5(payload.workflow_id);
16480
- const eventPhaseId = stringValue5(payload.workflow_phase_id);
16686
+ const eventWorkflowId = stringValue6(payload.workflow_id);
16687
+ const eventPhaseId = stringValue6(payload.workflow_phase_id);
16481
16688
  if (eventWorkflowId !== workflowId || eventPhaseId !== phaseId) {
16482
16689
  return void 0;
16483
16690
  }
@@ -16486,14 +16693,14 @@ function parseRuntimeCheckpointFromEvent(event, workflowId, phaseId) {
16486
16693
  return void 0;
16487
16694
  }
16488
16695
  return normalizeRuntimeCheckpointRecord({
16489
- summary: stringValue5(runtimeCheckpoint.summary) ?? stringValue5(payload.task) ?? "Runtime checkpoint captured",
16490
- capturedAt: stringValue5(runtimeCheckpoint.captured_at) ?? stringValue5(event.event.timestamp) ?? event.createdAt,
16491
- automationSessionId: stringValue5(runtimeCheckpoint.automation_session_id) ?? stringValue5(event.event.session_id) ?? void 0,
16696
+ summary: stringValue6(runtimeCheckpoint.summary) ?? stringValue6(payload.task) ?? "Runtime checkpoint captured",
16697
+ capturedAt: stringValue6(runtimeCheckpoint.captured_at) ?? stringValue6(event.event.timestamp) ?? event.createdAt,
16698
+ automationSessionId: stringValue6(runtimeCheckpoint.automation_session_id) ?? stringValue6(event.event.session_id) ?? void 0,
16492
16699
  hostedEventId: event.id,
16493
16700
  hostedRecordedAt: event.createdAt,
16494
- environment: stringValue5(runtimeCheckpoint.environment),
16495
- profile: stringValue5(runtimeCheckpoint.profile),
16496
- bootstrapQuery: stringValue5(runtimeCheckpoint.bootstrap_query) ?? stringValue5(payload.task) ?? void 0,
16701
+ environment: stringValue6(runtimeCheckpoint.environment),
16702
+ profile: stringValue6(runtimeCheckpoint.profile),
16703
+ bootstrapQuery: stringValue6(runtimeCheckpoint.bootstrap_query) ?? stringValue6(payload.task) ?? void 0,
16497
16704
  files: normalizeStringArray3(runtimeCheckpoint.files) ?? normalizeStringArray3(payload.files) ?? void 0,
16498
16705
  commands: normalizeStringArray3(runtimeCheckpoint.commands) ?? normalizeStringArray3(payload.commands) ?? void 0,
16499
16706
  artifacts: normalizeStringArray3(runtimeCheckpoint.artifacts) ?? void 0,
@@ -17131,7 +17338,7 @@ function commitsMatch(left, right) {
17131
17338
  }
17132
17339
  function stringArrayField(record, key) {
17133
17340
  const value = record[key];
17134
- return Array.isArray(value) ? value.map((item) => stringValue5(item)).filter((item) => Boolean(item)) : [];
17341
+ return Array.isArray(value) ? value.map((item) => stringValue6(item)).filter((item) => Boolean(item)) : [];
17135
17342
  }
17136
17343
  function printCodeIndexFreshness(record) {
17137
17344
  const freshness = recordField(record, "index_freshness");
@@ -17139,8 +17346,8 @@ function printCodeIndexFreshness(record) {
17139
17346
  return;
17140
17347
  }
17141
17348
  const coverage = recordField(freshness, "coverage");
17142
- const indexedCommit = stringValue5(freshness.indexed_commit_sha);
17143
- const sourceCommit = stringValue5(freshness.source_commit_sha);
17349
+ const indexedCommit = stringValue6(freshness.indexed_commit_sha);
17350
+ const sourceCommit = stringValue6(freshness.source_commit_sha);
17144
17351
  const commit = indexedCommit ?? sourceCommit;
17145
17352
  const coverageText = coverage && coverage.coverage_percent !== void 0 ? `${coverage.coverage_percent}%` : void 0;
17146
17353
  const localGit = readLocalGitState();
@@ -17183,9 +17390,9 @@ function printCodeIndexFreshness(record) {
17183
17390
  console.log("");
17184
17391
  }
17185
17392
  function formatAction(record) {
17186
- const label = stringValue5(record.action) ?? stringValue5(record.code) ?? stringValue5(record.tool) ?? stringValue5(record.name) ?? "action";
17187
- const priority = stringValue5(record.priority ?? record.severity);
17188
- const reason = stringValue5(record.reason ?? record.message);
17393
+ const label = stringValue6(record.action) ?? stringValue6(record.code) ?? stringValue6(record.tool) ?? stringValue6(record.name) ?? "action";
17394
+ const priority = stringValue6(record.priority ?? record.severity);
17395
+ const reason = stringValue6(record.reason ?? record.message);
17189
17396
  const targets = stringArrayField(record, "targets");
17190
17397
  const suffix = [
17191
17398
  priority ? `[${priority}]` : void 0,
@@ -17217,9 +17424,9 @@ function printSuggestedToolList(record) {
17217
17424
  }
17218
17425
  console.log(import_chalk9.default.bold("Suggested MCP Follow-ups"));
17219
17426
  for (const suggestion of suggestions.slice(0, 5)) {
17220
- const tool = stringValue5(suggestion.tool) ?? "snipara_code_*";
17427
+ const tool = stringValue6(suggestion.tool) ?? "snipara_code_*";
17221
17428
  const args = recordField(suggestion, "arguments") ?? {};
17222
- const reason = stringValue5(suggestion.reason);
17429
+ const reason = stringValue6(suggestion.reason);
17223
17430
  console.log(`- ${tool}(${JSON.stringify(args)})${reason ? ` - ${reason}` : ""}`);
17224
17431
  }
17225
17432
  console.log("");
@@ -17874,9 +18081,9 @@ async function enrichAdaptiveRoutingWithHostedCatalog(client, routing) {
17874
18081
  const gateway = {
17875
18082
  source: "hosted_mcp",
17876
18083
  success: gatewaySucceeded,
17877
- resolutionStatus: stringValue5(result.resolution?.status),
18084
+ resolutionStatus: stringValue6(result.resolution?.status),
17878
18085
  candidateCount,
17879
- fallback: stringValue5(result.fallback) ?? stringValue5(result.resolution?.fallback) ?? "main_agent",
18086
+ fallback: stringValue6(result.fallback) ?? stringValue6(result.resolution?.fallback) ?? "main_agent",
17880
18087
  warnings: gatewayWarnings
17881
18088
  };
17882
18089
  const reasons = [
@@ -17921,7 +18128,7 @@ function normalizeAdaptiveRoutingCatalog(value) {
17921
18128
  (candidate) => Boolean(candidate) && typeof candidate === "object" && !Array.isArray(candidate)
17922
18129
  ) : [];
17923
18130
  return {
17924
- version: stringValue5(record.version),
18131
+ version: stringValue6(record.version),
17925
18132
  candidates
17926
18133
  };
17927
18134
  }
@@ -18526,7 +18733,7 @@ function normalizeSyncDocumentsPayload(payload) {
18526
18733
  const inferred = inferDocumentFormat(item.path);
18527
18734
  const kind = normalizeDocumentKind(item.kind) ?? inferred?.kind;
18528
18735
  const format = normalizeDocumentFormat(item.format) ?? inferred?.format;
18529
- const language = stringValue5(item.language) ?? void 0;
18736
+ const language = stringValue6(item.language) ?? void 0;
18530
18737
  return {
18531
18738
  path: item.path,
18532
18739
  content: item.content,
@@ -18733,7 +18940,7 @@ var REPO_DOC_FILES = /* @__PURE__ */ new Set([
18733
18940
  "SECURITY.md"
18734
18941
  ]);
18735
18942
  function normalizeOnboardFolderMode(value) {
18736
- const normalized = stringValue5(value)?.replace(/[-\s]/g, "_").toLowerCase() ?? "auto";
18943
+ const normalized = stringValue6(value)?.replace(/[-\s]/g, "_").toLowerCase() ?? "auto";
18737
18944
  if (normalized === "auto" || normalized === "business_context" || normalized === "code_project" || normalized === "mixed") {
18738
18945
  return normalized;
18739
18946
  }
@@ -19055,7 +19262,7 @@ function normalizeUsageMode(value) {
19055
19262
  function hasReferenceProvenance(metadata) {
19056
19263
  const referenceProvenance = metadata.referenceProvenance ?? metadata.reference_provenance;
19057
19264
  if (isRecord9(referenceProvenance)) {
19058
- return Object.values(referenceProvenance).some((value) => Boolean(stringValue5(value)));
19265
+ return Object.values(referenceProvenance).some((value) => Boolean(stringValue6(value)));
19059
19266
  }
19060
19267
  return [
19061
19268
  metadata.clientId,
@@ -19094,7 +19301,7 @@ function validateDocumentForDryRun(document, now) {
19094
19301
  const reasons = [];
19095
19302
  const reviewReasons = [];
19096
19303
  const reuploadReasons = [];
19097
- const assetClass = stringValue5(metadata.assetClass ?? metadata.asset_class);
19304
+ const assetClass = stringValue6(metadata.assetClass ?? metadata.asset_class);
19098
19305
  if (!isSupportedDocumentFormat(kind, format)) {
19099
19306
  reasons.push("invalid_document_format");
19100
19307
  }
@@ -19109,7 +19316,7 @@ function validateDocumentForDryRun(document, now) {
19109
19316
  if (usageModeRaw !== void 0 && !usageMode) {
19110
19317
  reasons.push("invalid_usage_mode");
19111
19318
  }
19112
- const sourceKind = stringValue5(metadata.sourceKind ?? metadata.source_kind);
19319
+ const sourceKind = stringValue6(metadata.sourceKind ?? metadata.source_kind);
19113
19320
  if (sourceKind && !SOURCE_KINDS.has(sourceKind)) {
19114
19321
  reasons.push("invalid_source_kind");
19115
19322
  }
@@ -19118,8 +19325,8 @@ function validateDocumentForDryRun(document, now) {
19118
19325
  const sourceSnapshotAtRaw = metadata.sourceSnapshotAt ?? metadata.source_snapshot_at;
19119
19326
  const sourceModifiedAt = parseIsoDate(sourceModifiedAtRaw);
19120
19327
  const sourceSnapshotAt = parseIsoDate(sourceSnapshotAtRaw);
19121
- const sourceHash = stringValue5(metadata.sourceContentHash ?? metadata.source_content_hash);
19122
- const latestHash = stringValue5(
19328
+ const sourceHash = stringValue6(metadata.sourceContentHash ?? metadata.source_content_hash);
19329
+ const latestHash = stringValue6(
19123
19330
  metadata.latestSourceContentHash ?? metadata.currentSourceContentHash ?? metadata.manifestSourceContentHash
19124
19331
  );
19125
19332
  if (sourceModifiedAtRaw !== void 0 && !sourceModifiedAt) {
@@ -19673,9 +19880,11 @@ function buildWorkflowAdaptiveRouting(options, policy = null, intentWarnings = [
19673
19880
  allowedEndpointTypes,
19674
19881
  workerRole,
19675
19882
  plannerRetainsReasoning: options.plannerRetainsReasoning ?? policy?.plannerRetainsReasoning ?? (options.routeLocalWorkers ? true : void 0),
19676
- catalogLimit: policy?.catalogLimit ?? DEFAULT_ADAPTIVE_ROUTING_CATALOG_LIMIT
19883
+ catalogLimit: policy?.catalogLimit ?? DEFAULT_ADAPTIVE_ROUTING_CATALOG_LIMIT,
19884
+ dailyBudgetCents: policy?.dailyBudgetCents,
19885
+ monthlyBudgetCents: policy?.monthlyBudgetCents
19677
19886
  });
19678
- const requestedWorkerRole = stringValue5(options.routingWorkerRole);
19887
+ const requestedWorkerRole = stringValue6(options.routingWorkerRole);
19679
19888
  let routing = buildRecommendation(requestedWorkerRole);
19680
19889
  const allowedWorkerClasses = policy?.allowedWorkerClasses ?? [];
19681
19890
  if (allowedWorkerClasses.length > 0 && !isAdaptiveWorkerClassAllowed(routing.requirements.workerRole, allowedWorkerClasses)) {
@@ -19707,12 +19916,12 @@ function buildWorkflowAdaptiveRouting(options, policy = null, intentWarnings = [
19707
19916
  function normalizeRoutingEndpointTypes(values) {
19708
19917
  return Array.from(
19709
19918
  new Set(
19710
- (values ?? []).map((value) => stringValue5(value)?.toLowerCase()).filter((value) => Boolean(value))
19919
+ (values ?? []).map((value) => stringValue6(value)?.toLowerCase()).filter((value) => Boolean(value))
19711
19920
  )
19712
19921
  ).sort();
19713
19922
  }
19714
19923
  function normalizeAdaptiveRoutingMode(value) {
19715
- const normalized = stringValue5(value)?.toLowerCase();
19924
+ const normalized = stringValue6(value)?.toLowerCase();
19716
19925
  return normalized === "off" || normalized === "recommend" || normalized === "catalog" ? normalized : null;
19717
19926
  }
19718
19927
  function normalizeAdaptiveWorkerClasses(values) {
@@ -19739,7 +19948,7 @@ function intersectStrings(left, right) {
19739
19948
  return left.filter((value) => rightSet.has(value));
19740
19949
  }
19741
19950
  function canonicalAdaptiveWorkerClass(value) {
19742
- const normalized = stringValue5(value)?.toLowerCase().replace(/[-\s]/g, "_") ?? "execution";
19951
+ const normalized = stringValue6(value)?.toLowerCase().replace(/[-\s]/g, "_") ?? "execution";
19743
19952
  if (normalized === "docs" || normalized === "doc") {
19744
19953
  return "documentation";
19745
19954
  }
@@ -20197,9 +20406,9 @@ async function workflowRuntimeCheckpointCommand(options) {
20197
20406
  summary: options.summary,
20198
20407
  capturedAt: now,
20199
20408
  automationSessionId: loadConfig().sessionId,
20200
- environment: stringValue5(options.environment) ?? binding.environment,
20201
- profile: stringValue5(options.profile) ?? binding.profile,
20202
- bootstrapQuery: stringValue5(options.bootstrapQuery) ?? binding.bootstrapQuery,
20409
+ environment: stringValue6(options.environment) ?? binding.environment,
20410
+ profile: stringValue6(options.profile) ?? binding.profile,
20411
+ bootstrapQuery: stringValue6(options.bootstrapQuery) ?? binding.bootstrapQuery,
20203
20412
  files: uniqueStringList(options.files) ?? phase.files ?? [],
20204
20413
  commands: uniqueStringList(options.commands) ?? [],
20205
20414
  artifacts: uniqueStringList([...options.artifacts ?? [], ...contextPackArtifacts]) ?? binding.artifacts ?? [],
@@ -21012,7 +21221,7 @@ program.command("verify").description("Build a transparent verification plan fro
21012
21221
  json: Boolean(options.json)
21013
21222
  });
21014
21223
  });
21015
- program.command("run").description("Run the production Project Intelligence judgment flow for a task or release").option("--task <task>", "Current task or change summary").option("--branch <branch>", "Branch to scope continuity signals").option("--changed-files <changedFiles...>", "Changed files to analyze").option("--recent-files <recentFiles...>", "Recently touched files for continuity lookup").option("--diff-summary <diffSummary>", "Natural-language summary for code impact").option("--max-tokens <number>", "Resume context token budget", "4000").option("--release", "Run release-oriented guard and package surface review").option("--skip-impact", "Do not run companion code impact").option("--skip-memory-health", "Do not call snipara_memory_health").option("--skip-guard", "Skip collaboration guard during release runs").option("--skip-package-review", "Skip npm package surface review").option("--json", "Print raw JSON").action(async (options) => {
21224
+ program.command("run").description("Run the production Project Intelligence judgment flow for a task or release").option("--task <task>", "Current task or change summary").option("--branch <branch>", "Branch to scope continuity signals").option("--changed-files <changedFiles...>", "Changed files to analyze").option("--recent-files <recentFiles...>", "Recently touched files for continuity lookup").option("--diff-summary <diffSummary>", "Natural-language summary for code impact").option("--max-tokens <number>", "Resume context token budget", "4000").option("--release", "Run release-oriented guard and package surface review").option("--skip-impact", "Do not run companion code impact").option("--skip-memory-health", "Do not call snipara_memory_health").option("--skip-guard", "Skip collaboration guard during release runs").option("--skip-package-review", "Skip npm package surface review").option("--served-judgment-id <id>", "Served judgment id to use for first-party advisor receipts").option("--skip-advisor-receipts", "Skip first-party advisor influence receipt capture").option("--json", "Print raw JSON").action(async (options) => {
21016
21225
  await projectIntelligenceRunCommand({
21017
21226
  task: options.task,
21018
21227
  branch: options.branch,
@@ -21025,6 +21234,8 @@ program.command("run").description("Run the production Project Intelligence judg
21025
21234
  skipMemoryHealth: Boolean(options.skipMemoryHealth),
21026
21235
  skipGuard: Boolean(options.skipGuard),
21027
21236
  skipPackageReview: Boolean(options.skipPackageReview),
21237
+ servedJudgmentId: options.servedJudgmentId,
21238
+ skipAdvisorReceipts: Boolean(options.skipAdvisorReceipts),
21028
21239
  json: Boolean(options.json)
21029
21240
  });
21030
21241
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snipara-companion",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Snipara Git-style companion CLI for local workflow continuity, hooks, hosted context, and Mini Snipara OSS workflows",
5
5
  "main": "dist/index.js",
6
6
  "bin": {