yapout 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +41 -41
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2471,7 +2471,6 @@ The finding transitions: enriching \u2192 enriched \u2192 ready.`,
2471
2471
  ).optional().describe("Only meaningful Q&A from the conversation \u2014 deviations from expected scope, scoping decisions, etc. Omit if you had no questions."),
2472
2472
  isOversized: z11.boolean().optional().describe("Set to true if this finding is too large for a single PR"),
2473
2473
  suggestedSplit: z11.array(z11.string()).optional().describe("If oversized: suggested sub-finding titles for breaking it down"),
2474
- level: z11.enum(["project", "issue"]).optional().describe("Override the finding's level if enrichment reveals it should be reclassified"),
2475
2474
  nature: z11.enum(["implementable", "operational", "spike"]).optional().describe("Override the finding's nature if enrichment reveals it should be reclassified"),
2476
2475
  sessionId: z11.string().optional().describe("Bulk enrichment session ID (from yapout_start_enrichment). Updates session stats.")
2477
2476
  },
@@ -2488,7 +2487,6 @@ The finding transitions: enriching \u2192 enriched \u2192 ready.`,
2488
2487
  clarifications: args.clarifications,
2489
2488
  isOversized: args.isOversized,
2490
2489
  suggestedSplit: args.suggestedSplit,
2491
- level: args.level,
2492
2490
  nature: args.nature
2493
2491
  }
2494
2492
  );
@@ -2748,11 +2746,11 @@ Mark a finding as NOT ENRICHED (isEnriched: false or omitted) when:
2748
2746
  This is a quality gate. Do not inflate your assessment \u2014 unenriched findings get enriched properly later. Falsely marking something as enriched skips that process and produces bad findings.
2749
2747
 
2750
2748
  PRESENTING THE FINAL PICTURE:
2751
- When the conversation feels complete, present a summary grouped by project:
2749
+ When the conversation feels complete, present a summary grouped by bundles and standalone issues:
2752
2750
 
2753
2751
  "Here's what I've gathered from our conversation:
2754
2752
 
2755
- **[Project Name]** \u2014 [one-line description]
2753
+ **[Bundle Name]** \u2014 [one-line description]
2756
2754
  1. [Child issue] \u2014 enriched \u2713
2757
2755
  2. [Child issue] \u2014 enriched \u2713
