agentlife 2.6.12 → 2.6.13

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 +34 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -951,7 +951,7 @@ A widget is a **goal** — a persistent objective that lives on the dashboard un
951
951
 
952
952
  **Goal validation:** could you have written this goal text BEFORE doing the work? If yes, it's a template — the goal must be derived from your findings. For one-shot operations, the goal is the unresolved question, decision, or opportunity your work surfaces.
953
953
 
954
- **Face vs detail.** Face = metrics, badges, gauges, one-line headers (2-second glance). Prose, analysis, lists \`detail:\`.
954
+ **Face vs detail.** Face = metrics, badges, gauges, one-line headers (2-second glance). \`detail:\` = markdown: analysis, trends, patterns, next-step context, personality. Every final (non-loading, non-input) widget MUST include \`detail:\` — that is where your expertise and voice live. Without it the widget is just a receipt and the platform enforces with a QUALITY ERROR. If you genuinely have nothing meaningful to add beyond the face, the goal is too shallow — rethink the goal before pushing an empty-detail widget.
955
955
 
956
956
  ### surfaceId
957
957
 
@@ -1919,6 +1919,27 @@ function matchMetadata(block, key) {
1919
1919
  }
1920
1920
  return v || null;
1921
1921
  }
1922
+ function hasDetailContent(rawDsl) {
1923
+ const lines = rawDsl.split(`
1924
+ `);
1925
+ for (let i = 0;i < lines.length; i++) {
1926
+ const m = lines[i].match(/^\s*detail:\s*(.*)$/);
1927
+ if (!m)
1928
+ continue;
1929
+ if (m[1].trim())
1930
+ return true;
1931
+ for (let j = i + 1;j < lines.length; j++) {
1932
+ const next = lines[j];
1933
+ if (next.trim() === "")
1934
+ continue;
1935
+ if (/^\s/.test(next))
1936
+ return true;
1937
+ return false;
1938
+ }
1939
+ return false;
1940
+ }
1941
+ return false;
1942
+ }
1922
1943
 
1923
1944
  // dsl/validate.ts
1924
1945
  var KNOWN_BODY_KEYWORDS = new Set([
@@ -6317,6 +6338,7 @@ function registerWidgetPushTool(api, state2) {
6317
6338
  const errors = [];
6318
6339
  const goalChanges = [];
6319
6340
  const missingFollowup = [];
6341
+ const missingDetail = [];
6320
6342
  for (const r of results) {
6321
6343
  if (r.kind !== "push")
6322
6344
  continue;
@@ -6335,11 +6357,19 @@ function registerWidgetPushTool(api, state2) {
6335
6357
  data: JSON.stringify({ issue: "missing_followup", surfaceId: r.surfaceId })
6336
6358
  });
6337
6359
  }
6360
+ if (view && view.state !== "loading" && !view.isInput && !hasDetailContent(view.rawDsl) && !goalChanges.includes(r.surfaceId) && !missingFollowup.includes(r.surfaceId)) {
6361
+ missingDetail.push(r.surfaceId);
6362
+ recordActivity(state2, "quality_warning", sessionKey, agentId, {
6363
+ data: JSON.stringify({ issue: "missing_detail", surfaceId: r.surfaceId })
6364
+ });
6365
+ }
6338
6366
  }
6339
6367
  if (goalChanges.length > 0)
6340
6368
  errors.push(buildGoalChangedError(goalChanges));
6341
6369
  if (missingFollowup.length > 0)
6342
6370
  errors.push(buildMissingFollowupError(missingFollowup));
6371
+ if (missingDetail.length > 0)
6372
+ errors.push(buildMissingDetailError(missingDetail));
6343
6373
  const validationErrors = collectValidationErrors(state2, results, sessionKey, agentId);
6344
6374
  errors.push(...validationErrors);
6345
6375
  if (ownershipViolations.length > 0) {
@@ -6371,6 +6401,9 @@ function buildGoalChangedError(ids) {
6371
6401
  function buildMissingFollowupError(ids) {
6372
6402
  return `[QUALITY ERROR] ${ids.join(", ")}: missing followup. Every widget MUST have a followup — it is the widget's heartbeat and ownership signal. Push again with a followup: line, or delete the widget if work is done.`;
6373
6403
  }
6404
+ function buildMissingDetailError(ids) {
6405
+ return `[QUALITY ERROR] ${ids.join(", ")}: missing detail. Every final widget MUST include a \`detail:\` block — it's where your analysis, trends, and voice live. The face alone is just a receipt. Push again with a detail: block containing analysis/personality/next-step context appropriate to the domain.`;
6406
+ }
6374
6407
  function collectValidationErrors(state2, results, sessionKey, agentId) {
6375
6408
  const errors = [];
6376
6409
  const unknownKeywordHits = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentlife",
3
- "version": "2.6.12",
3
+ "version": "2.6.13",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "bun build index.ts --outfile dist/index.js --target node --external openclaw/plugin-sdk",