@damian87/omp 0.4.1 → 0.6.0

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 (90) hide show
  1. package/.github/agents/researcher.md +7 -6
  2. package/.github/copilot-instructions.md +23 -0
  3. package/.github/skills/daily-log/SKILL.md +64 -0
  4. package/.github/skills/goal/SKILL.md +33 -0
  5. package/.github/skills/schedule/SKILL.md +71 -0
  6. package/README.md +19 -2
  7. package/dist/src/cli.js +272 -9
  8. package/dist/src/cli.js.map +1 -1
  9. package/dist/src/comms/index.d.ts +116 -0
  10. package/dist/src/comms/index.js +258 -0
  11. package/dist/src/comms/index.js.map +1 -0
  12. package/dist/src/comms/resolve-session.d.ts +35 -0
  13. package/dist/src/comms/resolve-session.js +53 -0
  14. package/dist/src/comms/resolve-session.js.map +1 -0
  15. package/dist/src/daily-log.d.ts +18 -0
  16. package/dist/src/daily-log.js +138 -0
  17. package/dist/src/daily-log.js.map +1 -0
  18. package/dist/src/goal.d.ts +4 -0
  19. package/dist/src/goal.js +44 -0
  20. package/dist/src/goal.js.map +1 -0
  21. package/dist/src/instructions-memory.d.ts +9 -0
  22. package/dist/src/instructions-memory.js +72 -0
  23. package/dist/src/instructions-memory.js.map +1 -0
  24. package/dist/src/mcp/tools/daily-log.d.ts +2 -0
  25. package/dist/src/mcp/tools/daily-log.js +148 -0
  26. package/dist/src/mcp/tools/daily-log.js.map +1 -0
  27. package/dist/src/omp-root.d.ts +1 -0
  28. package/dist/src/omp-root.js +19 -0
  29. package/dist/src/omp-root.js.map +1 -0
  30. package/dist/src/project-memory.d.ts +13 -0
  31. package/dist/src/project-memory.js +105 -0
  32. package/dist/src/project-memory.js.map +1 -0
  33. package/dist/src/schedule/commands.d.ts +34 -0
  34. package/dist/src/schedule/commands.js +130 -0
  35. package/dist/src/schedule/commands.js.map +1 -0
  36. package/dist/src/schedule/installer.d.ts +20 -0
  37. package/dist/src/schedule/installer.js +76 -0
  38. package/dist/src/schedule/installer.js.map +1 -0
  39. package/dist/src/schedule/installers/crontab.d.ts +17 -0
  40. package/dist/src/schedule/installers/crontab.js +112 -0
  41. package/dist/src/schedule/installers/crontab.js.map +1 -0
  42. package/dist/src/schedule/installers/launchd.d.ts +22 -0
  43. package/dist/src/schedule/installers/launchd.js +125 -0
  44. package/dist/src/schedule/installers/launchd.js.map +1 -0
  45. package/dist/src/schedule/installers/systemd.d.ts +15 -0
  46. package/dist/src/schedule/installers/systemd.js +136 -0
  47. package/dist/src/schedule/installers/systemd.js.map +1 -0
  48. package/dist/src/schedule/job-store.d.ts +21 -0
  49. package/dist/src/schedule/job-store.js +102 -0
  50. package/dist/src/schedule/job-store.js.map +1 -0
  51. package/dist/src/schedule/lock.d.ts +9 -0
  52. package/dist/src/schedule/lock.js +83 -0
  53. package/dist/src/schedule/lock.js.map +1 -0
  54. package/dist/src/schedule/paths.d.ts +15 -0
  55. package/dist/src/schedule/paths.js +36 -0
  56. package/dist/src/schedule/paths.js.map +1 -0
  57. package/dist/src/schedule/runner.d.ts +8 -0
  58. package/dist/src/schedule/runner.js +151 -0
  59. package/dist/src/schedule/runner.js.map +1 -0
  60. package/dist/src/schedule/types.d.ts +60 -0
  61. package/dist/src/schedule/types.js +5 -0
  62. package/dist/src/schedule/types.js.map +1 -0
  63. package/dist/src/state.d.ts +17 -0
  64. package/dist/src/state.js +101 -0
  65. package/dist/src/state.js.map +1 -0
  66. package/dist/src/trace.d.ts +19 -0
  67. package/dist/src/trace.js +74 -0
  68. package/dist/src/trace.js.map +1 -0
  69. package/dist/test/catalog.test.d.ts +1 -0
  70. package/dist/test/catalog.test.js +21 -0
  71. package/dist/test/catalog.test.js.map +1 -0
  72. package/dist/test/jira.test.d.ts +1 -0
  73. package/dist/test/jira.test.js +26 -0
  74. package/dist/test/jira.test.js.map +1 -0
  75. package/dist/test/lint.test.d.ts +1 -0
  76. package/dist/test/lint.test.js +9 -0
  77. package/dist/test/lint.test.js.map +1 -0
  78. package/dist/test/sync.test.d.ts +1 -0
  79. package/dist/test/sync.test.js +15 -0
  80. package/dist/test/sync.test.js.map +1 -0
  81. package/docs/research/2026-06-01-schedule-cron-feature.md +346 -0
  82. package/package.json +1 -1
  83. package/scripts/lib/daily-log.mjs +155 -0
  84. package/scripts/lib/hook-output.mjs +2 -1
  85. package/scripts/lib/omp-root.mjs +15 -0
  86. package/scripts/lib/project-memory.mjs +21 -0
  87. package/scripts/lib/schedule-results.mjs +88 -0
  88. package/scripts/prompt-submit.mjs +14 -2
  89. package/scripts/session-end.mjs +6 -1
  90. package/scripts/session-start.mjs +60 -2
