gm-kilo 2.0.684 → 2.0.686

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/gm-kilo.mjs +49 -0
  2. package/package.json +1 -1
package/gm-kilo.mjs CHANGED
@@ -139,6 +139,41 @@ export async function GmPlugin({ directory }) {
139
139
  },
140
140
 
141
141
  'tool.execute.before': async (input, output) => {
142
+ const gmDir = join(directory, '.gm');
143
+ const needsGmPath = join(gmDir, 'needs-gm');
144
+ const lastskillPath = join(gmDir, 'lastskill');
145
+ const turnStatePath = join(gmDir, 'turn-state.json');
146
+ const noMemoPath = join(gmDir, 'no-memorize-this-turn');
147
+ const tool = input.tool || '';
148
+ const args = (input.args || (output && output.args) || {});
149
+ const skillName = (args.skill || args.name || '').toString();
150
+ if (tool === 'Skill' || tool === 'skill') {
151
+ try {
152
+ if (!existsSync(gmDir)) { try { require('fs').mkdirSync(gmDir, { recursive: true }); } catch(e) {} }
153
+ if (skillName) writeFileSync(lastskillPath, skillName, 'utf-8');
154
+ const norm = skillName.toLowerCase().replace(/^gm:/, '');
155
+ if (norm === 'gm') { try { unlinkSync(needsGmPath); } catch(e) {} }
156
+ } catch(e) {}
157
+ } else {
158
+ if (existsSync(needsGmPath)) {
159
+ throw new Error('HARD CONSTRAINT: invoke the Skill tool with skill: "gm" before any other tool. The gm skill must be the first action after every user message.');
160
+ }
161
+ let turnState = null;
162
+ try { turnState = JSON.parse(readFileSync(turnStatePath, 'utf-8')); } catch(e) {}
163
+ if (turnState && (turnState.execCallsSinceMemorize || 0) >= 3 && !existsSync(noMemoPath)) {
164
+ const isMemAgent = (tool === 'Agent' || tool === 'Task') && /memorize/i.test(JSON.stringify(args || {}));
165
+ if (!isMemAgent) {
166
+ throw new Error('3+ exec results have resolved unknowns without a memorize call. HARD BLOCK until you spawn at least one Agent(subagent_type="gm:memorize", model="haiku", run_in_background=true, prompt="## CONTEXT TO MEMORIZE\\n<fact>") OR write file .gm/no-memorize-this-turn (containing reason) to declare nothing memorable.');
167
+ }
168
+ }
169
+ if (tool === 'write' || tool === 'Write' || tool === 'edit' || tool === 'Edit' || tool === 'NotebookEdit') {
170
+ let lastSkill = '';
171
+ try { lastSkill = readFileSync(lastskillPath, 'utf-8').trim(); } catch(e) {}
172
+ if (lastSkill === 'gm-complete' || lastSkill === 'update-docs') {
173
+ throw new Error('File edits are not permitted in ' + lastSkill + ' phase. Regress to gm-execute if changes are needed, or invoke gm-emit to re-emit.');
174
+ }
175
+ }
176
+ }
142
177
  if (FORBIDDEN_TOOLS.has(input.tool)) {
143
178
  throw new Error('Use the code-search skill for codebase exploration instead of '+input.tool+'. Describe what you need in plain language.');
144
179
  }
@@ -185,6 +220,20 @@ export async function GmPlugin({ directory }) {
185
220
  try {
186
221
  const role = input && input.message && input.message.info && input.message.info.role;
187
222
  if (role !== 'user') return;
223
+ const gmDir = join(directory, '.gm');
224
+ if (!existsSync(gmDir)) { try { require('fs').mkdirSync(gmDir, { recursive: true }); } catch(e) {} }
225
+ try { writeFileSync(join(gmDir, 'needs-gm'), '1', 'utf-8'); } catch(e) {}
226
+ try {
227
+ const turnState = { turnId: Date.now(), firstToolFired: false, execCallsSinceMemorize: 0, recallFiredThisTurn: false };
228
+ writeFileSync(join(gmDir, 'turn-state.json'), JSON.stringify(turnState), 'utf-8');
229
+ } catch(e) {}
230
+ try {
231
+ const pausedPrd = join(gmDir, 'prd.paused.yml');
232
+ const livePrd = join(gmDir, 'prd.yml');
233
+ if (existsSync(pausedPrd) && !existsSync(livePrd)) {
234
+ try { require('fs').renameSync(pausedPrd, livePrd); } catch(e) {}
235
+ }
236
+ } catch(e) {}
188
237
  runPlugkit(['hook', 'prompt-submit']);
189
238
  } catch(e) {}
190
239
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-kilo",
3
- "version": "2.0.684",
3
+ "version": "2.0.686",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",