2758
2756
  3. [Child issue] \u2014 needs enrichment (we didn't discuss scope)
@@ -2768,7 +2766,7 @@ SUBMITTING:
2768
2766
  On confirmation, call yapout_extract_from_yap with the full data.
2769
2767
 
2770
2768
  For each finding, provide:
2771
- - title, description, sourceQuote, type, priority, confidence, level, nature
2769
+ - title, description, sourceQuote, type, priority, confidence, nature
2772
2770
  - isEnriched: your honest assessment (see above)
2773
2771
 
2774
2772
  For ENRICHED findings (isEnriched: true), also include:
@@ -2777,8 +2775,8 @@ For ENRICHED findings (isEnriched: true), also include:
2777
2775
  - implementationBrief: (optional) technical context \u2014 files, approach, edge cases. Only include if you read the codebase during the session. The implementing agent reads the codebase anyway.
2778
2776
  - clarifications: relevant Q&A from the conversation that shaped the finding
2779
2777
 
2780
- For PROJECT-level findings, also include:
2781
- - projectDescription: what this body of work accomplishes
2778
+ For findings with CHILDREN (bundles), also include:
2779
+ - bundleDescription: what this body of work accomplishes
2782
2780
  - suggestedOrder: implementation sequencing ("Phase 1: A, then Phase 2: B+C")
2783
2781
  - children: array of child issues (each with their own enrichment data)
2784
2782
 
@@ -2786,16 +2784,16 @@ For children with DEPENDENCIES, include:
2786
2784
  - dependsOn: array of sibling indices (0-based) that must complete first
2787
2785
 
2788
2786
  Structure:
2789
- - Projects include children inline \u2014 never create child issues as separate top-level findings
2787
+ - Findings with children become bundles \u2014 never create child issues as separate top-level findings
2790
2788
  - Standalone issues go at the top level
2791
2789
  - The hierarchy you produce should be the final structure
2792
2790
 
2793
2791
  Call yapout_extract_from_yap with:
2794
2792
  - sessionTitle: descriptive title for this session
2795
2793
  - sessionTranscript: clean summary of the conversation (meeting-notes style)
2796
- - findings: the array (projects with children, standalone issues)
2794
+ - findings: the array (bundles with children, standalone issues)
2797
2795
 
2798
- This creates findings (enriched or draft based on your assessment) and project decomposition \u2014 all in one call. Enriched findings appear in the work queue ready for the user to sync to Linear.
2796
+ This creates findings (enriched or draft based on your assessment) and bundles \u2014 all in one call. Enriched findings appear in the work queue ready for the user to sync to Linear.
2799
2797
 
2800
2798
  Only fall back to yapout_submit_yap_session if the session was purely exploratory with no clear actionable findings.
2801
2799
 
@@ -2831,7 +2829,7 @@ var childSchema = z15.object({
2831
2829
  title: z15.string().describe("Child issue title"),
2832
2830
  description: z15.string().describe("What needs to be done and why"),
2833
2831
  sourceQuote: z15.string().describe("Relevant excerpt from the conversation"),
2834
- type: z15.enum(["feature", "bug", "chore"]).describe("Finding category"),
2832
+ type: z15.enum(["feature", "bug", "chore", "spike"]).describe("Finding category"),
2835
2833
  priority: z15.enum(["urgent", "high", "medium", "low"]).describe("Priority level"),
2836
2834
  confidence: z15.number().min(0).max(1).describe("Confidence this is a clear, actionable finding (0-1)"),
2837
2835
  nature: z15.enum(["implementable", "operational", "spike"]).describe("What kind of work"),
@@ -2858,22 +2856,21 @@ function registerExtractFromYapTool(server, ctx) {
2858
2856
  title: z15.string().describe("Finding title"),
2859
2857
  description: z15.string().describe("What needs to be done and why"),
2860
2858
  sourceQuote: z15.string().describe("Relevant excerpt from the conversation"),
2861
- type: z15.enum(["feature", "bug", "chore"]).describe("Finding category (do not use spike \u2014 use nature instead)"),
2859
+ type: z15.enum(["feature", "bug", "chore", "spike"]).describe("Finding category (do not use spike \u2014 use nature instead)"),
2862
2860
  priority: z15.enum(["urgent", "high", "medium", "low"]).describe("Priority level"),
2863
2861
  confidence: z15.number().min(0).max(1).describe("Your confidence this is a clear, actionable finding (0-1)"),
2864
- level: z15.enum(["project", "issue"]).describe("project = body of work with children, issue = single unit"),
2865
2862
  nature: z15.enum(["implementable", "operational", "spike"]).describe("implementable = code changes, operational = manual task, spike = needs scoping"),
2866
2863
  sourceFindingId: z15.string().optional().describe("ID of an existing finding this scopes (e.g., scoping a spike)"),
2867
- // Issue-level enrichment (when level === "issue")
2864
+ // Enrichment data for standalone findings
2868
2865
  isEnriched: z15.boolean().optional().describe("For standalone issues: was this thoroughly discussed? true = enriched, false = draft"),
2869
- enrichedDescription: z15.string().optional().describe("Clean description for Linear (standalone issues only, required if isEnriched)"),
2870
- acceptanceCriteria: z15.array(z15.string()).optional().describe("Testable acceptance criteria (standalone issues only, required if isEnriched)"),
2871
- implementationBrief: z15.string().optional().describe("Technical context (standalone issues only, optional)"),
2872
- clarifications: z15.array(clarificationSchema).optional().describe("Relevant Q&A from conversation (standalone issues only)"),
2873
- // Project-level fields (when level === "project")
2874
- projectDescription: z15.string().optional().describe("What this body of work accomplishes (projects only)"),
2875
- suggestedOrder: z15.string().optional().describe("Implementation order: 'Phase 1: A, then Phase 2: B+C' (projects only)"),
2876
- children: z15.array(childSchema).optional().describe("Child issues for project-level decisions")
2866
+ enrichedDescription: z15.string().optional().describe("Clean description for Linear (required if isEnriched)"),
2867
+ acceptanceCriteria: z15.array(z15.string()).optional().describe("Testable acceptance criteria (required if isEnriched)"),
2868
+ implementationBrief: z15.string().optional().describe("Technical context (optional)"),
2869
+ clarifications: z15.array(clarificationSchema).optional().describe("Relevant Q&A from conversation"),
2870
+ // Bundle fields when a finding has children, a bundle is created
2871
+ bundleDescription: z15.string().optional().describe("What this body of work accomplishes (only for findings with children)"),
2872
+ suggestedOrder: z15.string().optional().describe("Implementation order: 'Phase 1: A, then Phase 2: B+C' (only for findings with children)"),
2873
+ children: z15.array(childSchema).optional().describe("Child issues \u2014 when present, a bundle is created from this finding")
2877
2874
  })
2878
2875
  ).describe("Findings from the conversation. Projects include children inline.")
2879
2876
  },