@@ -2,6 +2,8 @@
2
2
  import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { readStdin } from "./lib/stdin.mjs";
5
+ import { recordPrompt } from "./lib/daily-log.mjs";
6
+ import { ompRoot } from "./lib/omp-root.mjs";
5
7
 
6
8
  const HOOK_NAME = "UserPromptSubmit";
7
9
 
@@ -34,7 +36,7 @@ function buildContinuationContext(directory) {
34
36
  }
35
37
 
36
38
  function appendLog(directory, payload) {
37
- const logFile = join(directory, ".omp", "state", "hooks.log");
39
+ const logFile = join(ompRoot(directory), ".omp", "state", "hooks.log");
38
40
  try {
39
41
  mkdirSync(dirname(logFile), { recursive: true });
40
42
  appendFileSync(
@@ -54,7 +56,17 @@ function appendLog(directory, payload) {
54
56
  const directory = data.directory ?? process.cwd();
55
57
  const prompt = data.prompt ?? data.message?.content ?? "";
56
58
  appendLog(directory, { sessionId, promptBytes: String(prompt).length });
57
- const additionalContext = buildContinuationContext(directory);
59
+ // Count this prompt as session work (signals the SessionEnd nudge logic).
60
+ // Injects nothing — keeps per-turn token cost at zero.
61
+ try {
62
+ recordPrompt(directory);
63
+ } catch {
64
+ // best effort: counting must never block the prompt
65
+ }
66
+ const parts = [];
67
+ const cont = buildContinuationContext(directory);
68
+ if (cont) parts.push(cont);
69
+ const additionalContext = parts.join("\n\n---\n\n");
58
70
  const output = additionalContext
59
71
  ? { continue: true, hookSpecificOutput: { hookEventName: HOOK_NAME, additionalContext } }
60
72
  : { continue: true };
@@ -2,6 +2,8 @@
2
2
  import { appendFileSync, mkdirSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { readStdin } from "./lib/stdin.mjs";
5
+ import { endSession } from "./lib/daily-log.mjs";
6
+ import { ompRoot } from "./lib/omp-root.mjs";
5
7
 
6
8
  const HOOK_NAME = "SessionEnd";
7
9
 
@@ -11,7 +13,7 @@ const HOOK_NAME = "SessionEnd";
11
13
  const data = raw ? JSON.parse(raw) : {};
12
14
  const sessionId = data.sessionId ?? data.session_id ?? "unknown";
13
15
  const directory = data.directory ?? process.cwd();
14
- const logFile = join(directory, ".omp", "state", "hooks.log");
16
+ const logFile = join(ompRoot(directory), ".omp", "state", "hooks.log");
15
17
  try {
16
18
  mkdirSync(dirname(logFile), { recursive: true });
17
19
  appendFileSync(
@@ -21,6 +23,9 @@ const HOOK_NAME = "SessionEnd";
21
23
  } catch {
22
24
  // best effort
23
25
  }
26
+ // Arm a daily-log nudge for the next session if this one did work but
27
+ // logged nothing. endSession never throws.
28
+ endSession(directory);
24
29
  console.log(JSON.stringify({ continue: true }));
25
30
  } catch (err) {
26
31
  console.error(`[hook ${HOOK_NAME}] failed: ${err?.message ?? err}`);
@@ -3,16 +3,37 @@ import { appendFileSync, mkdirSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { readStdin } from "./lib/stdin.mjs";
5
5
  import { checkForUpdate, formatUpdateNotice } from "./lib/version-check.mjs";
6
+ import { scanScheduleResults } from "./lib/schedule-results.mjs";
7
+ import { readRepoGoal, readTodayGoal, recentEntryStats, startSession } from "./lib/daily-log.mjs";
8
+ import { readDirectives } from "./lib/project-memory.mjs";
9
+ import { ompRoot } from "./lib/omp-root.mjs";
6
10
 
7
11
  const HOOK_NAME = "SessionStart";
8
12
 
13
+ function buildDailyLogBreadcrumb(directory) {
14
+ try {
15
+ const goal = readTodayGoal(directory);
16
+ const { entries } = recentEntryStats(directory, 7);
17
+ if (!goal && entries === 0) return "";
18
+ const lines = ["[DAILY LOG]"];
19
+ if (goal) lines.push(`Goal: ${goal}`);
20
+ if (entries > 0)
21
+ lines.push(
22
+ `${entries} ${entries === 1 ? "entry" : "entries"} logged in the last 7 days — run \`omp daily-log read\` to load if relevant.`,
23
+ );
24
+ return lines.join("\n");
25
+ } catch {
26
+ return "";
27
+ }
28
+ }
29
+
9
30
  (async () => {
10
31
  try {
11
32
  const raw = await readStdin();
12
33
  const data = raw ? JSON.parse(raw) : {};
13
34
  const sessionId = data.sessionId ?? data.session_id ?? "unknown";
14
35
  const directory = data.directory ?? process.cwd();
15
- const stateDir = join(directory, ".omp", "state");
36
+ const stateDir = join(ompRoot(directory), ".omp", "state");
16
37
  const logFile = join(stateDir, "hooks.log");
17
38
  mkdirSync(dirname(logFile), { recursive: true });
18
39
  const line = JSON.stringify({
@@ -23,8 +44,45 @@ const HOOK_NAME = "SessionStart";
23
44
  });
24
45
  appendFileSync(logFile, `${line}\n`);
25
46
 
47
+ const parts = [];
26
48
  const update = await checkForUpdate({ stateDir });
27
- const additionalContext = update ? formatUpdateNotice(update.current, update.latest) : "";
49
+ if (update) parts.push(formatUpdateNotice(update.current, update.latest));
50
+ try {
51
+ const scheduleBanner = scanScheduleResults(ompRoot(directory));
52
+ if (scheduleBanner) parts.push(scheduleBanner);
53
+ } catch (e) {
54
+ // schedule scan is best-effort; never block session start
55
+ console.error(`[hook ${HOOK_NAME}] schedule scan failed: ${e?.message ?? e}`);
56
+ }
57
+ // Directives are must-follow rules — injected unconditionally (never on-demand)
58
+ // so the agent can't skip a rule by judging it "unrelated". Capped by count +
59
+ // chars so a bloated directive list can't balloon the start message; overflow
60
+ // is summarized with a pointer (mirrors OpenClaw's injection budget).
61
+ const directives = readDirectives(directory);
62
+ if (directives.length > 0) {
63
+ const MAX_DIRECTIVES = 12;
64
+ const MAX_DIRECTIVE_CHARS = 1200;
65
+ const shown = [];
66
+ let chars = 0;
67
+ for (const d of directives) {
68
+ if (shown.length >= MAX_DIRECTIVES || chars + d.length > MAX_DIRECTIVE_CHARS) break;
69
+ shown.push(d);
70
+ chars += d.length;
71
+ }
72
+ const more = directives.length - shown.length;
73
+ const body = shown.map((d) => `- ${d}`).join("\n");
74
+ const tail = more > 0 ? `\n- (+${more} more — run \`omp project-memory read\` to see all)` : "";
75
+ parts.push(`[DIRECTIVES] Follow these this session:\n${body}${tail}`);
76
+ }
77
+ const repoGoal = readRepoGoal(directory);
78
+ if (repoGoal) parts.push(`[REPO GOAL] ${repoGoal}`);
79
+ const breadcrumb = buildDailyLogBreadcrumb(directory);
80
+ if (breadcrumb) parts.push(breadcrumb);
81
+ // Resets the per-session baseline and flushes a nudge when the prior session
82
+ // did work but logged nothing. startSession never throws.
83
+ const flush = startSession(directory);
84
+ if (flush) parts.push(`[DAILY LOG] ${flush}`);
85
+ const additionalContext = parts.join("\n\n---\n\n");
28
86
 
29
87
  console.log(
30
88
  JSON.stringify({