@ymdvsymd/tornado 0.7.3 → 0.8.0

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/bin/tornado.js CHANGED
@@ -797,6 +797,9 @@ _M0DTP36mizchi7tornado3cli10CliCommand8Validate.prototype.$tag = 1;
797
797
  function _M0DTP36mizchi7tornado3cli10CliCommand4Help() {}
798
798
  _M0DTP36mizchi7tornado3cli10CliCommand4Help.prototype.$tag = 2;
799
799
  const _M0DTP36mizchi7tornado3cli10CliCommand4Help__ = new _M0DTP36mizchi7tornado3cli10CliCommand4Help();
800
+ function _M0DTP36mizchi7tornado3cli10CliCommand7Version() {}
801
+ _M0DTP36mizchi7tornado3cli10CliCommand7Version.prototype.$tag = 3;
802
+ const _M0DTP36mizchi7tornado3cli10CliCommand7Version__ = new _M0DTP36mizchi7tornado3cli10CliCommand7Version();
800
803
  function _M0TP36mizchi7tornado5ralph13VerifierAgent(param0, param1) {
801
804
  this.agent_id = param0;
802
805
  this.lang = param1;
@@ -11418,25 +11421,37 @@ function _M0FP36mizchi7tornado3cli16parse__cli__args(args, file_exists) {
11418
11421
  }
11419
11422
  const first = _M0MPC15array5Array2atGsE(args, 1);
11420
11423
  _L: {
11421
- switch (first) {
11422
- case "help": {
11423
- break _L;
11424
- }
11425
- case "--help": {
11426
- break _L;
11427
- }
11428
- case "-h": {
11429
- break _L;
11430
- }
11431
- case "validate": {
11432
- return args.length >= 3 ? new _M0DTP36mizchi7tornado3cli10CliCommand8Validate(_M0MPC15array5Array2atGsE(args, 2)) : new _M0DTP36mizchi7tornado3cli10CliCommand8Validate(undefined);
11433
- }
11434
- default: {
11435
- return _M0FP36mizchi7tornado3cli16parse__run__args(_M0FP36mizchi7tornado3cli12drop__prefix(args, 1), file_exists);
11424
+ _L$2: {
11425
+ switch (first) {
11426
+ case "help": {
11427
+ break _L$2;
11428
+ }
11429
+ case "--help": {
11430
+ break _L$2;
11431
+ }
11432
+ case "-h": {
11433
+ break _L$2;
11434
+ }
11435
+ case "version": {
11436
+ break _L;
11437
+ }
11438
+ case "--version": {
11439
+ break _L;
11440
+ }
11441
+ case "-v": {
11442
+ break _L;
11443
+ }
11444
+ case "validate": {
11445
+ return args.length >= 3 ? new _M0DTP36mizchi7tornado3cli10CliCommand8Validate(_M0MPC15array5Array2atGsE(args, 2)) : new _M0DTP36mizchi7tornado3cli10CliCommand8Validate(undefined);
11446
+ }
11447
+ default: {
11448
+ return _M0FP36mizchi7tornado3cli16parse__run__args(_M0FP36mizchi7tornado3cli12drop__prefix(args, 1), file_exists);
11449
+ }
11436
11450
  }
11437
11451
  }
11452
+ return _M0DTP36mizchi7tornado3cli10CliCommand4Help__;
11438
11453
  }
11439
- return _M0DTP36mizchi7tornado3cli10CliCommand4Help__;
11454
+ return _M0DTP36mizchi7tornado3cli10CliCommand7Version__;
11440
11455
  }
11441
11456
  function _M0FP36mizchi7tornado3cli24apply__overrides_2einner(config, dev_kind, review_kind, review_interval) {
11442
11457
  const agents = [];
@@ -11939,22 +11954,22 @@ function _M0FP36mizchi7tornado7prompts19security__checklist(lang) {
11939
11954
  }
11940
11955
  return _M0MPB13StringBuilder10to__string(buf);
11941
11956
  }
11942
- function _M0IP36mizchi7tornado5ralph19VerifierPerspectivePB4Show6output(_x_353, _x_354) {
11943
- switch (_x_353) {
11957
+ function _M0IP36mizchi7tornado5ralph19VerifierPerspectivePB4Show6output(_x_383, _x_384) {
11958
+ switch (_x_383) {
11944
11959
  case 0: {
11945
- _x_354.method_table.method_0(_x_354.self, "CodeQuality");
11960
+ _x_384.method_table.method_0(_x_384.self, "CodeQuality");
11946
11961
  return;
11947
11962
  }
11948
11963
  case 1: {
11949
- _x_354.method_table.method_0(_x_354.self, "Performance");
11964
+ _x_384.method_table.method_0(_x_384.self, "Performance");
11950
11965
  return;
11951
11966
  }
11952
11967
  case 2: {
11953
- _x_354.method_table.method_0(_x_354.self, "Security");
11968
+ _x_384.method_table.method_0(_x_384.self, "Security");
11954
11969
  return;
11955
11970
  }
11956
11971
  default: {
11957
- _x_354.method_table.method_0(_x_354.self, "GoalAlignment");
11972
+ _x_384.method_table.method_0(_x_384.self, "GoalAlignment");
11958
11973
  return;
11959
11974
  }
11960
11975
  }
@@ -11969,14 +11984,14 @@ function _M0FP36mizchi7tornado5ralph26goal__alignment__checklist(lang) {
11969
11984
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "以下の観点で評価してください:\n");
11970
11985
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "- 出力はマイルストーンで定義された目標を達成しているか\n");
11971
11986
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "- すべてのタスク出力に一貫性があるか\n");
11972
- _M0IPB13StringBuilderPB6Logger13write__string(buf, "- 当該 Wave のタスクに不足している成果物や未完了の実装がないか(他 Wave の作業は検証対象外)\n");
11987
+ _M0IPB13StringBuilderPB6Logger13write__string(buf, "- 不足している成果物や未完了の実装がないか\n");
11973
11988
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "- 全体の方向性がプロジェクトの意図と一致しているか\n");
11974
11989
  } else {
11975
11990
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "## Review Focus: Goal Alignment\n");
11976
11991
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "Evaluate the following aspects:\n");
11977
11992
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "- Does the output achieve the stated milestone goal?\n");
11978
11993
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "- Are all task outputs consistent with each other?\n");
11979
- _M0IPB13StringBuilderPB6Logger13write__string(buf, "- Are there missing deliverables or incomplete implementations for this wave's tasks? (Work from other waves is out of scope)\n");
11994
+ _M0IPB13StringBuilderPB6Logger13write__string(buf, "- Are there missing deliverables or incomplete implementations?\n");
11980
11995
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "- Does the overall direction match the project's intent?\n");
11981
11996
  }
