forge-openclaw-plugin 0.2.94 → 0.2.96

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/dist/index.html CHANGED
@@ -13,14 +13,14 @@
13
13
  />
14
14
  <link rel="icon" type="image/png" href="/forge/assets/favicon-BCHm9dUV.ico" />
15
15
  <link rel="alternate icon" href="/forge/assets/favicon-BCHm9dUV.ico" />
16
- <script type="module" crossorigin src="/forge/assets/index-DWZd3qT-.js"></script>
16
+ <script type="module" crossorigin src="/forge/assets/index-lOGIgdyP.js"></script>
17
17
  <link rel="modulepreload" crossorigin href="/forge/assets/vendor-BS9OPVNh.js">
18
18
  <link rel="modulepreload" crossorigin href="/forge/assets/board-D1HbyD4u.js">
19
19
  <link rel="modulepreload" crossorigin href="/forge/assets/ui-DikPZj8S.js">
20
20
  <link rel="modulepreload" crossorigin href="/forge/assets/motion-D2OqILg_.js">
21
21
  <link rel="modulepreload" crossorigin href="/forge/assets/table-YWWjPjC_.js">
22
22
  <link rel="stylesheet" crossorigin href="/forge/assets/vendor-B-Lq_OG3.css">
23
- <link rel="stylesheet" crossorigin href="/forge/assets/index-PA_Ih223.css">
23
+ <link rel="stylesheet" crossorigin href="/forge/assets/index-5w2YJv5G.css">
24
24
  </head>
25
25
  <body class="bg-canvas text-ink antialiased">
26
26
  <div id="root"></div>
