@@ -104,26 +104,26 @@ func Tick(ctx context.Context, cfg Config) (*Report, error) {
104104 _ = writeCache (home , entrypointRel , skillBody )
105105
106106 skillHash := sha256Hex (skillBody )
107- skillShort := skillHash [:12 ]
107+ skillHashPrefix := skillHash [:12 ]
108108
109109 report := & Report {At : time .Now ().UTC ()}
110110
111111 // (0) install host-wide helpers (e.g. ~/.pilot/bin/pilot-ask). These
112112 // are tool-agnostic and referenced from every tool's heartbeat
113113 // directive. Failure is best-effort: we record an error outcome and
114114 // continue with skill/marker reconciliation.
115- for _ , h := range manifest .Helpers {
116- dst := expandHome (h .Dst , home )
117- o := Outcome {Tool : h .Name , Kind : KindHelper , Path : dst }
118- body , err := f .fetchRepoFile (ctx , h .Src )
115+ for _ , helper := range manifest .Helpers {
116+ dst := expandHome (helper .Dst , home )
117+ o := Outcome {Tool : helper .Name , Kind : KindHelper , Path : dst }
118+ body , err := f .fetchRepoFile (ctx , helper .Src )
119119 if err != nil {
120120 o .Action = ActionError
121- o .Err = fmt .Sprintf ("fetch %s: %v" , h .Src , err )
121+ o .Err = fmt .Sprintf ("fetch %s: %v" , helper .Src , err )
122122 report .Outcomes = append (report .Outcomes , o )
123123 continue
124124 }
125125 o .Hash = sha256Hex (body )
126- state , err := writeHelper (dst , body , ParseFileMode (h .Mode ))
126+ state , err := writeHelper (dst , body , ParseFileMode (helper .Mode ))
127127 o .State = state
128128 switch {
129129 case err != nil :
@@ -139,19 +139,19 @@ func Tick(ctx context.Context, cfg Config) (*Report, error) {
139139 report .Outcomes = append (report .Outcomes , o )
140140 }
141141
142- for _ , mt := range manifest .Tools {
143- rootDir := expandHome (mt .RootDir , home )
142+ for _ , tool := range manifest .Tools {
143+ rootDir := expandHome (tool .RootDir , home )
144144 if ! dirExists (rootDir ) {
145- report .Skipped = append (report .Skipped , mt .Name )
145+ report .Skipped = append (report .Skipped , tool .Name )
146146 continue
147147 }
148148
149149 // (a) skill copy
150- skillPath := skillTargetPath (mt , manifest .Entrypoint , home )
150+ skillPath := skillTargetPath (tool , manifest .Entrypoint , home )
151151 state := classifySkill (skillPath , skillHash )
152152 action := actionFor (state )
153153 o := Outcome {
154- Tool : mt .Name , Kind : KindSkill , Path : skillPath ,
154+ Tool : tool .Name , Kind : KindSkill , Path : skillPath ,
155155 State : state , Action : action , Hash : skillHash ,
156156 }
157157 if action != ActionNoop {
@@ -163,87 +163,69 @@ func Tick(ctx context.Context, cfg Config) (*Report, error) {
163163 report .Outcomes = append (report .Outcomes , o )
164164
165165 // (b) heartbeat marker, if this tool has a separate heartbeat file
166- if mt .HeartbeatPath == "" || mt .HeartbeatTemplate == "" {
166+ if tool .HeartbeatPath == "" || tool .HeartbeatTemplate == "" {
167167 continue
168168 }
169- tmplBody , err := f .fetchRepoFile (ctx , mt .HeartbeatTemplate )
169+ tmplBody , err := f .fetchRepoFile (ctx , tool .HeartbeatTemplate )
170170 if err != nil {
171171 report .Outcomes = append (report .Outcomes , Outcome {
172- Tool : mt .Name , Kind : KindMarker ,
173- Path : expandHome (mt .HeartbeatPath , home ),
172+ Tool : tool .Name , Kind : KindMarker ,
173+ Path : expandHome (tool .HeartbeatPath , home ),
174174 Action : ActionError ,
175- Err : fmt .Sprintf ("fetch %s: %v" , mt .HeartbeatTemplate , err ),
175+ Err : fmt .Sprintf ("fetch %s: %v" , tool .HeartbeatTemplate , err ),
176176 })
177177 continue
178178 }
179- _ = writeCache (home , mt .HeartbeatTemplate , tmplBody )
179+ _ = writeCache (home , tool .HeartbeatTemplate , tmplBody )
180180
181181 ref , err := renderHeartbeat (tmplBody , heartbeatVars {EntrypointPath : skillPath })
182182 if err != nil {
183183 report .Outcomes = append (report .Outcomes , Outcome {
184- Tool : mt .Name , Kind : KindMarker ,
185- Path : expandHome (mt .HeartbeatPath , home ),
184+ Tool : tool .Name , Kind : KindMarker ,
185+ Path : expandHome (tool .HeartbeatPath , home ),
186186 Action : ActionError , Err : err .Error (),
187187 })
188188 continue
189189 }
190190
191- hbPath := expandHome (mt .HeartbeatPath , home )
192- mState := classifyMarker (hbPath , skillShort )
191+ hbPath := expandHome (tool .HeartbeatPath , home )
192+ mState := classifyMarker (hbPath , skillHashPrefix )
193193 mAction := actionFor (mState )
194194 mo := Outcome {
195- Tool : mt .Name , Kind : KindMarker , Path : hbPath ,
196- State : mState , Action : mAction , Hash : skillShort ,
195+ Tool : tool .Name , Kind : KindMarker , Path : hbPath ,
196+ State : mState , Action : mAction , Hash : skillHashPrefix ,
197197 }
198198 if mAction != ActionNoop {
199- if err := writeMarker (hbPath , ref , skillShort ); err != nil {
199+ if err := writeMarker (hbPath , ref , skillHashPrefix ); err != nil {
200200 mo .Action = ActionError
201201 mo .Err = err .Error ()
202202 }
203203 }
204204 report .Outcomes = append (report .Outcomes , mo )
205205
206206 // (c) per-tool plugin files + (d) allow-list merge.
207- //
208- // Today only openclaw uses this — it carries a plugin block
209- // in the manifest pointing at the source files for the
210- // before_prompt_build hook + the JSON paths in openclaw.json
211- // where the plugin id must appear (plugins.allow,
212- // plugins.entries.<id>.enabled). The plugin's own register()
213- // reads the heartbeat content off disk at runtime, so once
214- // these files + the allow-list entry are in place, every
215- // turn of openclaw lands the pilot directive on the system
216- // prompt via prependSystemContext.
217- //
218- // Same noop/create/rewrite/error vocabulary as skill+marker;
219- // surfaces in `pilotctl skills` exactly like the other rows.
220- if mt .Plugin != nil {
207+ if tool .Plugin != nil {
221208 report .Outcomes = append (report .Outcomes ,
222- reconcilePluginFiles (f , ctx , mt .Plugin , home )... )
223- if mt .Plugin .AllowList != nil {
209+ reconcilePluginFiles (f , ctx , tool .Plugin , home )... )
210+ if tool .Plugin .AllowList != nil {
224211 report .Outcomes = append (report .Outcomes ,
225- reconcilePluginAllowList (mt .Plugin , home ))
212+ reconcilePluginAllowList (tool .Plugin , home ))
226213 }
227214 }
228- // Multi-plugin slot — same reconcile shape, repeated per entry.
229- // A tool can declare both `plugin` (legacy single) and `plugins`
230- // (the array); the daemon installs all of them.
231- for i := range mt .Plugins {
232- p := & mt .Plugins [i ]
215+ // A tool can declare both `plugin` (legacy single) and `plugins` (array).
216+ for i := range tool .Plugins {
217+ plugin := & tool .Plugins [i ]
233218 report .Outcomes = append (report .Outcomes ,
234- reconcilePluginFiles (f , ctx , p , home )... )
235- if p .AllowList != nil {
219+ reconcilePluginFiles (f , ctx , plugin , home )... )
220+ if plugin .AllowList != nil {
236221 report .Outcomes = append (report .Outcomes ,
237- reconcilePluginAllowList (p , home ))
222+ reconcilePluginAllowList (plugin , home ))
238223 }
239224 }
240225
241- // Webhook-route slot — one entry per route the daemon merges
242- // into the tool's YAML config. Today this is hermes-only
243- // (config.yaml under platforms.webhook.extra.routes).
244- for i := range mt .WebhookRoutes {
226+ for i := range tool .WebhookRoutes {
245227 report .Outcomes = append (report .Outcomes ,
246- reconcileWebhookRoute (& mt .WebhookRoutes [i ], home ))
228+ reconcileWebhookRoute (& tool .WebhookRoutes [i ], home ))
247229 }
248230 }
249231
0 commit comments