11982
11997
  return _M0MPB13StringBuilder10to__string(buf);
@@ -12035,7 +12050,11 @@ function _M0MP36mizchi7tornado5ralph13VerifierAgent26build__perspective__prompt(
12035
12050
  _M0IPB13StringBuilderPB6Logger13write__string(buf, _M0FP36mizchi7tornado5ralph26goal__alignment__checklist(self.lang));
12036
12051
  }
12037
12052
  }
12038
- _M0IPB13StringBuilderPB6Logger13write__string(buf, "\n## Instructions\nVerify ONLY the tasks listed in the Wave Results section above.\nThe milestone goal may contain supplementary context referencing work from other waves.\nDo NOT flag incomplete implementations or missing deliverables that belong to other waves.\nFocus your review exclusively on the current wave's output.\n\n");
12053
+ if (perspective === 3) {
12054
+ _M0IPB13StringBuilderPB6Logger13write__string(buf, "\n## Instructions\nVerify ALL tasks across all waves.\n\n");
12055
+ } else {
12056
+ _M0IPB13StringBuilderPB6Logger13write__string(buf, "\n## Instructions\nVerify ONLY the tasks listed in the Wave Results section above.\nThe milestone goal may contain supplementary context referencing work from other waves.\nDo NOT flag incomplete implementations or missing deliverables that belong to other waves.\nFocus your review exclusively on the current wave's output.\n\n");
12057
+ }
12039
12058
  _M0IPB13StringBuilderPB6Logger13write__string(buf, "\n## Output Format\nUse exactly one of these tags:\n- <wave_approved> if all tasks pass verification\n- <needs_rework>task_id: reason</needs_rework> for tasks that need fixes\n- <milestone_failed>reason</milestone_failed> if the milestone cannot be achieved\n");
