opencode-immune 1.0.28 → 1.0.29

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/plugin.js +85 -8
  2. package/package.json +1 -1
package/dist/plugin.js CHANGED
@@ -1277,8 +1277,77 @@ const PRE_COMMIT_MARKER = "0-ULTRAWORK: PRE_COMMIT";
1277
1277
  const CYCLE_COMPLETE_MARKER = "0-ULTRAWORK: CYCLE_COMPLETE";
1278
1278
  const NEXT_TASK_PATTERN = /Next task:\s*(.+)/;
1279
1279
  const ALL_CYCLES_COMPLETE_MARKER = "0-ULTRAWORK: ALL_CYCLES_COMPLETE";
1280
+ // Default commit prompt — used when user's /commit command file is not found
1281
+ const DEFAULT_COMMIT_PROMPT = `Review the staged changes using \`git diff --cached\` and create a commit.
1282
+
1283
+ If there are no staged changes, check \`git status\` for unstaged changes and stage the relevant files first.
1284
+
1285
+ The commit message MUST follow this structure:
1286
+ 1. First line: short description (<50 chars) prefixed with feat:/fix:/refactor:
1287
+ 2. Second line: empty
1288
+ 3. Body: concise bullet points describing significant changes
1289
+
1290
+ Create the commit using \`git commit -m\` with the properly formatted message.`;
1280
1291
  /**
1281
- * Helper: run git commit in the project directory.
1292
+ * Load the /commit command prompt from user's global config.
1293
+ * Falls back to DEFAULT_COMMIT_PROMPT if file doesn't exist.
1294
+ */
1295
+ async function loadCommitPrompt() {
1296
+ try {
1297
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
1298
+ const commandPath = (0, path_1.join)(home, ".config", "opencode", "commands", "commit.md");
1299
+ const content = await (0, promises_1.readFile)(commandPath, "utf-8");
1300
+ // Strip YAML frontmatter (--- ... ---)
1301
+ const stripped = content.replace(/^---[\s\S]*?---\s*/, "").trim();
1302
+ return stripped || DEFAULT_COMMIT_PROMPT;
1303
+ }
1304
+ catch {
1305
+ return DEFAULT_COMMIT_PROMPT;
1306
+ }
1307
+ }
1308
+ /**
1309
+ * Execute a commit by sending the /commit prompt to a new session.
1310
+ * The agent will analyze the diff and create a proper commit message.
1311
+ * Returns true if the prompt was sent successfully.
1312
+ */
1313
+ async function runSmartCommit(state) {
1314
+ try {
1315
+ const commitPrompt = await loadCommitPrompt();
1316
+ // Create a dedicated session for the commit
1317
+ const createResult = await state.input.client.session.create({
1318
+ body: {
1319
+ title: "Auto-commit (ultrawork cycle)",
1320
+ },
1321
+ });
1322
+ const sessionData = createResult?.data;
1323
+ const commitSessionID = sessionData?.id;
1324
+ if (!commitSessionID) {
1325
+ console.error("[opencode-immune] Smart commit: failed to create session.");
1326
+ return false;
1327
+ }
1328
+ console.log(`[opencode-immune] Smart commit: session created ${commitSessionID}, sending commit prompt...`);
1329
+ // Send commit prompt and wait for completion (sync prompt, not async)
1330
+ await state.input.client.session.prompt({
1331
+ body: {
1332
+ parts: [
1333
+ {
1334
+ type: "text",
1335
+ text: commitPrompt,
1336
+ },
1337
+ ],
1338
+ },
1339
+ path: { id: commitSessionID },
1340
+ });
1341
+ console.log("[opencode-immune] Smart commit: completed.");
1342
+ return true;
1343
+ }
1344
+ catch (err) {
1345
+ console.error("[opencode-immune] Smart commit failed:", err);
1346
+ return false;
1347
+ }
1348
+ }
1349
+ /**
1350
+ * Helper: run git commit in the project directory (fallback).
1282
1351
  * Uses execFile for safety (no shell injection).
1283
1352
  * Returns true if commit succeeded, false otherwise.
1284
1353
  */
@@ -1336,12 +1405,16 @@ function createTextCompleteHandler(state) {
1336
1405
  if (text.includes(PRE_COMMIT_MARKER) && !text.includes(CYCLE_COMPLETE_MARKER)) {
1337
1406
  if (!state.commitPending) {
1338
1407
  state.commitPending = true;
1339
- console.log("[opencode-immune] Multi-Cycle: PRE_COMMIT detected (standalone), running git commit...");
1408
+ console.log("[opencode-immune] Multi-Cycle: PRE_COMMIT detected (standalone), running smart commit...");
1340
1409
  try {
1341
- await runGitCommit(state.input.directory, "chore: ultrawork cycle auto-commit");
1410
+ const ok = await runSmartCommit(state);
1411
+ if (!ok) {
1412
+ console.log("[opencode-immune] Multi-Cycle: smart commit failed, falling back to git commit...");
1413
+ await runGitCommit(state.input.directory, "chore: ultrawork cycle auto-commit");
1414
+ }
1342
1415
  }
1343
1416
  catch (err) {
1344
- console.error("[opencode-immune] Multi-Cycle: git commit failed (standalone):", err);
1417
+ console.error("[opencode-immune] Multi-Cycle: commit failed (standalone):", err);
1345
1418
  }
1346
1419
  finally {
1347
1420
  state.commitPending = false;
@@ -1354,13 +1427,17 @@ function createTextCompleteHandler(state) {
1354
1427
  // Step 1: Always commit first (CYCLE_COMPLETE implies end of cycle)
1355
1428
  if (!state.commitPending) {
1356
1429
  state.commitPending = true;
1357
- console.log("[opencode-immune] Multi-Cycle: CYCLE_COMPLETE detected, running git commit first...");
1430
+ console.log("[opencode-immune] Multi-Cycle: CYCLE_COMPLETE detected, running smart commit first...");
1358
1431
  try {
1359
- await runGitCommit(state.input.directory, "chore: ultrawork cycle auto-commit");
1360
- console.log("[opencode-immune] Multi-Cycle: git commit completed before new cycle.");
1432
+ const ok = await runSmartCommit(state);
1433
+ if (!ok) {
1434
+ console.log("[opencode-immune] Multi-Cycle: smart commit failed, falling back to git commit...");
1435
+ await runGitCommit(state.input.directory, "chore: ultrawork cycle auto-commit");
1436
+ }
1437
+ console.log("[opencode-immune] Multi-Cycle: commit completed before new cycle.");
1361
1438
  }
1362
1439
  catch (err) {
1363
- console.error("[opencode-immune] Multi-Cycle: git commit failed (continuing anyway):", err);
1440
+ console.error("[opencode-immune] Multi-Cycle: commit failed (continuing anyway):", err);
1364
1441
  }
1365
1442
  finally {
1366
1443
  state.commitPending = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-immune",
3
- "version": "1.0.28",
3
+ "version": "1.0.29",
4
4
  "description": "OpenCode plugin: session recovery, auto-retry, multi-cycle automation, context monitoring",
5
5
  "exports": {
6
6
  "./server": "./dist/plugin.js"