dominds 1.2.5 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/agent-priming.js +2051 -0
  2. package/dist/apps/app-lock-file.js +228 -0
  3. package/dist/apps/assigned-port.js +124 -0
  4. package/dist/apps/enabled-apps.js +472 -7
  5. package/dist/apps/manifest.js +37 -0
  6. package/dist/apps/override-paths.js +19 -6
  7. package/dist/apps/problems.js +43 -0
  8. package/dist/apps/resolution-file.js +370 -0
  9. package/dist/apps/runtime.js +5 -17
  10. package/dist/apps/teammates.js +102 -1
  11. package/dist/cli/disable.js +10 -6
  12. package/dist/cli/enable.js +21 -19
  13. package/dist/cli/install.js +40 -18
  14. package/dist/cli/uninstall.js +6 -6
  15. package/dist/cli/update.js +38 -13
  16. package/dist/dialog.js +5 -0
  17. package/dist/docs/app-constitution.md +85 -18
  18. package/dist/docs/app-constitution.zh.md +86 -21
  19. package/dist/docs/dialog-system.md +1 -1
  20. package/dist/docs/dialog-system.zh.md +1 -1
  21. package/dist/docs/dominds-agent-priming.md +218 -0
  22. package/dist/docs/dominds-agent-priming.zh.md +196 -0
  23. package/dist/docs/drive-logic-context-refactor-plan.zh.md +338 -0
  24. package/dist/docs/keep-going.md +176 -0
  25. package/dist/docs/keep-going.zh.md +162 -0
  26. package/dist/docs/showing-by-doing.md +208 -0
  27. package/dist/docs/showing-by-doing.zh.md +177 -0
  28. package/dist/docs/team-mgmt-toolset.md +482 -0
  29. package/dist/docs/team-mgmt-toolset.zh.md +426 -0
  30. package/dist/llm/defaults.yaml +1 -1
  31. package/dist/llm/driver.js +4093 -0
  32. package/dist/llm/kernel-driver/drive.js +5 -2
  33. package/dist/llm/kernel-driver/flow.js +3 -0
  34. package/dist/minds/promptdocs.js +263 -0
  35. package/dist/problems.js +67 -16
  36. package/dist/server/api-routes.js +333 -0
  37. package/dist/server/prompts-routes.js +545 -0
  38. package/dist/server/server-core.js +4 -0
  39. package/dist/server/websocket-handler.js +17 -0
  40. package/dist/shared/team-mgmt-manual.js +120 -0
  41. package/dist/shared/types/prompts.js +2 -0
  42. package/dist/shared/types/tellask.js +8 -0
  43. package/dist/showing-by-doing.js +1091 -0
  44. package/dist/snippets/README.en.md +3 -0
  45. package/dist/snippets/README.md +4 -0
  46. package/dist/static/assets/{_basePickBy-CF9r08iy.js → _basePickBy-BMCtwrV7.js} +3 -3
  47. package/dist/static/assets/{_basePickBy-CF9r08iy.js.map → _basePickBy-BMCtwrV7.js.map} +1 -1
  48. package/dist/static/assets/{_baseUniq-CxKv0cd4.js → _baseUniq-BuyCgJiA.js} +2 -2
  49. package/dist/static/assets/{_baseUniq-CxKv0cd4.js.map → _baseUniq-BuyCgJiA.js.map} +1 -1
  50. package/dist/static/assets/{arc-C9JyvnlB.js → arc-BDuN8lwA.js} +2 -2
  51. package/dist/static/assets/{arc-C9JyvnlB.js.map → arc-BDuN8lwA.js.map} +1 -1
  52. package/dist/static/assets/{architectureDiagram-VXUJARFQ-CpcUgjHf.js → architectureDiagram-VXUJARFQ-C-ekqGAD.js} +7 -7
  53. package/dist/static/assets/{architectureDiagram-VXUJARFQ-CpcUgjHf.js.map → architectureDiagram-VXUJARFQ-C-ekqGAD.js.map} +1 -1
  54. package/dist/static/assets/{blockDiagram-VD42YOAC-BA9vtmm7.js → blockDiagram-VD42YOAC-CgQiNuuQ.js} +7 -7
  55. package/dist/static/assets/{blockDiagram-VD42YOAC-BA9vtmm7.js.map → blockDiagram-VD42YOAC-CgQiNuuQ.js.map} +1 -1
  56. package/dist/static/assets/{c4Diagram-YG6GDRKO-D49MGNdF.js → c4Diagram-YG6GDRKO-DONC39q-.js} +3 -3
  57. package/dist/static/assets/{c4Diagram-YG6GDRKO-D49MGNdF.js.map → c4Diagram-YG6GDRKO-DONC39q-.js.map} +1 -1
  58. package/dist/static/assets/{channel-B4KzL0Kg.js → channel-CJTFwXIG.js} +2 -2
  59. package/dist/static/assets/{channel-B4KzL0Kg.js.map → channel-CJTFwXIG.js.map} +1 -1
  60. package/dist/static/assets/{chunk-4BX2VUAB-0F-1ayl0.js → chunk-4BX2VUAB-NaIy4uLJ.js} +2 -2
  61. package/dist/static/assets/{chunk-4BX2VUAB-0F-1ayl0.js.map → chunk-4BX2VUAB-NaIy4uLJ.js.map} +1 -1
  62. package/dist/static/assets/{chunk-55IACEB6-Dnl2HDTZ.js → chunk-55IACEB6-JUKI_Ayx.js} +2 -2
  63. package/dist/static/assets/{chunk-55IACEB6-Dnl2HDTZ.js.map → chunk-55IACEB6-JUKI_Ayx.js.map} +1 -1
  64. package/dist/static/assets/{chunk-B4BG7PRW-Bhx5RbkQ.js → chunk-B4BG7PRW-dIswFJDn.js} +5 -5
  65. package/dist/static/assets/{chunk-B4BG7PRW-Bhx5RbkQ.js.map → chunk-B4BG7PRW-dIswFJDn.js.map} +1 -1
  66. package/dist/static/assets/{chunk-DI55MBZ5-EYd1wL3E.js → chunk-DI55MBZ5-DU2b_N30.js} +4 -4
  67. package/dist/static/assets/{chunk-DI55MBZ5-EYd1wL3E.js.map → chunk-DI55MBZ5-DU2b_N30.js.map} +1 -1
  68. package/dist/static/assets/{chunk-FMBD7UC4-DAjkhhUU.js → chunk-FMBD7UC4-BgExcScw.js} +2 -2
  69. package/dist/static/assets/{chunk-FMBD7UC4-DAjkhhUU.js.map → chunk-FMBD7UC4-BgExcScw.js.map} +1 -1
  70. package/dist/static/assets/{chunk-QN33PNHL-CK6TY7IE.js → chunk-QN33PNHL-bitxyqh7.js} +2 -2
  71. package/dist/static/assets/{chunk-QN33PNHL-CK6TY7IE.js.map → chunk-QN33PNHL-bitxyqh7.js.map} +1 -1
  72. package/dist/static/assets/{chunk-QZHKN3VN-CketngiE.js → chunk-QZHKN3VN-Cor8u7DT.js} +2 -2
  73. package/dist/static/assets/{chunk-QZHKN3VN-CketngiE.js.map → chunk-QZHKN3VN-Cor8u7DT.js.map} +1 -1
  74. package/dist/static/assets/{chunk-TZMSLE5B-Bcuvqo45.js → chunk-TZMSLE5B-Aceoxav_.js} +2 -2
  75. package/dist/static/assets/{chunk-TZMSLE5B-Bcuvqo45.js.map → chunk-TZMSLE5B-Aceoxav_.js.map} +1 -1
  76. package/dist/static/assets/{classDiagram-2ON5EDUG-CaP4T3r4.js → classDiagram-2ON5EDUG-D1Q6a8Hg.js} +6 -6
  77. package/dist/static/assets/{classDiagram-2ON5EDUG-CaP4T3r4.js.map → classDiagram-2ON5EDUG-D1Q6a8Hg.js.map} +1 -1
  78. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-CaP4T3r4.js → classDiagram-v2-WZHVMYZB-D1Q6a8Hg.js} +6 -6
  79. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-CaP4T3r4.js.map → classDiagram-v2-WZHVMYZB-D1Q6a8Hg.js.map} +1 -1
  80. package/dist/static/assets/{clone-C-JULvnG.js → clone-MlWbv1V0.js} +2 -2
  81. package/dist/static/assets/{clone-C-JULvnG.js.map → clone-MlWbv1V0.js.map} +1 -1
  82. package/dist/static/assets/{cose-bilkent-S5V4N54A-vXCmi_eC.js → cose-bilkent-S5V4N54A-DWPCXSrn.js} +2 -2
  83. package/dist/static/assets/{cose-bilkent-S5V4N54A-vXCmi_eC.js.map → cose-bilkent-S5V4N54A-DWPCXSrn.js.map} +1 -1
  84. package/dist/static/assets/{dagre-6UL2VRFP-bhGzX6kO.js → dagre-6UL2VRFP-C8ptQ9V3.js} +7 -7
  85. package/dist/static/assets/{dagre-6UL2VRFP-bhGzX6kO.js.map → dagre-6UL2VRFP-C8ptQ9V3.js.map} +1 -1
  86. package/dist/static/assets/{diagram-PSM6KHXK-BUKfmfGk.js → diagram-PSM6KHXK-Bgf1FqkE.js} +8 -8
  87. package/dist/static/assets/{diagram-PSM6KHXK-BUKfmfGk.js.map → diagram-PSM6KHXK-Bgf1FqkE.js.map} +1 -1
  88. package/dist/static/assets/{diagram-QEK2KX5R-DYlq3uFq.js → diagram-QEK2KX5R-BZ5xzofU.js} +7 -7
  89. package/dist/static/assets/{diagram-QEK2KX5R-DYlq3uFq.js.map → diagram-QEK2KX5R-BZ5xzofU.js.map} +1 -1
  90. package/dist/static/assets/{diagram-S2PKOQOG-CjxkLHWG.js → diagram-S2PKOQOG-Dwp47T9I.js} +7 -7
  91. package/dist/static/assets/{diagram-S2PKOQOG-CjxkLHWG.js.map → diagram-S2PKOQOG-Dwp47T9I.js.map} +1 -1
  92. package/dist/static/assets/{erDiagram-Q2GNP2WA-S3hR85On.js → erDiagram-Q2GNP2WA-Cx4weIHl.js} +5 -5
  93. package/dist/static/assets/{erDiagram-Q2GNP2WA-S3hR85On.js.map → erDiagram-Q2GNP2WA-Cx4weIHl.js.map} +1 -1
  94. package/dist/static/assets/{flowDiagram-NV44I4VS-aBmNMuQ0.js → flowDiagram-NV44I4VS-vNUuIeRk.js} +6 -6
  95. package/dist/static/assets/{flowDiagram-NV44I4VS-aBmNMuQ0.js.map → flowDiagram-NV44I4VS-vNUuIeRk.js.map} +1 -1
  96. package/dist/static/assets/{ganttDiagram-JELNMOA3-DJxXaiW1.js → ganttDiagram-JELNMOA3-BEfozJAr.js} +3 -3
  97. package/dist/static/assets/{ganttDiagram-JELNMOA3-DJxXaiW1.js.map → ganttDiagram-JELNMOA3-BEfozJAr.js.map} +1 -1
  98. package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-DEOBCM0G.js → gitGraphDiagram-V2S2FVAM-eHxwc3d9.js} +8 -8
  99. package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-DEOBCM0G.js.map → gitGraphDiagram-V2S2FVAM-eHxwc3d9.js.map} +1 -1
  100. package/dist/static/assets/{graph-DwrKSIE7.js → graph-C6a6uAok.js} +3 -3
  101. package/dist/static/assets/{graph-DwrKSIE7.js.map → graph-C6a6uAok.js.map} +1 -1
  102. package/dist/static/assets/{index-HWTRvE2k.js → index-D3TQbAKh.js} +383 -59
  103. package/dist/static/assets/index-D3TQbAKh.js.map +1 -0
  104. package/dist/static/assets/{infoDiagram-HS3SLOUP-BH9kVuYd.js → infoDiagram-HS3SLOUP-CX0NiId3.js} +6 -6
  105. package/dist/static/assets/{infoDiagram-HS3SLOUP-BH9kVuYd.js.map → infoDiagram-HS3SLOUP-CX0NiId3.js.map} +1 -1
  106. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-Dap7AcjR.js → journeyDiagram-XKPGCS4Q-C1IepPZ-.js} +5 -5
  107. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-Dap7AcjR.js.map → journeyDiagram-XKPGCS4Q-C1IepPZ-.js.map} +1 -1
  108. package/dist/static/assets/{kanban-definition-3W4ZIXB7-4NOl8MEj.js → kanban-definition-3W4ZIXB7-uMNX4Z1W.js} +3 -3
  109. package/dist/static/assets/{kanban-definition-3W4ZIXB7-4NOl8MEj.js.map → kanban-definition-3W4ZIXB7-uMNX4Z1W.js.map} +1 -1
  110. package/dist/static/assets/{layout-D6uIxu1E.js → layout-CpE3kk5z.js} +5 -5
  111. package/dist/static/assets/{layout-D6uIxu1E.js.map → layout-CpE3kk5z.js.map} +1 -1
  112. package/dist/static/assets/{linear-CvBOGQA2.js → linear-DV8laXr9.js} +2 -2
  113. package/dist/static/assets/{linear-CvBOGQA2.js.map → linear-DV8laXr9.js.map} +1 -1
  114. package/dist/static/assets/{mindmap-definition-VGOIOE7T-ugsrLNY5.js → mindmap-definition-VGOIOE7T-CKjgVM9S.js} +4 -4
  115. package/dist/static/assets/{mindmap-definition-VGOIOE7T-ugsrLNY5.js.map → mindmap-definition-VGOIOE7T-CKjgVM9S.js.map} +1 -1
  116. package/dist/static/assets/{pieDiagram-ADFJNKIX-CdVZjM8g.js → pieDiagram-ADFJNKIX-BBonlNyT.js} +8 -8
  117. package/dist/static/assets/{pieDiagram-ADFJNKIX-CdVZjM8g.js.map → pieDiagram-ADFJNKIX-BBonlNyT.js.map} +1 -1
  118. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-A6m5lZKd.js → quadrantDiagram-AYHSOK5B-BTI8HbBu.js} +3 -3
  119. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-A6m5lZKd.js.map → quadrantDiagram-AYHSOK5B-BTI8HbBu.js.map} +1 -1
  120. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-Cac3zSJH.js → requirementDiagram-UZGBJVZJ-ZtSr9Q5R.js} +4 -4
  121. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-Cac3zSJH.js.map → requirementDiagram-UZGBJVZJ-ZtSr9Q5R.js.map} +1 -1
  122. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DXDdUUl1.js → sankeyDiagram-TZEHDZUN-DibLVGzg.js} +2 -2
  123. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DXDdUUl1.js.map → sankeyDiagram-TZEHDZUN-DibLVGzg.js.map} +1 -1
  124. package/dist/static/assets/{sequenceDiagram-WL72ISMW-Domsjl5Y.js → sequenceDiagram-WL72ISMW-qXatfzVt.js} +4 -4
  125. package/dist/static/assets/{sequenceDiagram-WL72ISMW-Domsjl5Y.js.map → sequenceDiagram-WL72ISMW-qXatfzVt.js.map} +1 -1
  126. package/dist/static/assets/{stateDiagram-FKZM4ZOC-Bu0lRQK1.js → stateDiagram-FKZM4ZOC-7fgxCQHo.js} +9 -9
  127. package/dist/static/assets/{stateDiagram-FKZM4ZOC-Bu0lRQK1.js.map → stateDiagram-FKZM4ZOC-7fgxCQHo.js.map} +1 -1
  128. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-D0K-n3ic.js → stateDiagram-v2-4FDKWEC3-DcWlOAnF.js} +5 -5
  129. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-D0K-n3ic.js.map → stateDiagram-v2-4FDKWEC3-DcWlOAnF.js.map} +1 -1
  130. package/dist/static/assets/{timeline-definition-IT6M3QCI-BGvpddwR.js → timeline-definition-IT6M3QCI-iX2MRdpY.js} +3 -3
  131. package/dist/static/assets/{timeline-definition-IT6M3QCI-BGvpddwR.js.map → timeline-definition-IT6M3QCI-iX2MRdpY.js.map} +1 -1
  132. package/dist/static/assets/{treemap-GDKQZRPO-BoOzOm2j.js → treemap-GDKQZRPO-AVRnyXu1.js} +5 -5
  133. package/dist/static/assets/{treemap-GDKQZRPO-BoOzOm2j.js.map → treemap-GDKQZRPO-AVRnyXu1.js.map} +1 -1
  134. package/dist/static/assets/{xychartDiagram-PRI3JC2R-C_h3_ICR.js → xychartDiagram-PRI3JC2R-DVYEo5aJ.js} +3 -3
  135. package/dist/static/assets/{xychartDiagram-PRI3JC2R-C_h3_ICR.js.map → xychartDiagram-PRI3JC2R-DVYEo5aJ.js.map} +1 -1
  136. package/dist/static/index.html +1 -1
  137. package/dist/team.js +52 -48
  138. package/dist/tellask.js +439 -0
  139. package/dist/tools/context-health.js +177 -0
  140. package/dist/tools/diag.js +583 -0
  141. package/dist/tools/fs.js +194 -68
  142. package/dist/tools/prompts/memory/en/principles.md +13 -5
  143. package/dist/tools/prompts/memory/en/tools.md +11 -36
  144. package/dist/tools/prompts/memory/zh/principles.md +18 -8
  145. package/dist/tools/prompts/memory/zh/tools.md +11 -36
  146. package/dist/tools/team-mgmt.js +3487 -0
  147. package/dist/utils/task-doc.js +236 -0
  148. package/package.json +1 -1
  149. package/dist/static/assets/index-HWTRvE2k.js.map +0 -1