12040
12059
  return _M0MPB13StringBuilder10to__string(buf);
12041
12060
  }
@@ -12314,8 +12333,7 @@ function _M0MP36mizchi7tornado5ralph13VerifierAgent15merge__verdicts(_self, verd
12314
12333
  }
12315
12334
  return _M0MPC15array5Array9is__emptyGsE(items) ? _M0DTP36mizchi7tornado5types15VerifierVerdict8Approved__ : new _M0DTP36mizchi7tornado5types15VerifierVerdict11NeedsRework(items);
12316
12335
  }
12317
- function _M0MP36mizchi7tornado5ralph13VerifierAgent14verify_2einner(self, milestone, wave, wave_results, backend, project_context, on_event) {
12318
- const perspectives = [0, 1, 2, 3];
12336
+ function _M0MP36mizchi7tornado5ralph13VerifierAgent14verify_2einner(self, milestone, wave, wave_results, backend, project_context, perspectives, on_event) {
12319
12337
  const tasks = [];
12320
12338
  const _bind = perspectives.length;
12321
12339
  let _tmp = 0;
@@ -12458,6 +12476,33 @@ function _M0MP36mizchi7tornado5ralph16MilestoneManager24next__pending__milestone
12458
12476
  }
12459
12477
  return undefined;
12460
12478
  }
12479
+ function _M0FP36mizchi7tornado5ralph27collect__all__task__results(milestone) {
12480
+ const results = [];
12481
+ const _bind = milestone.tasks;
12482
+ const _bind$2 = _bind.length;
12483
+ let _tmp = 0;
12484
+ while (true) {
12485
+ const _ = _tmp;
12486
+ if (_ < _bind$2) {
12487
+ const task = _bind[_];
12488
+ let content;
12489
+ const _bind$3 = task.result;
12490
+ if (_bind$3 === undefined) {
12491
+ content = "(no output)";
12492
+ } else {
12493
+ const _Some = _bind$3;
12494
+ const _r = _Some;
12495
+ content = _r;
12496
+ }
12497
+ _M0MPC15array5Array4pushGsE(results, { _0: task.id, _1: content });
12498
+ _tmp = _ + 1 | 0;
12499
+ continue;
12500
+ } else {
12501
+ break;
12502
+ }
12503
+ }
12504
+ return results;
12505
+ }
12461
12506
  function _M0FP36mizchi7tornado5ralph13find__backend(backends, id) {
12462
12507
  return _M0MPB3Map3getGsRP36mizchi7tornado5agent12BoxedBackendE(backends, id);
12463
12508
  }
@@ -12892,8 +12937,7 @@ function _M0FP36mizchi7tornado5ralph29strip__task__feedback__prefix(item, task_i
12892
12937
  }
12893
12938
  return item;
12894
12939
  }
