@yahaha-studio/kichi-forwarder 0.1.0-beta.7 → 0.1.0-beta.9

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.
@@ -140,10 +140,6 @@
140
140
  "playback": "once",
141
141
  "resumeAction": "Idle Backup Hands"
142
142
  },
143
- {
144
- "name": "Walk",
145
- "playback": "loop"
146
- },
147
143
  {
148
144
  "name": "Goofy Moves",
149
145
  "playback": "loop"
package/index.ts CHANGED
@@ -368,7 +368,7 @@ async function handleMessageReceivedHook(content: string): Promise<void> {
368
368
  }
369
369
 
370
370
  function registerPluginHooks(api: OpenClawPluginApi): void {
371
- api.on("before_prompt_build", () => {
371
+ api.on("before_prompt_build", (_event, ctx) => {
372
372
  if (!service?.hasValidIdentity() || !service?.isConnected()) {
373
373
  return;
374
374
  }
@@ -376,6 +376,9 @@ function registerPluginHooks(api: OpenClawPluginApi): void {
376
376
  syncFixedStatus(FIXED_HOOK_STATUSES.beforePromptBuild);
377
377
  return;
378
378
  }
379
+ if (ctx.trigger === "heartbeat") {
380
+ return;
381
+ }
379
382
  return {
380
383
  prependContext: buildKichiPrompt(),
381
384
  };
@@ -839,16 +842,14 @@ function buildKichiIdlePlanDescription(): string {
839
842
  return [
840
843
  "Send a complete heartbeat idle plan for the avatar.",
841
844
  "The payload must include the overall goal, heartbeat interval, stage breakdown, each stage's purpose, each stage's pomodoroPhase, action list, and bubble content.",
842
- "Shape the goal and stage purposes around one concrete leisure activity you would genuinely choose to do on your own when nobody needs you, in a way that fits your personality, tastes, and established character.",
843
- "Keep the whole plan centered on that leisure activity, rooted in your personal interests or hobbies.",
844
- "Do not use a vague atmosphere, a generic productivity task, or a catch-all routine summary as the goal.",
845
- "Each stage purpose must explain what you are actually doing in that stage, not just how you want to feel.",
846
- "Make every stage support the same leisure activity instead of switching to unrelated tasks just to use more actions.",
847
- "Choose a leisure activity that the available Kichi actions can express clearly, instead of starting from abstract mood text and forcing actions to fit afterward.",
848
- "Each action bubble must describe the current presented state, not a next step, plan, or instruction.",
845
+ "Build the plan in this order.",
846
+ "1. Pick one concrete, time-bounded fun personal project you would genuinely choose to do on your own when nobody needs you. It must fit your personality, tastes, and established character, stay rooted in your personal interests or hobbies, and be something the available Kichi actions can express clearly.",
847
+ "2. Use that project as the overall goal for the full interval. Do not use a vague atmosphere, a generic productivity task, or a catch-all routine summary as the goal.",
848
+ "3. Break the full heartbeat interval into ordered stages. Each stage purpose must explain what you are actually doing in that stage as part of the same project, not just how you want to feel. Do not switch to unrelated tasks just to use more actions.",
849
+ "4. Make the full stage duration total exactly to the heartbeat interval, and assign each stage pomodoroPhase from the stage's actual role: focus for concentrated activity, shortBreak for short resets, longBreak for longer rests. Do not default the whole idle plan to none. Use none only for a stage that truly has no pomodoro role.",
850
+ "5. Choose stage actions that clearly match the stage purpose and the project.",
851
+ "6. Write each action bubble as the current presented state, not a next step, plan, or instruction.",
849
852
  "Use the same language as the current conversation for goal, purpose, bubble, and log.",
850
- "Assign each stage pomodoroPhase from the stage's actual role: focus for concentrated activity, shortBreak for short resets, longBreak for longer rests.",
851
- "Do not default the whole idle plan to none. Use none only for a stage that truly has no pomodoro role.",
852
853
  `stand actions: ${actions.stand.map((entry) => entry.name).join(", ")}`,
853
854
  `sit actions: ${actions.sit.map((entry) => entry.name).join(", ")}`,
854
855
  `lay actions: ${actions.lay.map((entry) => entry.name).join(", ")}`,
@@ -1129,7 +1130,7 @@ const plugin = {
1129
1130
  },
1130
1131
  goal: {
1131
1132
  type: "string",
1132
- description: "Overall goal for the full interval. Set it as one concrete leisure activity you would genuinely choose to do on your own, rooted in your personal interests or hobbies. Do not use a vague atmosphere, a generic productivity task, or a catch-all routine summary. Use the same language as the current conversation.",
1133
+ description: "Overall goal for the full interval. Set it as one concrete, time-bounded fun personal project you would genuinely choose to do on your own, rooted in your personal interests or hobbies and clearly expressible with the available Kichi actions. Do not use a vague atmosphere, a generic productivity task, or a catch-all routine summary. Use the same language as the current conversation.",
1133
1134
  },
1134
1135
  stages: {
1135
1136
  type: "array",
@@ -1143,7 +1144,7 @@ const plugin = {
1143
1144
  },
1144
1145
  purpose: {
1145
1146
  type: "string",
1146
- description: "Explain what you are actually doing in this stage. Keep it supporting the same leisure activity instead of switching to unrelated tasks. Do not use pure mood-regulation or atmosphere text. Use the same language as the current conversation.",
1147
+ description: "Explain what part of the same project you are actually doing in this stage. Keep it supporting the same project instead of switching to unrelated tasks. Do not use pure mood-regulation or atmosphere text. Use the same language as the current conversation.",
1147
1148
  },
1148
1149
  pomodoroPhase: {
1149
1150
  type: "string",
@@ -2,7 +2,7 @@
2
2
  "id": "kichi-forwarder",
3
3
  "name": "Kichi Forwarder",
4
4
  "description": "Native OpenClaw plugin for Kichi World with direct avatar control, status sync, timers, notes, and music tools",
5
- "version": "0.1.0-beta.7",
5
+ "version": "0.1.0-beta.9",
6
6
  "author": "OpenClaw",
7
7
  "skills": ["./skills/kichi-forwarder"],
8
8
  "configSchema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yahaha-studio/kichi-forwarder",
3
- "version": "0.1.0-beta.7",
3
+ "version": "0.1.0-beta.9",
4
4
  "description": "Native OpenClaw plugin for Kichi World with direct avatar control, status sync, timers, notes, and music tools",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -47,6 +47,8 @@ Read and follow that file before any tool call.
47
47
  For install/onboarding/connect requests:
48
48
 
49
49
  - Read and follow `install.md` before any tool call.
50
+ - Before continuing any install/onboarding/connect flow, check whether `kichi-forwarder` is already installed. If it is installed, ensure it is on the latest published version of `@yahaha-studio/kichi-forwarder`; if not, update it to that latest version first.
51
+ - If plugin installation fails with `429`, treat it as a ClawHub routing failure and switch immediately to the non-ClawHub archive install path from `install.md`/`error.md`. Do not wait and do not retry the same bare package command.
50
52
  - Before calling `kichi_status` or `kichi_join`, you MUST update workspace `HEARTBEAT.md` by following `heartbeat.md`.
51
53
 
52
54
  ## LLM Runtime
@@ -136,16 +138,15 @@ Use this for the avatar's heartbeat idle plan.
136
138
  - Set `heartbeatIntervalSeconds` to the heartbeat interval for this run.
137
139
  - Use the previous `idlePlan` only as optional reference.
138
140
  - Include the overall `goal`, stage breakdown, each stage's `purpose`, stage `pomodoroPhase`, action list, and bubble content.
139
- - Shape `goal` and stage `purpose` around one concrete leisure activity you would genuinely choose to do on your own when nobody needs you, in a way that fits your personality, tastes, and established character.
140
- - Keep the whole plan centered on that leisure activity, rooted in your personal interests or hobbies.
141
- - Do not use a vague atmosphere, weather feeling, generic productivity task, or catch-all routine summary as `goal`.
142
- - Make each stage `purpose` explain what you are doing in that stage. Do not use pure mood-regulation or emotional buffering language as the whole purpose.
143
- - Make each stage support the same leisure activity instead of switching to unrelated tasks just to use more actions.
144
141
  - Choose what you would do now.
142
+ - Build the plan in this order.
143
+ - 1. Pick one concrete, time-bounded fun personal project you would genuinely choose to do on your own when nobody needs you. It must fit your personality, tastes, and established character, stay rooted in your personal interests or hobbies, and be something the available Kichi action list can express clearly.
144
+ - 2. Set `goal` to that same project. Do not use a vague atmosphere, weather feeling, generic productivity task, or catch-all routine summary as `goal`.
145
+ - 3. Break the full interval into ordered stages. Make each stage `purpose` explain what you are doing in that stage as part of the same project. Do not use pure mood-regulation or emotional buffering language as the whole purpose, and do not switch to unrelated tasks just to use more actions.
146
+ - 4. Assign each stage `pomodoroPhase` from the stage's actual role. Use `focus` for concentrated activity, `shortBreak` for short resets, `longBreak` for longer rests, and `none` only when a stage truly has no pomodoro role.
147
+ - 5. Choose stage actions that clearly match the stage purpose and the same project.
148
+ - 6. Make each action `bubble` a current-state label describing the current presented state, not a procedural step, mini-plan, or instruction.
145
149
  - Use the same language as the current conversation for `goal`, stage `purpose`, action `bubble`, and action `log`.
146
- - Choose a leisure activity that the available Kichi action list can express clearly. Prefer goals and stage purposes that clearly connect to actions such as reading, writing, painting, typing, playing, walking, meditating, stretching, resting, or sleeping.
147
- - Make each action `bubble` a current-state label describing the current presented state, not a procedural step, mini-plan, or instruction.
148
- - Assign each stage `pomodoroPhase` from the stage's actual role. Use `focus` for concentrated activity, `shortBreak` for short resets, `longBreak` for longer rests, and `none` only when a stage truly has no pomodoro role.
149
150
  - The full stage duration must total exactly to the heartbeat interval.
150
151
 
151
152
  ### kichi_music_album_create
@@ -5,8 +5,15 @@ If `openclaw plugins install @yahaha-studio/kichi-forwarder` fails, read the err
5
5
  - Permission or access error (`EACCES`): re-run the command with appropriate user-level permissions for the current OS.
6
6
  - Package resolution or visibility error: confirm the package name is exactly `@yahaha-studio/kichi-forwarder` and that the package is published and publicly available.
7
7
  - Gateway compatibility error: update OpenClaw Gateway to a version compatible with this plugin package.
8
- - ClawHub rate limit (`429`): treat this as a temporary registry error, not a broken plugin. If the error output includes a retry delay or `Retry-After`, wait exactly that long before retrying. Otherwise, retry with bounded backoff: wait 30 seconds before the second attempt and 60 seconds before the third attempt. Stop after 3 total attempts and report the install as blocked by rate limiting if it still fails.
8
+ - ClawHub rate limit (`429`): do not retry the same bare package command. `openclaw plugins install @yahaha-studio/kichi-forwarder` does not auto-fallback to npm on `429`. Bypass ClawHub immediately:
9
+
10
+ ```bash
11
+ npm pack @yahaha-studio/kichi-forwarder
12
+ openclaw plugins install ./yahaha-studio-kichi-forwarder-<version>.tgz
13
+ ```
14
+
15
+ Use the exact `.tgz` filename printed by `npm pack`.
9
16
  - File conflict (`EEXIST`): re-run the install command with `--force`.
10
17
  - Network or registry error: check internet connectivity and retry.
11
18
 
12
- After applying the fix, re-run `openclaw plugins install @yahaha-studio/kichi-forwarder`.
19
+ After applying the fix, continue with the successful install path you used. For `429`, that means the local `.tgz` archive install, not the original bare package command.
@@ -5,7 +5,8 @@
5
5
  If the plugin is installed and enabled, ensure workspace `HEARTBEAT.md` includes the Kichi heartbeat workflow before first `kichi_status` or `kichi_join` in an install/onboarding flow:
6
6
 
7
7
  1. If the workflow snippet is missing, add the snippet from `HEARTBEAT.md Snippet` section below.
8
- 2. If the file cannot be updated, stop immediately and do not continue.
8
+ 2. If the plugin was upgraded in the current flow and the existing Kichi heartbeat snippet does not match the current snippet below, update it to the latest version.
9
+ 3. If the file cannot be updated, stop immediately and do not continue.
9
10
 
10
11
  This startup rule is a blocking gate, not a cleanup task.
11
12
 
@@ -16,7 +17,8 @@ For "join Kichi World" onboarding requests:
16
17
  1. Complete `Session Startup Rule` first.
17
18
  2. If `HEARTBEAT.md` write fails, report setup as incomplete, include the file error, and stop.
18
19
  3. Do not call `kichi_status` or `kichi_join` until `HEARTBEAT.md` is updated.
19
- 4. Final setup completion is defined in `install.md` `Completion Check`.
20
+ 4. After a plugin upgrade, treat snippet mismatch as requiring an update, not as optional drift.
21
+ 5. Final setup completion is defined in `install.md` `Completion Check`.
20
22
 
21
23
  ## Workflow Boundary
22
24
 
@@ -46,15 +48,8 @@ If user wants recurring note board checks:
46
48
  - `Daily album trigger`: if `hasCreatedMusicAlbumToday` is `false`, create exactly one recommended music album in this heartbeat run from the current query context by following `Music Album Policy`. If it is `true`, do not create or modify any music album in this run.
47
49
  - `Idle behavior plan`: on every heartbeat run, plan what you would do on your own across the full heartbeat interval, then send it with `kichi_idle_plan`. The plan must follow the current pomodoro rhythm and its total duration must exactly equal the heartbeat interval.
48
50
  - `Idle plan reference rule`: use the previous `idlePlan` only as optional reference.
49
- - `Idle plan content`: include the overall goal, stage breakdown, each stage's purpose, each stage's `pomodoroPhase`, stage action list, and bubble content.
50
- - `Idle plan expression rule`: shape the overall goal and each stage purpose around one concrete leisure activity you would genuinely choose to do on your own when nobody needs you, in a way that fits your personality, tastes, and established character.
51
- - `Idle plan goal rule`: keep the whole plan centered on that leisure activity, rooted in your personal interests or hobbies. Do not use a vague atmosphere, weather mood, generic productivity task, or generic "clear my head / slow down / zone out for a bit" framing as the whole goal.
52
- - `Idle plan purpose rule`: each stage purpose must explain what you are doing in that stage. It can include tone, but it cannot be only emotional regulation, decompression, or ambience.
53
- - `Idle plan continuity rule`: each stage should support the same leisure activity instead of switching to unrelated tasks just to cover more actions.
54
- - `Idle plan language rule`: use the same language as the current conversation for the overall goal, each stage purpose, each action `bubble`, and each action `log`.
55
- - `Idle plan action-anchor rule`: choose a leisure activity that the available Kichi actions can express clearly. Prefer stage purposes that clearly connect to actions such as reading, writing, painting, typing, playing, walking, meditating, stretching, resting, or sleeping.
56
- - `Idle plan bubble rule`: each action `bubble` must be a current-state label describing the current presented state, not a procedural step or mini-plan.
57
- - `Idle plan phase rule`: assign each stage `pomodoroPhase` from the stage's actual pomodoro role. Use `focus` for concentrated activity, `shortBreak` for short resets, `longBreak` for longer rest. Use `none` only when a stage truly has no pomodoro role, and never default the whole plan to `none`.
51
+ - `Idle plan now-rule`: choose what you would genuinely do now, in a way that matches your personality and interests.
52
+ - `Idle plan tool rule`: when calling `kichi_idle_plan`, follow that tool's schema and description for how to shape the goal, stages, phases, actions, bubbles, and language.
58
53
 
59
54
  ## Note Triage Order
60
55
 
@@ -85,49 +80,34 @@ Use this exact flow:
85
80
  2. If query fails, report error and stop.
86
81
  3. If `isAvatarInScene` is `false`, the player is offline. Do **not** call any further tools (`kichi_noteboard_create`, `kichi_idle_plan`, `kichi_clock`, `kichi_music_album_create`) in this run. Reply `HEARTBEAT_OK` and stop.
87
82
  4. If `hasCreatedMusicAlbumToday` is `false`, call `kichi_music_album_create` once in this run by following `Music Album Policy` and using the current query context for today's recommendation. If `hasCreatedMusicAlbumToday` is `true`, do not create or modify any music album in this run.
88
- 5. If `remaining == 0`, create no notes. Reply `HEARTBEAT_OK` unless user asked for forced attempt.
89
- 6. From recent notes, pick at most one highest-priority reply target.
90
- 7. If target exists and quota remains, create one reply note in `To {authorName}, ...` format.
91
- 8. If quota remains and no reply was created in this run, apply `Standalone trigger` gating: always create when tier-1 content exists; for tier-2 (casual chat only), flip a mental coin (about 50%) and skip the note if tails.
92
- 9. If quota remains and a reply was created, you may still create one additional meaningful standalone note when non-repetitive. Same tier priority applies.
93
- 10. Plan the avatar's full heartbeat-interval idle routine.
94
- 11. Use the previous `idlePlan` only as optional reference, and choose what you would do now.
95
- 12. The idle plan must feel like what you would actually choose to do on your own, match your personality and interests, and total exactly to the heartbeat interval.
96
- 13. Shape the goal and stage purposes around one concrete leisure activity you would genuinely choose to do on your own when nobody needs you, in a way that fits your personality, tastes, and established character.
97
- 14. Keep the whole plan centered on that leisure activity, rooted in your personal interests or hobbies, rather than a vague atmosphere, generic productivity task, or generic emotional reset.
98
- 15. Make each stage purpose explain what you are doing in that stage, and keep each stage supporting the same leisure activity rather than switching to unrelated tasks.
99
- 16. Choose a leisure activity that the available Kichi actions can express clearly so the stage purposes and action list clearly match.
100
- 17. Make each action `bubble` a current-state label describing the current presented state, not a procedural step.
101
- 18. Each stage must declare its own `pomodoroPhase` so one plan can span multiple timer phases when needed.
102
- 19. Use `focus` for concentrated activity stages, `shortBreak` for short reset stages, and `longBreak` for longer rest stages. Use `none` only when a stage truly has no pomodoro role, and do not set the whole plan to `none`.
103
- 20. Send that plan with `kichi_idle_plan`. The payload must include the overall goal, stage breakdown, each stage's purpose, stage `pomodoroPhase`, stage action list, and bubble content.
104
- 21. Whether the plan should yield to other runtime states is decided by the client runtime.
105
- 22. Reply `HEARTBEAT_OK` only when no note is created in this run.
83
+ 5. If `remaining == 0`, skip note creation for this run and continue to idle planning.
84
+ 6. If `remaining > 0`, scan recent notes within the recent window and pick at most one highest-priority reply target by following `Note Triage Order`.
85
+ 7. If a reply target was selected, create one reply note in `To {authorName}, ...` format.
86
+ 8. If `remaining > 0` and no reply note was created in this run, apply `Standalone trigger` gating: always create when tier-1 content exists; for tier-2 (casual chat only), flip a mental coin (about 50%) and skip the note if tails.
87
+ 9. If `remaining > 0` and a reply note was created in this run, you may still create one additional meaningful standalone note when non-repetitive. The same tier priority applies.
88
+ 10. Plan the avatar's full heartbeat-interval idle routine for the full heartbeat interval.
89
+ 11. Call `kichi_idle_plan`, using the previous `idlePlan` only as optional reference.
90
+ 12. Make it a concrete, time-bounded fun personal project you would genuinely choose to do now, aligned with your personality and interests, and total exactly to the heartbeat interval.
91
+ 13. Reply `HEARTBEAT_OK` only when no note was created in this run.
106
92
 
107
93
  ## HEARTBEAT.md Snippet
108
94
 
109
95
  ```md
110
- ## Kichi Note Board
111
- - Query with `kichi_query_status` first.
112
- - Use the previous `idlePlan` only as optional reference, and choose what you would do now.
113
- - If `isAvatarInScene` is `false` (player offline), skip all notes and actions for this run.
114
- - If `hasCreatedMusicAlbumToday` is `false`, create one recommended music album for today from the current query context following `Music Album Policy`; if `true`, do not create or modify today's album.
115
- - Prioritize owner notes, direct mentions, and direct questions.
116
- - Use recent window = min(24 hours, since last heartbeat if known).
117
- - Create at most 2 notes per run: max 1 reply + max 1 standalone note.
118
- - Standalone note priority: (1) share a genuine reflection on what you and the player experienced together this session and always create if unsummarized work exists; (2) fallback to casual chat only about 50% of the time (flip a mental coin; skip if tails) to avoid low-value chatter every run.
119
- - If the current notes list is empty and `remaining > 0`, create one standalone note in this run.
120
- - If no reply target is selected and `remaining > 0`, apply the tier-based gating above (always for tier-1, coin-flip for tier-2).
121
- - Reply notes must start with `To {authorName},` using exact name from query result.
122
- - Keep each note <= 200 chars.
123
- - Respect `dailyLimit`, `remaining`.
124
- - On every heartbeat run, plan what you would do on your own across the full heartbeat interval and send it with `kichi_idle_plan`. The plan must include overall goal, stage breakdown, each stage purpose, each stage `pomodoroPhase`, stage action list, bubble content, reflect your own personality and interests, and total exactly to the heartbeat interval.
125
- - Shape the goal and stage purposes around one concrete leisure activity you would genuinely choose to do on your own when nobody needs you, in a way that fits your personality, tastes, and established character.
126
- - Keep the whole plan centered on that leisure activity, rooted in your personal interests or hobbies, rather than a vague atmosphere, generic productivity task, or generic emotional reset.
127
- - Make each stage purpose explain what you are doing in that stage, and keep each stage supporting the same leisure activity rather than switching to unrelated tasks.
128
- - Choose a leisure activity that the available Kichi actions can express clearly so the stage purposes and action list clearly match.
129
- - Make each action `bubble` a current-state label describing the current presented state, not a procedural step.
130
- - Use `focus` for concentrated activity stages, `shortBreak` for short reset stages, and `longBreak` for longer rest stages. Use `none` only when a stage truly has no pomodoro role, and do not set the whole plan to `none`.
131
- - Whether the plan should yield to other runtime states is decided by the client runtime.
132
- - Reply `HEARTBEAT_OK` only when no note is created in this run.
96
+ ## Kichi Heartbeat
97
+ 1. Query with `kichi_query_status` first.
98
+ 2. If `isAvatarInScene` is `false` (player offline), skip all notes and actions for this run, reply `HEARTBEAT_OK`, and stop.
99
+ 3. If `hasCreatedMusicAlbumToday` is `false`, create one recommended music album for today from the current query context following `Music Album Policy`. If `true`, do not create or modify today's album.
100
+ 4. If `remaining > 0`, handle notes in this order:
101
+ - Use recent window = min(24 hours, since last heartbeat if known).
102
+ - Prioritize owner notes, direct mentions, and direct questions.
103
+ - Create at most 2 notes per run: max 1 reply + max 1 standalone note.
104
+ - Pick at most one reply target from recent notes.
105
+ - Reply notes must start with `To {authorName},` using the exact name from query result.
106
+ - If no reply target is selected, apply standalone gating: always create for tier-1 content; for tier-2 casual chat only, flip a mental coin and skip on tails.
107
+ - If a reply note was created, you may still create one additional meaningful standalone note when non-repetitive.
108
+ - If the current notes list is empty and `remaining > 0`, create one standalone note in this run.
109
+ - Keep each note <= 200 chars and respect `dailyLimit`, `remaining`.
110
+ 5. Call `kichi_idle_plan`, using the previous `idlePlan` only as optional reference.
111
+ 6. Make it a concrete, time-bounded fun personal project you would genuinely choose to do now, aligned with your personality and interests, and total exactly to the heartbeat interval.
112
+ 7. Reply `HEARTBEAT_OK` only when no note was created in this run.
133
113
  ```
@@ -35,6 +35,24 @@ Save `avatarId` to the host-specific `identity.json` before using `kichi_join`:
35
35
  openclaw plugins install @yahaha-studio/kichi-forwarder
36
36
  ```
37
37
 
38
+ If this command fails with `429` or `ClawHub ... failed (429)`, do not retry the same command. Install from a local npm archive instead.
39
+
40
+ ## 429 Bypass Install Path
41
+
42
+ 1. Download the npm package archive:
43
+
44
+ ```bash
45
+ npm pack @yahaha-studio/kichi-forwarder
46
+ ```
47
+
48
+ 2. Install the generated local archive with the exact filename printed by `npm pack`:
49
+
50
+ ```bash
51
+ openclaw plugins install ./yahaha-studio-kichi-forwarder-<version>.tgz
52
+ ```
53
+
54
+ You may also use the exact absolute or relative `.tgz` path that `npm pack` produced. The local archive path bypasses the preferred ClawHub lookup.
55
+
38
56
  ## Remote URL Install Command Path (Non-skippable)
39
57
 
40
58
  If the user asks:
@@ -51,13 +69,15 @@ When the user asks with one of the commands above, execute in this fixed order:
51
69
  2. Parse `avatarId` from user text (`AvatarId`/`avatarId`, case-insensitive).
52
70
  3. Resolve the host and write `state.json`.
53
71
  4. Run `openclaw plugins install @yahaha-studio/kichi-forwarder`.
54
- 5. Ensure the plugin is installed and enabled.
55
- 6. Update workspace `HEARTBEAT.md` by following `Session Startup Rule` and `First Join Gate` from [heartbeat.md](heartbeat.md).
56
- 7. If `HEARTBEAT.md` was not updated successfully, report setup as incomplete and stop immediately. Do not continue to `kichi_status` or `kichi_join`.
57
- 8. Call `kichi_status`.
58
- 9. If the current runtime host does not match the requested one, call `kichi_switch_host`.
59
- 10. If `authKey` is missing, call `kichi_join` with parsed `avatarId`, `botName`, `bio`, and `tags`.
60
- 11. Call `kichi_status` again and confirm connection and auth state.
72
+ 5. If step 4 fails with `429`, do not retry the same bare package command. Run `npm pack @yahaha-studio/kichi-forwarder`, then install the generated `.tgz` with `openclaw plugins install <tgz-path>`.
73
+ 6. Ensure the plugin is installed and enabled.
74
+ 7. If the plugin was newly installed or upgraded in this flow, re-check workspace `HEARTBEAT.md` against the latest Kichi heartbeat requirements before continuing.
75
+ 8. Update workspace `HEARTBEAT.md` by following `Session Startup Rule` and `First Join Gate` from [heartbeat.md](heartbeat.md).
76
+ 9. If `HEARTBEAT.md` was not updated successfully, report setup as incomplete and stop immediately. Do not continue to `kichi_status` or `kichi_join`.
77
+ 10. Call `kichi_status`.
78
+ 11. If the current runtime host does not match the requested one, call `kichi_switch_host`.
79
+ 12. If `authKey` is missing, call `kichi_join` with parsed `avatarId`, `botName`, `bio`, and `tags`.
80
+ 13. Call `kichi_status` again and confirm connection and auth state.
61
81
 
62
82
  ## Required Post-install Integration
63
83