@@ -52,7 +52,7 @@
52
52
  padding: 20px;
53
53
  }
54
54
  </style>
55
- <script type="module" crossorigin src="/assets/index-HWTRvE2k.js"></script>
55
+ <script type="module" crossorigin src="/assets/index-D3TQbAKh.js"></script>
56
56
  <link rel="stylesheet" crossorigin href="/assets/index-BiNcBn_U.css">
57
57
  </head>
58
58
  <body>
package/dist/team.js CHANGED
@@ -699,38 +699,14 @@ exports.Team = Team;
699
699
  finalizeProblems();
700
700
  return team;
701
701
  }
702
- // Apps: merge enabled app teammate definitions (additive).
702
+ let appTeammates = [];
703
703
  try {
704
- const appTeammates = await (0, teammates_1.loadEnabledAppTeammates)({ rtwsRootAbs: process.cwd() });
705
- if (appTeammates.length > 0) {
706
- if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
707
- addIssue('apps/teammates/invalid_base', 'Failed to merge app teammates into .minds/team.yaml: base YAML is not an object.', `Expected .minds/team.yaml to parse into an object before applying app teammate merges.`);
708
- }
709
- else {
710
- const rec = parsed;
711
- const membersRaw = rec['members'];
712
- const members = typeof membersRaw === 'object' && membersRaw !== null && !Array.isArray(membersRaw)
713
- ? membersRaw
714
- : {};
715
- if (rec['members'] === undefined) {
716
- rec['members'] = members;
717
- }
718
- for (const snip of appTeammates) {
719
- for (const [id, member] of Object.entries(snip.members)) {
720
- if (Object.prototype.hasOwnProperty.call(members, id)) {
721
- addIssue(`apps/teammates/duplicate_member/${sanitizeProblemIdSegment(id)}`, 'App teammate id collision while loading .minds/team.yaml.', `Enabled app '${snip.appId}' contributes member id '${id}', but it already exists in team.yaml (or another app). Disable/uninstall the conflicting app or rename the member id.`);
722
- continue;
723
- }
724
- members[id] = member;
725
- }
726
- }
727
- }
728
- }
704
+ appTeammates = await (0, teammates_1.loadEnabledAppTeammates)({ rtwsRootAbs: process.cwd() });
729
705
  }