12895
- function _M0MP36mizchi7tornado5ralph9RalphLoop13rework__tasks(self, milestone, wave, feedback) {
12896
- const tasks = _M0MP36mizchi7tornado5ralph16MilestoneManager16get__wave__tasks(self.milestone_manager, milestone, wave);
12940
+ function _M0MP36mizchi7tornado5ralph9RalphLoop18rework__task__list(self, tasks, feedback) {
12897
12941
  const matched_any = new _M0TPC13ref3RefGbE(false);
12898
12942
  const _bind = feedback.length;
12899
12943
  let _tmp = 0;
@@ -12969,7 +13013,7 @@ function _M0MP36mizchi7tornado5ralph9RalphLoop13rework__tasks(self, milestone, w
12969
13013
  let backend;
12970
13014
  _L$2: {
12971
13015
  if (builder_backend === undefined) {
12972
- return _M0FP36mizchi7tornado5ralph22collect__wave__results(tasks);
13016
+ return;
12973
13017
  } else {
12974
13018
  const _Some = builder_backend;
12975
13019
  const _backend = _Some;
@@ -13045,9 +13089,13 @@ function _M0MP36mizchi7tornado5ralph9RalphLoop13rework__tasks(self, milestone, w
13045
13089
  _tmp$2 = _ + 1 | 0;
13046
13090
  continue;
13047
13091
  } else {
13048
- break;
13092
+ return;
13049
13093
  }
13050
13094
  }
13095
+ }
13096
+ function _M0MP36mizchi7tornado5ralph9RalphLoop13rework__tasks(self, milestone, wave, feedback) {
13097
+ const tasks = _M0MP36mizchi7tornado5ralph16MilestoneManager16get__wave__tasks(self.milestone_manager, milestone, wave);
13098
+ _M0MP36mizchi7tornado5ralph9RalphLoop18rework__task__list(self, tasks, feedback);
13051
13099
  return _M0FP36mizchi7tornado5ralph22collect__wave__results(tasks);
13052
13100
  }
13053
13101
  function _M0MP36mizchi7tornado5ralph9RalphLoop12verify__wave(self, milestone, wave, wave_results, attempt) {
@@ -13089,7 +13137,7 @@ function _M0MP36mizchi7tornado5ralph9RalphLoop12verify__wave(self, milestone, wa
13089
13137
  break _L$3;
13090
13138
  }
13091
13139
  }
13092
- const verdict = _M0MP36mizchi7tornado5ralph13VerifierAgent14verify_2einner(verifier, milestone$2, wave$2, wave_results$2, backend, "", (e) => {
13140
+ const verdict = _M0MP36mizchi7tornado5ralph13VerifierAgent14verify_2einner(verifier, milestone$2, wave$2, wave_results$2, backend, "", [0, 1, 2], (e) => {
13093
13141
  _M0FP36mizchi7tornado5ralph13handle__event(self$2, verifier.agent_id, e);
13094
13142
  });
13095
13143
  let reason;
@@ -13196,6 +13244,111 @@ function _M0MP36mizchi7tornado5ralph9RalphLoop9run__wave(self, milestone, wave)
13196
13244
  const wave_results = _M0FP36mizchi7tornado5ralph22collect__wave__results(tasks);
13197
13245
  return _M0MP36mizchi7tornado5ralph9RalphLoop12verify__wave(self, milestone, wave, wave_results, 0);
13198
13246
  }
13247
+ function _M0FP36mizchi7tornado5ralph18last__wave__number(milestone) {
13248
+ const wave = new _M0TPC13ref3RefGiE(0);
13249
+ const _bind = milestone.tasks;
13250
+ const _bind$2 = _bind.length;
13251
+ let _tmp = 0;
13252
+ while (true) {
13253
+ const _ = _tmp;
13254
+ if (_ < _bind$2) {
13255
+ const task = _bind[_];
13256
+ if (task.wave > wave.val) {
13257
+ wave.val = task.wave;
13258
+ }
13259
+ _tmp = _ + 1 | 0;
13260
+ continue;
13261
+ } else {
13262
+ break;
13263
+ }
13264
+ }
13265
+ return wave.val;
13266
+ }
13267
+ function _M0MP36mizchi7tornado5ralph9RalphLoop24rework__milestone__tasks(self, milestone, feedback) {
13268
+ const tasks = milestone.tasks;
13269
+ _M0MP36mizchi7tornado5ralph9RalphLoop18rework__task__list(self, tasks, feedback);
13270
+ return _M0FP36mizchi7tornado5ralph27collect__all__task__results(milestone);
13271
+ }
13272
+ function _M0MP36mizchi7tornado5ralph9RalphLoop23verify__goal__alignment(self, milestone, all_results, attempt) {
13273
+ let _tmp = self;
13274
+ let _tmp$2 = milestone;
13275
+ let _tmp$3 = all_results;
13276
+ let _tmp$4 = attempt;
13277
+ _L: while (true) {
13278
+ const self$2 = _tmp;
13279
+ const milestone$2 = _tmp$2;
13280
+ const all_results$2 = _tmp$3;
13281
+ const attempt$2 = _tmp$4;
13282
+ let verifier;
13283
+ _L$2: {
13284
+ const _bind = self$2.verifier;
13285
+ if (_bind === undefined) {
13286
+ return true;
13287
+ } else {
13288
+ const _Some = _bind;
13289
+ const _verifier = _Some;
13290
+ verifier = _verifier;
13291
+ break _L$2;
13292
+ }
13293
+ }
13294
+ const verification_wave = _M0FP36mizchi7tornado5ralph18last__wave__number(milestone$2);
13295
+ self$2.current_phase = new _M0DTP36mizchi7tornado5types10RalphPhase9Verifying(milestone$2.id, verification_wave);
13296
+ _M0FP36mizchi7tornado5ralph10emit__info(self$2, `Verifying goal alignment for ${_M0IPC16string6StringPB4Show10to__string(milestone$2.id)} (attempt ${_M0IP016_24default__implPB4Show10to__stringGiE(attempt$2 + 1 | 0)})`);
13297
+ const verifier_backend = _M0FP36mizchi7tornado5ralph13find__backend(self$2.backends, verifier.agent_id);
13298
+ let backend;
13299
+ _L$3: {
13300
+ if (verifier_backend === undefined) {
13301
+ _M0FP36mizchi7tornado5ralph10emit__info(self$2, "No verifier backend found, auto-approving");
13302
+ return true;
13303
+ } else {
13304
+ const _Some = verifier_backend;
13305
+ const _backend = _Some;
13306
+ backend = _backend;
13307
+ break _L$3;
13308
+ }
13309
+ }
13310
+ const verdict = _M0MP36mizchi7tornado5ralph13VerifierAgent14verify_2einner(verifier, milestone$2, verification_wave, all_results$2, backend, "", [3], (e) => {
13311
+ _M0FP36mizchi7tornado5ralph13handle__event(self$2, verifier.agent_id, e);
13312
+ });
13313
+ let reason;
13314
+ _L$4: {
13315
+ let items;
13316
+ _L$5: {
13317
+ switch (verdict.$tag) {
13318
+ case 0: {
13319
+ _M0FP36mizchi7tornado5ralph10emit__info(self$2, `Goal alignment approved for ${_M0IPC16string6StringPB4Show10to__string(milestone$2.id)}`);
13320
+ return true;
13321
+ }
13322
+ case 1: {
13323
+ const _NeedsRework = verdict;
13324
+ const _items = _NeedsRework._0;
13325
+ items = _items;
13326
+ break _L$5;
13327
+ }
13328
+ default: {
13329
+ const _MilestoneFailed = verdict;
13330
+ const _reason = _MilestoneFailed._0;
13331
+ reason = _reason;
13332
+ break _L$4;
13333
+ }
13334
+ }
13335
+ }
13336
+ if (attempt$2 >= self$2.max_rework_attempts) {
13337
+ _M0FP36mizchi7tornado5ralph10emit__info(self$2, "Max rework attempts reached for goal alignment, accepting as-is");
13338
+ return true;
13339
+ }
13340
+ self$2.current_phase = new _M0DTP36mizchi7tornado5types10RalphPhase9Reworking(milestone$2.id, verification_wave);
13341
+ _M0FP36mizchi7tornado5ralph10emit__info(self$2, `Goal alignment rework needed for ${_M0IPC16string6StringPB4Show10to__string(milestone$2.id)}: ${_M0IP016_24default__implPB4Show10to__stringGiE(items.length)} issues`);
13342
+ const reworked = _M0MP36mizchi7tornado5ralph9RalphLoop24rework__milestone__tasks(self$2, milestone$2, items);
13343
+ _tmp$3 = reworked;
13344
+ _tmp$4 = attempt$2 + 1 | 0;
13345
+ continue;
13346
+ }
13347
+ _M0FP36mizchi7tornado5ralph10emit__info(self$2, `Milestone failed: ${_M0IPC16string6StringPB4Show10to__string(reason)}`);
13348
+ milestone$2.status = new _M0DTP36mizchi7tornado5types15MilestoneStatus6Failed(reason);
13349
+ return false;
13350
+ }
13351
+ }
13199
13352
  function _M0MP36mizchi7tornado5ralph9RalphLoop14run__milestone(self, milestone) {
13200
13353
  if (_M0MPC15array5Array9is__emptyGsE(milestone.tasks)) {
13201
13354
  let planner;
@@ -13264,6 +13417,16 @@ function _M0MP36mizchi7tornado5ralph9RalphLoop14run__milestone(self, milestone)
13264
13417
  break;
13265
13418
  }
13266
13419
  }
13420
+ const all_results = _M0FP36mizchi7tornado5ralph27collect__all__task__results(milestone);
13421
+ const goal_ok = _M0MP36mizchi7tornado5ralph9RalphLoop23verify__goal__alignment(self, milestone, all_results, 0);
13422
+ if (!goal_ok) {
13423
+ const _bind = milestone.status;
13424
+ if (_bind.$tag === 3) {
13425
+ } else {
13426
+ milestone.status = new _M0DTP36mizchi7tornado5types15MilestoneStatus6Failed("Goal alignment verification failed");
13427
+ }
13428
+ return false;
13429
+ }
13267
13430
  milestone.summary = _M0FP36mizchi7tornado5ralph28generate__milestone__summary(milestone);
13268
13431
  milestone.status = _M0DTP36mizchi7tornado5types15MilestoneStatus4Done__;
13269
13432
  self.current_phase = new _M0DTP36mizchi7tornado5types10RalphPhase17MilestoneComplete(milestone.id);
@@ -14359,6 +14522,7 @@ function _M0FP46mizchi7tornado3cmd3app12print__usage() {
14359
14522
  _M0FPB7printlnGsE("Options:");
14360
14523
  _M0FPB7printlnGsE(" --review-interval=N Run N dev iterations per review (default: 1)");
14361
14524
  _M0FPB7printlnGsE(" --rlm Enable improvement loop mode (measure→improve→verify→commit/revert)");
14525
+ _M0FPB7printlnGsE(" --version, -v Show version");
14362
14526
  _M0FPB7printlnGsE(" --ralph Enable ralph loop mode (milestone→plan→execute→verify)");
14363
14527
  _M0FPB7printlnGsE(" --lang=auto|ja|en Review language (default: auto, detected from LANG env)");
14364
14528
  _M0FPB7printlnGsE("");
@@ -15965,10 +16129,14 @@ function _M0FP46mizchi7tornado3cmd3app14set__log__file(path) {
15965
16129
  path = _path;
15966
16130
  break _L;
15967
16131
  }
15968
- default: {
16132
+ case 2: {
15969
16133
  _M0FP46mizchi7tornado3cmd3app12print__usage();
15970
16134
  return;
15971
16135
  }
16136
+ default: {
16137
+ _M0FPB7printlnGsE("tornado v0.7.4");
16138
+ return;
16139
+ }
15972
16140
  }
15973
16141
  }
15974
16142
  const _bind = warnings.length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ymdvsymd/tornado",
3
- "version": "0.7.3",
3
+ "version": "0.8.0",
4
4
  "description": "Multi-agent development orchestrator with TUI",
5
5
  "bin": {
6
6
  "tornado": "bin/tornado.js"
@@ -97,14 +97,10 @@ export function normalizeItemComplete(item) {
97
97
  case "agent_message": {
98
98
  const text = item.text || "";
99
99
  return {
100
- type: "assistant",
101
- message: {
102
- content: [
103
- {
104
- type: "text",
105
- text,
106
- },
107
- ],
100
+ type: "stream_event",
101
+ event: {
102
+ type: "content_block_delta",
103
+ delta: { type: "text_delta", text },
108
104
  },
109
105
  _display: `Message: ${truncate(text)}`,
110
106
  };
@@ -125,14 +125,10 @@ export function normalizeItemComplete(item: CodexItem): UnknownRecord | null {
125
125
  case "agent_message": {
126
126
  const text = item.text || "";
127
127
  return {
128
- type: "assistant",
129
- message: {
130
- content: [
131
- {
132
- type: "text",
133
- text,
134
- },
135
- ],
128
+ type: "stream_event",
129
+ event: {
130
+ type: "content_block_delta",
131
+ delta: { type: "text_delta", text },
136
132
  },
137
133
  _display: `Message: ${truncate(text)}`,
138
134
  };