@@ -2903,8 +2900,8 @@ function registerExtractFromYapTool(server, ctx) {
2903
2900
  let draftCount = 0;
2904
2901
  let totalFindings = 0;
2905
2902
  for (const item of result.items) {
2906
- if (item.level === "project") {
2907
- for (const child of item.children ?? []) {
2903
+ if (item.children && item.children.length > 0) {
2904
+ for (const child of item.children) {
2908
2905
  totalFindings++;
2909
2906
  if (child.findingStatus === "enriched") enrichedCount++;
2910
2907
  else draftCount++;
@@ -2954,35 +2951,36 @@ function registerExtractFromYapTool(server, ctx) {
2954
2951
  );
2955
2952
  }
2956
2953
 
2957
- // src/mcp/tools/save-project-enrichment.ts
2954
+ // src/mcp/tools/decompose-finding.ts
2958
2955
  import { z as z16 } from "zod";
2959
- function registerSaveProjectEnrichmentTool(server, ctx) {
2956
+ function registerDecomposeFindingTool(server, ctx) {
2960
2957
  server.tool(
2961
- "yapout_save_project_enrichment",
2962
- `Save the decomposition of a project-level finding into implementable child issues.
2958
+ "yapout_decompose_finding",
2959
+ `Decompose a finding into a bundle with child issues.
2963
2960
 
2964
- Call this after enriching a finding with level: "project". The agent should have:
2961
+ Call this when enrichment reveals a finding is too large for a single PR.
2962
+ The agent should have:
2965
2963
  1. Read the codebase extensively
2966
2964
  2. Asked the user scoping questions
2967
2965
  3. Produced a set of child issues with dependencies
2968
2966
 
2969
- This tool creates child findings in yapout, transitions the original
2970
- finding to "decomposed", and returns the child finding IDs for subsequent Linear sync.
2967
+ This tool creates a bundle in yapout, assigns child findings to it, and
2968
+ archives the original finding. Returns the bundle ID and child finding IDs.
2971
2969
 
2972
2970
  Each child issue's implementation brief must be detailed enough to stand alone as a
2973
2971
  full spec \u2014 schema changes, files to modify, edge cases, and acceptance criteria.`,
2974
2972
  {
2975
- findingId: z16.string().describe("The project-level finding being decomposed (from yapout_get_unenriched_finding)"),
2976
- projectDescription: z16.string().describe("Description for the project \u2014 what this body of work accomplishes"),
2973
+ findingId: z16.string().describe("The finding being decomposed (from yapout_get_unenriched_finding)"),
2974
+ bundleDescription: z16.string().describe("Description for the bundle \u2014 what this body of work accomplishes"),
2977
2975
  suggestedOrder: z16.string().describe("Human-readable implementation order (e.g. 'Phase 1: A, then Phase 2: B+C in parallel, then Phase 3: D')"),
2978
- linearProjectId: z16.string().optional().describe("Existing Linear project ID to associate child issues with. Omit to skip Linear project association \u2014 issues will be synced without a project."),
2976
+ linearProjectId: z16.string().optional().describe("Existing Linear project ID to associate with. Omit to skip Linear project association."),
2979
2977
  issues: z16.array(
2980
2978
  z16.object({
2981
2979
  title: z16.string().describe("Child issue title"),
2982
2980
  description: z16.string().describe("What needs to be done and why"),
2983
2981
  acceptanceCriteria: z16.array(z16.string()).describe("Testable acceptance criteria"),
2984
2982
  implementationBrief: z16.string().describe("Full spec: files to modify, schema changes, edge cases, approach"),
2985
- type: z16.enum(["feature", "bug", "chore"]).describe("Category of work"),
2983
+ type: z16.enum(["feature", "bug", "chore", "spike"]).describe("Category of work"),
2986
2984
  priority: z16.enum(["urgent", "high", "medium", "low"]).describe("Priority level"),
2987
2985
  dependsOn: z16.array(z16.number()).describe("Indices (0-based) of issues in this array that must be completed first")
2988
2986
  })
@@ -3002,10 +3000,10 @@ full spec \u2014 schema changes, files to modify, edge cases, and acceptance cri
3002
3000
  }
3003
3001
  try {
3004
3002
  const result = await ctx.client.mutation(
3005
- anyApi2.functions.localPipeline.saveProjectEnrichment,
3003
+ anyApi2.functions.localPipeline.decomposeIntoBundle,
3006
3004
  {
3007
3005
  findingId: args.findingId,
3008
- projectDescription: args.projectDescription,
3006
+ bundleDescription: args.bundleDescription,
3009
3007
  suggestedOrder: args.suggestedOrder,
3010
3008
  linearProjectId: args.linearProjectId,
3011
3009
  issues: args.issues
@@ -3018,10 +3016,12 @@ full spec \u2014 schema changes, files to modify, edge cases, and acceptance cri
3018
3016
  text: JSON.stringify(
3019
3017
  {
3020
3018
  findingId: result.findingId,
3021
- status: "decomposed",
3019
+ bundleId: result.bundleId,
3020
+ status: "archived",
3021
+ archivedReason: "decomposed",
3022
3022
  childFindingIds: result.childFindingIds,
3023
3023
  suggestedOrder: result.suggestedOrder,
3024
- message: `Project decomposed into ${result.childFindingIds.length} child issues. Original finding marked as decomposed. Child findings are in draft status \u2014 enrich and sync each one individually, or approve them for the user to review.`
3024
+ message: `Finding decomposed into bundle with ${result.childFindingIds.length} child issues. Original finding archived. Child findings are in draft status \u2014 enrich and sync each one individually, or approve them for the user to review.`
3025
3025
  },
3026
3026
  null,
3027
3027
  2
@@ -3034,7 +3034,7 @@ full spec \u2014 schema changes, files to modify, edge cases, and acceptance cri
3034
3034
  content: [
3035
3035
  {
3036
3036
  type: "text",
3037
- text: `Error saving project enrichment: ${err.message}`
3037
+ text: `Error decomposing finding: ${err.message}`
3038
3038
  }
3039
3039
  ],
3040
3040
  isError: true
@@ -3561,7 +3561,7 @@ async function startMcpServer() {
3561
3561
  registerSubmitYapSessionTool(server, ctx);
3562
3562
  registerStartYapTool(server, ctx);
3563
3563
  registerExtractFromYapTool(server, ctx);
3564
- registerSaveProjectEnrichmentTool(server, ctx);
3564
+ registerDecomposeFindingTool(server, ctx);
3565
3565
  registerMarkDuplicateTool(server, ctx);
3566
3566
  registerGetLinearProjectsTool(server, ctx);
3567
3567
  registerStartEnrichmentTool(server, ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yapout",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "yapout CLI — link local repos, authenticate, and manage projects",
5
5
  "type": "module",
6
6
  "bin": {