730
706
  catch (err) {
731
707
  addIssue('apps/teammates/load', 'Failed to load enabled app teammates.', err instanceof Error ? err.message : String(err));
732
708
  }
733
- const parsedTeam = parseTeamYamlObject(parsed, md, { fuxi, pangu });
709
+ const parsedTeam = parseTeamYamlObject(parsed, md, { fuxi, pangu }, { appTeammates });
734
710
  for (const issue of parsedTeam.issues) {
735
711
  addIssue(issue.id, issue.message, issue.errorText);
736
712
  }
@@ -1306,11 +1282,15 @@ exports.Team = Team;
1306
1282
  if (overrides.hidden !== undefined)
1307
1283
  member.setHidden(overrides.hidden);
1308
1284
  }
1309
- function parseTeamYamlObject(obj, md, shadow) {
1285
+ function parseTeamYamlObject(obj, md, shadow, deps) {
1310
1286
  const issues = [];
1311
1287
  const pushIssue = (id, message, errorText) => {
1312
1288
  issues.push({ id, message, errorText });
1313
1289
  };
1290
+ const appMembersByAppId = new Map();
1291
+ for (const snip of deps.appTeammates) {
1292
+ appMembersByAppId.set(snip.appId, snip.members);
1293
+ }
1314
1294
  const teamObj = (() => {
1315
1295
  if (isRecordValue(obj))
1316
1296
  return obj;
@@ -1394,9 +1374,9 @@ exports.Team = Team;
1394
1374
  pushIssue(`members/${idSeg}`, `Invalid .minds/team.yaml: ${memberAt} must be an object.`, `Invalid ${memberAt}: expected an object (got ${describeValueType(raw)})`);
1395
1375
  continue;
1396
1376
  }
1397
- // Cross-app teammate reference (draft): members.<id>.from + (use|import).
1398
- // v0 behavior: fail-open, only surface Problems; runtime still treats the member as local.
1399
- {
1377
+ // Cross-app teammate reference (v0): members.<id>.from + (use|import).
1378
+ // Fail-open: surface Problems, but keep Team usable.
1379
+ const effectiveRaw = (() => {
1400
1380
  const memberObj = raw;
1401
1381
  const hasFrom = hasOwnKey(memberObj, 'from');
1402
1382
  const hasUse = hasOwnKey(memberObj, 'use');
@@ -1405,34 +1385,58 @@ exports.Team = Team;
1405
1385
  const useRaw = hasUse ? memberObj['use'] : undefined;
1406
1386
  const importRaw = hasImport ? memberObj['import'] : undefined;
1407
1387
  // Problem id should stay short and stable: it is a UI address, not a stack trace.
1408
- // During the transition, team definitions can come from multiple scopes (rtws/kernel/apps).
1409
- // This validator currently runs on the effective rtws `.minds/team.yaml` object.
1388
+ // This validator runs on the effective rtws `.minds/team.yaml` object.
1410
1389
  const definingScopeSeg = 'rtws';
1411
1390
  const memberPrefix = `members/${definingScopeSeg}/${idSeg}`;
1412
1391
  if (hasUse && hasImport) {
1413
1392
  pushIssue(`${memberPrefix}/use_and_import_conflict`, `Invalid .minds/team.yaml: ${memberAt} cannot specify both 'use' and 'import'.`, `Both ${memberAt}.use and ${memberAt}.import are present; remove one.`);
1393
+ return memberObj;
1414
1394
  }
1415
1395
  if ((hasUse || hasImport) && !hasFrom) {
1416
1396
  pushIssue(`${memberPrefix}/from/missing`, `Invalid .minds/team.yaml: ${memberAt} uses cross-app member reference but is missing 'from'.`, `Either remove ${memberAt}.use/${memberAt}.import, or add ${memberAt}.from: <dep-app-id>.`);
1397
+ return memberObj;
1417
1398
  }
1418
- if (hasFrom) {
1419
- if (typeof fromRaw !== 'string' || fromRaw.trim() === '') {
1420
- pushIssue(`${memberPrefix}/from/invalid`, `Invalid .minds/team.yaml: ${memberAt}.from must be a non-empty string.`, `Invalid ${memberAt}.from: expected non-empty string (got ${describeValueType(fromRaw)})`);
1421
- }
1399
+ if (!hasFrom)
1400
+ return memberObj;
1401
+ if (typeof fromRaw !== 'string' || fromRaw.trim() === '') {
1402
+ pushIssue(`${memberPrefix}/from/invalid`, `Invalid .minds/team.yaml: ${memberAt}.from must be a non-empty string.`, `Invalid ${memberAt}.from: expected non-empty string (got ${describeValueType(fromRaw)})`);
1403
+ return memberObj;
1422
1404
  }
1423
- if (hasUse) {
1424
- if (typeof useRaw !== 'string' || useRaw.trim() === '') {
1425
- pushIssue(`${memberPrefix}/use/invalid`, `Invalid .minds/team.yaml: ${memberAt}.use must be a non-empty string.`, `Invalid ${memberAt}.use: expected non-empty string (got ${describeValueType(useRaw)})`);
1426
- }
1405
+ // `from`-only is accepted (v0 no-op): treat it as a local member definition.
1406
+ if (!hasUse && !hasImport)
1407
+ return memberObj;
1408
+ const refKind = hasUse ? 'use' : 'import';
1409
+ const refRaw = hasUse ? useRaw : importRaw;
1410
+ if (typeof refRaw !== 'string' || refRaw.trim() === '') {
1411
+ pushIssue(`${memberPrefix}/${refKind}/invalid`, `Invalid .minds/team.yaml: ${memberAt}.${refKind} must be a non-empty string.`, `Invalid ${memberAt}.${refKind}: expected non-empty string (got ${describeValueType(refRaw)})`);
1412
+ return memberObj;
1427
1413
  }
1428
- if (hasImport) {
1429
- if (typeof importRaw !== 'string' || importRaw.trim() === '') {
1430
- pushIssue(`${memberPrefix}/import/invalid`, `Invalid .minds/team.yaml: ${memberAt}.import must be a non-empty string.`, `Invalid ${memberAt}.import: expected non-empty string (got ${describeValueType(importRaw)})`);
1431
- }
1414
+ const fromAppId = fromRaw.trim();
1415
+ const refMemberId = refRaw.trim();
1416
+ const appMembers = appMembersByAppId.get(fromAppId);
1417
+ if (!appMembers) {
1418
+ pushIssue(`${memberPrefix}/from/unresolved_app`, `Invalid .minds/team.yaml: ${memberAt}.from refers to an app that is not enabled.`, `App '${fromAppId}' is not enabled (or does not export teammates YAML).`);
1419
+ return memberObj;
1432
1420
  }
1433
- }
1434
- validateCommonModelParamMisplacements(pushIssue, `members/${idSeg}`, memberAt, raw);
1435
- const parsedMember = parseMemberOverrides(raw, memberAt);
1421
+ const sourceRaw = appMembers[refMemberId];
1422
+ if (sourceRaw === undefined) {
1423
+ pushIssue(`${memberPrefix}/${refKind}/unresolved_member`, `Invalid .minds/team.yaml: ${memberAt}.${refKind} refers to a missing member in app '${fromAppId}'.`, `App '${fromAppId}' does not export member id '${refMemberId}'.`);
1424
+ return memberObj;
1425
+ }
1426
+ if (!isRecordValue(sourceRaw)) {
1427
+ pushIssue(`${memberPrefix}/${refKind}/invalid_member`, `Invalid app teammates YAML: member '${refMemberId}' must be an object (app '${fromAppId}').`, `Expected app member '${fromAppId}.${refMemberId}' to be an object (got ${describeValueType(sourceRaw)}).`);
1428
+ return memberObj;
1429
+ }
1430
+ const merged = { ...sourceRaw };
1431
+ for (const [k, v] of Object.entries(memberObj)) {
1432
+ if (k === 'from' || k === 'use' || k === 'import')
1433
+ continue;
1434
+ merged[k] = v;
1435
+ }
1436
+ return merged;
1437
+ })();
1438
+ validateCommonModelParamMisplacements(pushIssue, `members/${idSeg}`, memberAt, effectiveRaw);
1439
+ const parsedMember = parseMemberOverrides(effectiveRaw, memberAt);
1436
1440
  if (parsedMember.kind === 'error') {
1437
1441
  pushIssue(`members/${idSeg}`, `Invalid .minds/team.yaml: ${memberAt} has invalid fields.`, parsedMember.errorTexts.join('\n'));
1438
1442
  if (id === 'fuxi' || id === 'pangu') {
@@ -0,0 +1,439 @@
1
+ "use strict";
2
+ /**
3
+ * # Tellask Grammar ("诉请")
4
+ *
5
+ * A primitive, line-based streaming call format designed to be robust under arbitrary
6
+ * upstream chunk boundaries (no backtick/markdown state machine required).
7
+ *
8
+ * ## Rules
9
+ *
10
+ * - Tellask call blocks consist of **lines**.
11
+ * - Any line starting with literal `!?` is a tellask line (prefix is not included in payload).
12
+ * - Any line(s) **without** `!?` prefix are treated as markdown, and also act as separators:
13
+ * they terminate the current tellask call block (if any).
14
+ *
15
+ * Within a tellask call block:
16
+ * - The first tellask line is the start of the call headline.
17
+ * - The first line MUST start with `!?@<valid-mention-id>` to be considered valid.
18
+ * Otherwise the block still parses, but is reported as malformed.
19
+ * - While still in headline phase, subsequent tellask lines starting with `!?@` extend
20
+ * the headline (multiline headline).
21
+ * - Any other tellask lines (starting with `!?` but NOT `!?@`) start/continue the call body.
22
+ *
23
+ * All downstream chunks preserve upstream chunk boundaries unless correctness requires
24
+ * a split (e.g. line-start prefix disambiguation across chunks).
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.TellaskStreamParser = void 0;
28
+ const id_1 = require("./utils/id");
29
+ class TellaskStreamParser {
30
+ constructor(downstream) {
31
+ this.callCounter = 0;
32
+ this.collectedCalls = [];
33
+ this.markdownStarted = false;
34
+ this.markdownChunkBuffer = '';
35
+ this.activeCall = null;
36
+ this.headlineBuffer = '';
37
+ this.bodyBuffer = '';
38
+ this.isAtLineStart = true;
39
+ this.lineStartProbe = '';
40
+ this.currentLineKind = 'unknown';
41
+ this.pendingCallLineRole = false;
42
+ this.currentCallLineRole = null;
43
+ // Total raw upstream characters consumed so far.
44
+ this.upstreamPos = 0;
45
+ this.downstream = downstream;
46
+ }
47
+ async takeUpstreamChunk(chunk) {
48
+ let pos = 0;
49
+ while (pos < chunk.length) {
50
+ const char = chunk[pos] ?? '';
51
+ if (this.isAtLineStart && this.currentLineKind === 'unknown') {
52
+ const consumed = await this.processLineStartProbe(char);
53
+ if (consumed) {
54
+ pos += 1;
55
+ this.upstreamPos += 1;
56
+ continue;
57
+ }
58
+ // Not consumed means we decided the line kind and need to re-process this char
59
+ // with the decided line kind.
60
+ }
61
+ if (this.currentLineKind === 'markdown') {
62
+ await this.processMarkdownChar(char);
63
+ pos += 1;
64
+ this.upstreamPos += 1;
65
+ continue;
66
+ }
67
+ if (this.currentLineKind === 'call') {
68
+ await this.processCallChar(char);
69
+ pos += 1;
70
+ this.upstreamPos += 1;
71
+ continue;
72
+ }
73
+ // Fallback: should be unreachable, but keep safe to avoid infinite loops.
74
+ await this.processMarkdownChar(char);
75
+ pos += 1;
76
+ this.upstreamPos += 1;
77
+ }
78
+ await this.flushAtUpstreamChunkEnd();
79
+ }
80
+ async finalize() {
81
+ // Resolve any pending single-char probe at start-of-line.
82
+ if (this.isAtLineStart && this.currentLineKind === 'unknown' && this.lineStartProbe === '!') {
83
+ // This is a markdown separator line starting with '!' but not enough chars to be `!?`.
84
+ await this.endActiveCallBlockIfAny();
85
+ this.markdownChunkBuffer += '!';
86
+ this.lineStartProbe = '';
87
+ }
88
+ // End-of-input can terminate a call without a trailing newline.
89
+ if (this.activeCall) {
90
+ await this.resolvePendingFirstLineMentionAtEofIfNeeded();
91
+ await this.endActiveCallBlockIfAny();
92
+ }
93
+ if (this.markdownChunkBuffer.length > 0) {
94
+ if (!this.markdownStarted) {
95
+ await this.downstream.markdownStart();
96
+ this.markdownStarted = true;
97
+ }
98
+ await this.downstream.markdownChunk(this.markdownChunkBuffer);
99
+ this.markdownChunkBuffer = '';
100
+ }
101
+ if (this.markdownStarted) {
102
+ await this.downstream.markdownFinish();
103
+ this.markdownStarted = false;
104
+ }
105
+ }
106
+ getCollectedCalls() {
107
+ return [...this.collectedCalls];
108
+ }
109
+ async processLineStartProbe(char) {
110
+ // Returns true if the character was consumed as part of probing decision.
111
+ if (this.lineStartProbe === '') {
112
+ if (char === '\n') {
113
+ // Empty line is markdown separator.
114
+ await this.endActiveCallBlockIfAny();
115
+ this.currentLineKind = 'markdown';
116
+ await this.processMarkdownChar(char);
117
+ this.resetLineStateAfterNewline();
118
+ return true;
119
+ }
120
+ this.lineStartProbe = '!';
121
+ if (char !== '!') {
122
+ // First char isn't '!' => markdown line.
123
+ this.lineStartProbe = '';
124
+ await this.endActiveCallBlockIfAny();
125
+ this.currentLineKind = 'markdown';
126
+ // Re-process this char as markdown.
127
+ return false;
128
+ }
129
+ // We saw '!' at column 0; need one more char to decide.
130
+ return true;
131
+ }
132
+ // lineStartProbe === '!' means we already consumed a '!' at strict column 0.
133
+ if (char === '\n') {
134
+ // Line length is 1 => markdown line containing '!\n'.
135
+ this.lineStartProbe = '';
136
+ await this.endActiveCallBlockIfAny();
137
+ this.currentLineKind = 'markdown';
138
+ this.markdownChunkBuffer += '!\n';
139
+ this.resetLineStateAfterNewline();
140
+ return true;
141
+ }
142
+ if (char === '?') {
143
+ // Confirmed call line prefix `!?` at column 0.
144
+ this.lineStartProbe = '';
145
+ await this.ensureCallLineModeStart();
146
+ return true;
147
+ }
148
+ // Not `!?` => markdown line starting with '!' then current char.
149
+ this.lineStartProbe = '';
150
+ await this.endActiveCallBlockIfAny();
151
+ this.currentLineKind = 'markdown';
152
+ this.markdownChunkBuffer += '!' + char;
153
+ this.isAtLineStart = false;
154
+ return true;
155
+ }
156
+ async ensureCallLineModeStart() {
157
+ // Transition from markdown to call line: finalize markdown fragment if active.
158
+ if (this.markdownChunkBuffer.length > 0) {
159
+ if (!this.markdownStarted) {
160
+ await this.downstream.markdownStart();
161
+ this.markdownStarted = true;
162
+ }
163
+ await this.downstream.markdownChunk(this.markdownChunkBuffer);
164
+ this.markdownChunkBuffer = '';
165
+ }
166
+ if (this.markdownStarted) {
167
+ await this.downstream.markdownFinish();
168
+ this.markdownStarted = false;
169
+ }
170
+ this.currentLineKind = 'call';
171
+ this.isAtLineStart = false;
172
+ this.pendingCallLineRole = true;
173
+ this.currentCallLineRole = null;
174
+ if (!this.activeCall) {
175
+ this.activeCall = {
176
+ kind: 'active',
177
+ validation: null,
178
+ firstLineMentionParse: { kind: 'pending_first_char' },
179
+ tellaskHead: '',
180
+ body: '',
181
+ callLineIndex: 0,
182
+ phase: 'headline',
183
+ tellaskHeadFinished: false,
184
+ bodyStarted: false,
185
+ callStartEmitted: false,
186
+ };
187
+ }
188
+ else {
189
+ this.activeCall.callLineIndex += 1;
190
+ }
191
+ }
192
+ async processMarkdownChar(char) {
193
+ // Markdown content includes all characters verbatim.
194
+ this.markdownChunkBuffer += char;
195
+ if (char === '\n') {
196
+ this.resetLineStateAfterNewline();
197
+ }
198
+ else {
199
+ this.isAtLineStart = false;
200
+ }
201
+ }
202
+ async processCallChar(char) {
203
+ const call = this.activeCall;
204
+ if (!call) {
205
+ // Should never happen: call line implies active call. Fall back to markdown.
206
+ await this.processMarkdownChar(char);
207
+ return;
208
+ }
209
+ if (this.pendingCallLineRole) {
210
+ const role = this.decideCallLineRole(call, char);
211
+ this.pendingCallLineRole = false;
212
+ this.currentCallLineRole = role;
213
+ if (role === 'body') {
214
+ if (call.phase === 'headline') {
215
+ await this.finishHeadlineIfNeeded();
216
+ await this.startBodyIfNeeded();
217
+ call.phase = 'body';
218
+ }
219
+ }
220
+ }
221
+ // First line mention validation is based on the first tellask line only.
222
+ if (call.callLineIndex === 0 && call.phase === 'headline') {
223
+ await this.processFirstLineMentionParse(char);
224
+ }
225
+ if (this.currentCallLineRole === 'headline') {
226
+ this.headlineBuffer += char;
227
+ }
228
+ else {
229
+ this.bodyBuffer += char;
230
+ }
231
+ if (char === '\n') {
232
+ this.resetLineStateAfterNewline();
233
+ }
234
+ else {
235
+ this.isAtLineStart = false;
236
+ }
237
+ }
238
+ decideCallLineRole(call, firstCharAfterPrefix) {
239
+ if (call.phase === 'body')
240
+ return 'body';
241
+ if (call.callLineIndex === 0)
242
+ return 'headline';
243
+ return firstCharAfterPrefix === '@' ? 'headline' : 'body';
244
+ }
245
+ async processFirstLineMentionParse(char) {
246
+ const call = this.activeCall;
247
+ if (!call)
248
+ return;
249
+ const parse = call.firstLineMentionParse;
250
+ if (parse.kind === 'resolved')
251
+ return;
252
+ if (parse.kind === 'pending_first_char') {
253
+ if (char === '\n') {
254
+ await this.resolveFirstLineMention({ kind: 'malformed', reason: 'missing_mention_prefix' });
255
+ return;
256
+ }
257
+ if (char !== '@') {
258
+ await this.resolveFirstLineMention({ kind: 'malformed', reason: 'missing_mention_prefix' });
259
+ return;
260
+ }
261
+ call.firstLineMentionParse = { kind: 'pending_mention_chars', raw: '' };
262
+ return;
263
+ }
264
+ if (parse.kind === 'pending_mention_chars') {
265
+ if (this.isValidMentionChar(char)) {
266
+ call.firstLineMentionParse = { kind: 'pending_mention_chars', raw: parse.raw + char };
267
+ return;
268
+ }
269
+ const trimmed = this.trimTrailingDots(parse.raw);
270
+ if (trimmed.length > 0) {
271
+ await this.resolveFirstLineMention({ kind: 'valid', firstMention: trimmed });
272
+ }
273
+ else {
274
+ await this.resolveFirstLineMention({ kind: 'malformed', reason: 'invalid_mention_id' });
275
+ }
276
+ return;
277
+ }
278
+ }
279
+ async resolveFirstLineMention(validation) {
280
+ const call = this.activeCall;
281
+ if (!call)
282
+ return;
283
+ call.validation = validation;
284
+ call.firstLineMentionParse = { kind: 'resolved', validation };
285
+ if (!call.callStartEmitted) {
286
+ call.callStartEmitted = true;
287
+ await this.downstream.callStart(validation);
288
+ }
289
+ await this.flushHeadlineBuffer();
290
+ }
291
+ async resolvePendingFirstLineMentionAtEofIfNeeded() {
292
+ const call = this.activeCall;
293
+ if (!call)
294
+ return;
295
+ if (call.callLineIndex !== 0)
296
+ return;
297
+ const parse = call.firstLineMentionParse;
298
+ if (parse.kind === 'resolved')
299
+ return;
300
+ if (parse.kind === 'pending_first_char') {
301
+ await this.resolveFirstLineMention({ kind: 'malformed', reason: 'missing_mention_prefix' });
302
+ return;
303
+ }
304
+ if (parse.kind === 'pending_mention_chars') {
305
+ const trimmed = this.trimTrailingDots(parse.raw);
306
+ if (trimmed.length > 0) {
307
+ await this.resolveFirstLineMention({ kind: 'valid', firstMention: trimmed });
308
+ }
309
+ else {
310
+ await this.resolveFirstLineMention({ kind: 'malformed', reason: 'invalid_mention_id' });
311
+ }
312
+ }
313
+ }
314
+ async finishHeadlineIfNeeded() {
315
+ const call = this.activeCall;
316
+ if (!call)
317
+ return;
318
+ if (call.tellaskHeadFinished)
319
+ return;
320
+ if (!call.callStartEmitted) {
321
+ // If the first line did not contain a mention terminator, we resolve at boundary.
322
+ await this.resolvePendingFirstLineMentionAtEofIfNeeded();
323
+ }
324
+ await this.flushHeadlineBuffer();
325
+ await this.downstream.callHeadLineFinish();
326
+ call.tellaskHeadFinished = true;
327
+ }
328
+ async startBodyIfNeeded() {
329
+ const call = this.activeCall;
330
+ if (!call)
331
+ return;
332
+ if (call.bodyStarted)
333
+ return;
334
+ await this.downstream.tellaskBodyStart();
335
+ call.bodyStarted = true;
336
+ }
337
+ async endActiveCallBlockIfAny() {
338
+ const call = this.activeCall;
339
+ if (!call)
340
+ return;
341
+ const upstreamEndOffset = this.upstreamPos;
342
+ // If the first line never encountered an invalid mention delimiter, ensure we still resolve.
343
+ await this.resolvePendingFirstLineMentionAtEofIfNeeded();
344
+ await this.finishHeadlineIfNeeded();
345
+ if (call.bodyStarted) {
346
+ await this.flushBodyBuffer();
347
+ await this.downstream.tellaskBodyFinish();
348
+ }
349
+ const validation = call.validation ?? { kind: 'malformed', reason: 'missing_mention_prefix' };
350
+ const callId = (0, id_1.generateContentHash)(`tellask\n${validation.kind === 'valid' ? validation.firstMention : ''}\n${call.tellaskHead}\n${call.body}`, this.callCounter++);
351
+ const collected = {
352
+ validation,
353
+ tellaskHead: call.tellaskHead,
354
+ body: call.body,
355
+ callId,
356
+ };
357
+ this.collectedCalls.push(collected);
358
+ await this.downstream.callFinish(collected, upstreamEndOffset);
359
+ this.activeCall = null;
360
+ this.headlineBuffer = '';
361
+ this.bodyBuffer = '';
362
+ this.pendingCallLineRole = false;
363
+ this.currentCallLineRole = null;
364
+ }
365
+ resetLineStateAfterNewline() {
366
+ this.isAtLineStart = true;
367
+ this.lineStartProbe = '';
368
+ this.currentLineKind = 'unknown';
369
+ this.pendingCallLineRole = false;
370
+ this.currentCallLineRole = null;
371
+ }
372
+ async flushHeadlineBuffer() {
373
+ const call = this.activeCall;
374
+ if (!call)
375
+ return;
376
+ if (!call.callStartEmitted)
377
+ return;
378
+ if (this.headlineBuffer.length === 0)
379
+ return;
380
+ call.tellaskHead += this.headlineBuffer;
381
+ await this.downstream.callHeadLineChunk(this.headlineBuffer);
382
+ this.headlineBuffer = '';
383
+ }
384
+ async flushBodyBuffer() {
385
+ const call = this.activeCall;
386
+ if (!call)
387
+ return;
388
+ if (this.bodyBuffer.length === 0)
389
+ return;
390
+ call.body += this.bodyBuffer;
391
+ await this.downstream.tellaskBodyChunk(this.bodyBuffer);
392
+ this.bodyBuffer = '';
393
+ }
394
+ async flushAtUpstreamChunkEnd() {
395
+ if (this.markdownChunkBuffer.length > 0) {
396
+ if (!this.markdownStarted) {
397
+ await this.downstream.markdownStart();
398
+ this.markdownStarted = true;
399
+ }
400
+ await this.downstream.markdownChunk(this.markdownChunkBuffer);
401
+ this.markdownChunkBuffer = '';
402
+ }
403
+ const call = this.activeCall;
404
+ if (call) {
405
+ if (call.callLineIndex === 0) {
406
+ const parse = call.firstLineMentionParse;
407
+ if (parse.kind === 'pending_mention_chars' && parse.raw.length > 0) {
408
+ // Do nothing: we cannot resolve until a delimiter/newline/EOF.
409
+ }
410
+ }
411
+ await this.flushHeadlineBuffer();
412
+ if (call.bodyStarted) {
413
+ await this.flushBodyBuffer();
414
+ }
415
+ }
416
+ }
417
+ isValidMentionChar(char) {
418
+ const charCode = char.charCodeAt(0);
419
+ return (
420
+ // ASCII alphanumeric: a-z, A-Z, 0-9
421
+ (charCode >= 48 && charCode <= 57) ||
422
+ (charCode >= 65 && charCode <= 90) ||
423
+ (charCode >= 97 && charCode <= 122) ||
424
+ // Special allowed characters
425
+ char === '_' ||
426
+ char === '-' ||
427
+ char === '.' ||
428
+ // Unicode letters and digits
429
+ /\p{L}/u.test(char) ||
430
+ /\p{N}/u.test(char));
431
+ }
432
+ trimTrailingDots(value) {
433
+ let out = value;
434
+ while (out.endsWith('.'))
435
+ out = out.slice(0, -1);
436
+ return out;
437
+ }
438
+ }
439
+ exports.TellaskStreamParser = TellaskStreamParser;