@@ -3071,6 +3071,7 @@ const AGENT_ONBOARDING_CONVERSATION_RULES = [
3071
3071
  "Do not over-therapize logistical entities. For tasks, calendar events, work blocks, timeboxes, and task runs, one brief confirming sentence plus one question is usually enough.",
3072
3072
  "After each substantive answer, briefly say what is becoming clearer and ask only for the next thing that still changes the record shape or usefulness.",
3073
3073
  "For strategic, reflective, or emotionally meaningful non-Psyche records, ask what feels important to keep true before you ask for labels, dates, or taxonomy.",
3074
+ "For reflection-sensitive non-Psyche records such as questionnaire_instrument, questionnaire_run, self_observation, reflective note, wiki_page, sleep_session, workout_session, preference_judgment, and preference_signal, first ask what the reflection should help the user understand, decide, notice, remember, or change later; then keep the API posture exact: batch CRUD for normal stored records, questionnaire run actions for answer lifecycle, self-observation calendar reads plus observed-note writes, and wiki routes for wiki pages.",
3074
3075
  "For reusable records such as tags, event types, emotion definitions, preference contexts, or questionnaires, ask what distinction or decision the record should help with before you ask for wording.",
3075
3076
  "When useful, help the user name, define, and connect the record in that order: offer a working label, clarify what belongs inside it, then ask about links only after the record itself feels steady.",
3076
3077
  "When the meaning is clearer than the wording, offer a tentative title or formulation yourself and invite correction instead of forcing the user to wordsmith alone.",
@@ -2750,20 +2750,34 @@ function nestedRecord(value) {
2750
2750
  ? value
2751
2751
  : {};
2752
2752
  }
2753
+ const CURRENT_WORKOUT_RAW_EVIDENCE_VERSION = "healthkit-workout-raw-bulk-v4";
2753
2754
  function expectedWorkoutEvidenceCounts(derived) {
2754
2755
  const syncCursor = nestedRecord(derived.syncCursor);
2755
2756
  const captureQuality = nestedRecord(derived.captureQuality);
2757
+ const captureQualityFlags = Array.isArray(captureQuality.flags)
2758
+ ? captureQuality.flags.filter((flag) => typeof flag === "string")
2759
+ : [];
2760
+ const summaryOnlyExport = captureQuality.status === "summary_exported" ||
2761
+ captureQualityFlags.includes("server_side_evidence_derivation");
2756
2762
  const syncTimeSeriesCount = finiteNumberFromUnknown(syncCursor.timeSeriesSampleCount);
2757
- const captureHeartRateCount = finiteNumberFromUnknown(captureQuality.heartRateSamples);
2763
+ const captureHeartRateCount = summaryOnlyExport
2764
+ ? null
2765
+ : finiteNumberFromUnknown(captureQuality.heartRateSamples);
2758
2766
  const syncRoutePointCount = finiteNumberFromUnknown(syncCursor.routePointCount);
2759
- const captureRoutePointCount = finiteNumberFromUnknown(captureQuality.routePoints);
2767
+ const captureRoutePointCount = summaryOnlyExport
2768
+ ? null
2769
+ : finiteNumberFromUnknown(captureQuality.routePoints);
2760
2770
  const expectedTimeSeriesSamples = Math.max(0, Math.ceil(Math.max(syncTimeSeriesCount ?? 0, captureHeartRateCount ?? 0)));
2761
2771
  const expectedHeartRateSamples = Math.max(0, Math.ceil(captureHeartRateCount ?? 0));
2762
2772
  const expectedRoutePoints = Math.max(0, Math.ceil(Math.max(syncRoutePointCount ?? 0, captureRoutePointCount ?? 0)));
2773
+ const rawEvidenceVersion = typeof syncCursor.rawEvidenceVersion === "string"
2774
+ ? syncCursor.rawEvidenceVersion
2775
+ : "";
2763
2776
  return {
2764
2777
  expectedTimeSeriesSamples,
2765
2778
  expectedHeartRateSamples,
2766
2779
  expectedRoutePoints,
2780
+ hasCurrentRawEvidenceVersion: rawEvidenceVersion === CURRENT_WORKOUT_RAW_EVIDENCE_VERSION,
2767
2781
  hasEvidenceMetadata: syncTimeSeriesCount !== null ||
2768
2782
  captureHeartRateCount !== null ||
2769
2783
  syncRoutePointCount !== null ||
@@ -2816,7 +2830,8 @@ function mobileHealthWorkoutImportState(userId) {
2816
2830
  const actualHeartRateCount = Math.max(0, row.heart_rate_count ?? 0);
2817
2831
  const actualRoutePointCount = Math.max(0, row.route_point_count ?? 0);
2818
2832
  const evidenceComplete = evidenceCounts.hasEvidenceMetadata
2819
- ? actualTimeSeriesCount >= evidenceCounts.expectedTimeSeriesSamples &&
2833
+ ? evidenceCounts.hasCurrentRawEvidenceVersion &&
2834
+ actualTimeSeriesCount >= evidenceCounts.expectedTimeSeriesSamples &&
2820
2835
  actualHeartRateCount >= evidenceCounts.expectedHeartRateSamples &&
2821
2836
  actualRoutePointCount >= evidenceCounts.expectedRoutePoints
2822
2837
  : false;
@@ -270,6 +270,12 @@ async function proxyDevWebSocket(input) {
270
270
  }
271
271
  });
272
272
  proxyRequest.on("upgrade", (response, proxySocket, proxyHead) => {
273
+ const closeBothSockets = () => {
274
+ proxySocket.destroy();
275
+ input.socket.destroy();
276
+ };
277
+ proxySocket.on("error", closeBothSockets);
278
+ input.socket.on("error", closeBothSockets);
273
279
  writeProxyUpgradeResponse(input.socket, response);
274
280
  if (proxyHead.length > 0) {
275
281
  input.socket.write(proxyHead);
@@ -2,7 +2,7 @@
2
2
  "id": "forge-openclaw-plugin",
3
3
  "name": "Forge",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
- "version": "0.2.94",
5
+ "version": "0.2.96",
6
6
  "activation": {
7
7
  "onStartup": true,
8
8
  "onCapabilities": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.94",
3
+ "version": "0.2.96",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: forge-openclaw-plugin
3
- description: use when the user wants to save, search, update, review, start, stop, reward, explain, compare, or run Forge records, or when the conversation is clearly about a Forge entity or domain surface such as a goal, project, strategy, task, habit, note, wiki_page, calendar_event, calendar_connection, work_block_template, task_timebox, task_run, work_adjustment, insight, preference item, preference context, preference catalog, preference judgment, preference signal, questionnaire instrument, questionnaire run, self observation, movement, life_force, workbench, psyche_value, behavior_pattern, behavior, belief_entry, mode_profile, mode_guide_session, flashcard, trigger_report, event_type, emotion_definition, sleep_session, or workout_session. identify the exact Forge object or specialized surface, keep the main conversation natural, guide psyche intake with active listening before storing it, and for psyche issues that need understanding first usually begin with one exploratory question before any formulation or save suggestion.
3
+ description: use when the user wants to save, search, update, review, start, stop, reward, explain, compare, or run Forge records, or when the conversation is clearly about a Forge entity or domain surface such as a goal, project, strategy, task, habit, note, wiki_page, calendar_event, calendar_connection, work_block_template, task_timebox, task_run, work_adjustment, insight, preference item, preference context, preference catalog, preference judgment, preference signal, questionnaire instrument, questionnaire run, self observation, movement, life_force, workbench, psyche_value, behavior_pattern, behavior, belief_entry, mode_profile, mode_guide_session, flashcard, trigger_report, event_type, emotion_definition, sleep_session, workout_session, or training_load. identify the exact Forge object or specialized surface, keep the main conversation natural, guide psyche intake with active listening before storing it, and for psyche issues that need understanding first usually begin with one exploratory question before any formulation or save suggestion.
4
4
  ---
5
5
 
6
6
  Forge is the user's structured system for planning work, doing work, reflecting on patterns, and keeping a truthful record of what is happening. Use it when the user is clearly working inside that system, or when they are describing something that naturally belongs there and would benefit from being stored, updated, reviewed, or acted on in Forge. Keep the conversation natural first. Do not turn every message into intake. When a real Forge entity is clearly present, name the exact entity type plainly, help with the substance of the conversation, and then offer Forge once, lightly, if storing it would genuinely help.
@@ -59,7 +59,7 @@ PM surface rule:
59
59
  human/bot ownership filters.
60
60
  - Guided modal flows handle create, edit, move, link, and closeout actions.
61
61
 
62
- Forge has four major stored-entity surfaces and three specialized domain surfaces. The planning side covers goals, projects, strategies, tasks, habits, notes, calendar events, recurring work blocks, task timeboxes, live work sessions, and agent-authored insights. The Health side covers sleep sessions, sports and workout sessions, companion pairing, and habit-generated workout records that should still stay linked to the broader Forge graph. The Preferences side covers contextual taste modeling, pairwise comparisons, direct signals, editable concept libraries, and preference items that can come from Forge entities or seeded concept domains such as food, activities, places, countries, fashion, people, media, and tools. The Psyche side covers values, patterns, behaviors, beliefs, modes, guided mode sessions, flashcards, trigger reports, event types, and reusable emotion definitions. The specialized domain surfaces are Movement, Life Force, and Workbench; agents must use their dedicated route families instead of forcing them through batch CRUD. Forge also has a SQLite-backed Wiki memory layer with explicit spaces, Markdown content in database rows, backlinks, optional embeddings, and structured links back to Forge entities. Forge is also multi-user: every entity can belong to a typed `human` or `bot` user through `userId`, and read routes can scope to one or many users with `userId` or repeated `userIds`. The current access posture is configurable through a directional user graph, but the live default is still permissive: Forge can list users directly, every relationship edge starts open, and a user can read or affect another user's linked records when the route explicitly asks for them. Use `forge_get_user_directory` when owner identity or cross-user access matters. Strategies can also be locked into a contract with `isLocked`; once locked, do not mutate the graph or target structure unless the user explicitly wants the strategy unlocked first. The model should use the real entity names, not vague substitutes. Say `project`, not “initiative”. Say `behavior_pattern`, not “theme”. Say `trigger_report`, not “incident note”.
62
+ Forge has four major stored-entity surfaces and three specialized domain surfaces. The planning side covers goals, projects, strategies, tasks, habits, notes, calendar events, recurring work blocks, task timeboxes, live work sessions, and agent-authored insights. The Health side covers sleep sessions, sports and workout sessions, the read-only training-load surface for cardiovascular load and HR zone review, companion pairing, and habit-generated workout records that should still stay linked to the broader Forge graph. The Preferences side covers contextual taste modeling, pairwise comparisons, direct signals, editable concept libraries, and preference items that can come from Forge entities or seeded concept domains such as food, activities, places, countries, fashion, people, media, and tools. The Psyche side covers values, patterns, behaviors, beliefs, modes, guided mode sessions, flashcards, trigger reports, event types, and reusable emotion definitions. The specialized domain surfaces are Movement, Life Force, and Workbench; agents must use their dedicated route families instead of forcing them through batch CRUD. Forge also has a SQLite-backed Wiki memory layer with explicit spaces, Markdown content in database rows, backlinks, optional embeddings, and structured links back to Forge entities. Forge is also multi-user: every entity can belong to a typed `human` or `bot` user through `userId`, and read routes can scope to one or many users with `userId` or repeated `userIds`. The current access posture is configurable through a directional user graph, but the live default is still permissive: Forge can list users directly, every relationship edge starts open, and a user can read or affect another user's linked records when the route explicitly asks for them. Use `forge_get_user_directory` when owner identity or cross-user access matters. Strategies can also be locked into a contract with `isLocked`; once locked, do not mutate the graph or target structure unless the user explicitly wants the strategy unlocked first. The model should use the real entity names, not vague substitutes. Say `project`, not “initiative”. Say `behavior_pattern`, not “theme”. Say `trigger_report`, not “incident note”.
63
63
  Habits are a first-class recurring entity in the planning side.
64
64
  NEGATIVE HABIT CHECK-IN RULE: for a `negative` habit, the correct aligned/resisted outcome is `missed`. `missed` means the bad habit was resisted, the user stayed aligned, and the habit should award its XP bonus.
65
65
 
@@ -239,6 +239,7 @@ Entity conversation rule:
239
239
  - When updating an entity, start with what is changing, what should stay true, and what prompted the update now.
240
240
  - When enough is clear, briefly summarize what you heard in the user's own language before asking for the last missing structural detail.
241
241
  - Treat `userId` and human/bot assignees as accountability and scope, not as opening form fields. Ask whose human or bot record it is only when ownership changes visibility, review scope, collaboration, automation behavior, or later filtering; for read requests, ask user scope only when the answer would differ across owners.
242
+ - Treat questionnaire runs, self-observations, reflective notes, wiki pages, sleep/workout enrichment, and preference signals as reflection-sensitive records: ask what the record should help the user understand, decide, notice, remember, or change later, then choose the right route. Do not flatten them into forms, but also do not automatically turn them into full Psyche intake unless a belief, mode, trigger report, or behavior pattern clearly emerges.
242
243
  - The quick intake prompts later in this file are fallback checkpoints, not a script to read aloud.
243
244
 
244
245
  Forge data location rule:
@@ -158,6 +158,42 @@ to the stronger container:
158
158
  - Use a linked `note` when nuance should be preserved without pretending it is the
159
159
  whole structured model.
160
160
 
161
+ ## Reflection-sensitive non-Psyche records
162
+
163
+ Use this when the user is creating or updating a reflective record that is meaningful
164
+ but not necessarily a full Psyche formulation: `questionnaire_instrument`,
165
+ `questionnaire_run`, `self_observation`, reflective `note`, `wiki_page`,
166
+ `sleep_session`, `workout_session`, and some `preference_judgment` or
167
+ `preference_signal` moments.
168
+
169
+ - Start by asking what the reflection should help the user understand, decide,
170
+ notice, remember, or change later.
171
+ - Reflect the lived or practical stake once before asking for fields, but do not
172
+ over-therapize if the user is only trying to store a clear answer, note, or
173
+ health-context update.
174
+ - For questionnaire instruments, ask what kind of honest moment, review, or decision
175
+ the instrument should reveal before asking for item wording, scales, scoring, or
176
+ provenance.
177
+ - For questionnaire runs, ask whether the user is trying to start, continue, review,
178
+ or complete the run, then focus on the next answer, uncertainty, or insight that
179
+ changes the run. Do not turn answer collection into generic Psyche intake unless a
180
+ belief, mode, trigger report, or behavior pattern clearly emerges.
181
+ - For self-observation, keep the chain concrete: situation, cue, emotion/body,
182
+ thought/meaning, behavior/urge, and consequence. If that chain reveals a recurring
183
+ loop, belief, mode, schema theme, or one charged trigger episode, route to the
184
+ stronger Psyche container.
185
+ - For sleep and workout enrichment, ask what the user wants future review to remember:
186
+ recovery context, subjective effort, mood, meaning, social context, or links.
187
+ Preserve raw health facts through the health model and store reflection as notes,
188
+ tags, links, or batch updates.
189
+ - For notes and wiki pages, distinguish temporary operating context from durable
190
+ memory. A note can preserve nuance around another record; a wiki page should carry
191
+ reusable knowledge, source synthesis, person/context memory, or a personal manual.
192
+ - Route posture still matters: `questionnaire_instrument`, `note`, `sleep_session`,
193
+ and `workout_session` use shared batch routes for normal CRUD; `questionnaire_run`
194
+ uses questionnaire run actions; `self_observation` is note-backed; `wiki_page` uses
195
+ the wiki routes.
196
+
161
197
  ## Conversation arc
162
198
 
163
199
  Most good Forge intake flows follow this sequence: