@zerwiz/ymir 0.1.16 → 0.1.18

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 (171) hide show
  1. package/.agents/config/app-repos.yaml +38 -0
  2. package/.claude/settings.json +31 -0
  3. package/.codex/hooks.json +43 -0
  4. package/.cursor/hooks.json +33 -0
  5. package/.pi/extensions/README.md +39 -0
  6. package/.pi/extensions/gna-pi-watch.ts +15 -0
  7. package/.pi/extensions/lib/ro-assistant-layout.ts +96 -0
  8. package/.pi/extensions/lib/ro-operational-user-layout.ts +145 -0
  9. package/.pi/extensions/lib/ro-visibility.ts +99 -0
  10. package/.pi/extensions/lib/ro-working-ship.ts +243 -0
  11. package/.pi/extensions/lib/rodd-operational-input.ts +62 -0
  12. package/.pi/extensions/lib/skuld-branch-dispatch.ts +252 -0
  13. package/.pi/extensions/lib/skuld-branch-model-picker.ts +77 -0
  14. package/.pi/extensions/lib/vordr-sessionstart-supervisor.mjs +48 -0
  15. package/.pi/extensions/ro.ts +11 -0
  16. package/.pi/extensions/skuld-branch-supervision.ts +11 -0
  17. package/.pi/extensions/syn-turnend-guard.ts +11 -0
  18. package/.pi/mcp.json +16 -0
  19. package/.pi/mcp.json.example +11 -0
  20. package/.pi/npm/.gitignore +2 -0
  21. package/.pi/settings.json +8 -0
  22. package/.pi/shared/extensions/gna-pi-watch.ts +750 -0
  23. package/.pi/shared/extensions/herdr-agent-state.ts +257 -0
  24. package/.pi/shared/extensions/open-editor.ts +509 -0
  25. package/.pi/shared/extensions/ro.ts +504 -0
  26. package/.pi/shared/extensions/skuld-branch-supervision.ts +1535 -0
  27. package/.pi/shared/extensions/syn-turnend-guard.ts +683 -0
  28. package/.pi/shared/extensions/todo.ts +133 -0
  29. package/.pi/shared/extensions/ymir-subagents.ts +287 -0
  30. package/.pi/shared/extensions/ymir-well.ts +130 -0
  31. package/CHANGELOG.md +23 -0
  32. package/assets/Ymir.md +4654 -0
  33. package/assets/healer.html +717 -0
  34. package/assets/icon-family/family-sheet.png +0 -0
  35. package/assets/icon-family/hlidskjalf.svg +1 -0
  36. package/assets/icon-family/sessrumnir.svg +1 -0
  37. package/assets/icon-family/smidja.svg +1 -0
  38. package/assets/icon-family/ymir.svg +1 -0
  39. package/assets/mimirswell.html +880 -0
  40. package/assets/mock/README.md +16 -0
  41. package/assets/mock/feeds.ts +175 -0
  42. package/assets/mock/mock.ts +408 -0
  43. package/assets/reference/docs/agent-control.md +122 -0
  44. package/assets/reference/docs/apodex/Appdex_as_Orchestrator_Planner_Reviewer_Assessment.md +176 -0
  45. package/assets/reference/docs/apodex/Final Report(1).md +198 -0
  46. package/assets/reference/docs/apodex/Final Report(2).md +54 -0
  47. package/assets/reference/docs/apodex/Final Report(3).md +40 -0
  48. package/assets/reference/docs/apodex/Final Report(4).md +234 -0
  49. package/assets/reference/docs/apodex/Final Report(5).md +13 -0
  50. package/assets/reference/docs/apodex/Final Report.md +82 -0
  51. package/assets/reference/docs/architecture.md +392 -0
  52. package/assets/reference/docs/arm-pretool-check.md +247 -0
  53. package/assets/reference/docs/calm-mode-feasibility.md +541 -0
  54. package/assets/reference/docs/calm.md +59 -0
  55. package/assets/reference/docs/captain-hold-lifecycle.md +96 -0
  56. package/assets/reference/docs/cd-guard.md +165 -0
  57. package/assets/reference/docs/cmux-backend.md +133 -0
  58. package/assets/reference/docs/codex-app-backend.md +57 -0
  59. package/assets/reference/docs/configuration.md +924 -0
  60. package/assets/reference/docs/documentation-audiences.json +468 -0
  61. package/assets/reference/docs/documentation-audiences.md +28 -0
  62. package/assets/reference/docs/examples/crew-dispatch.json +26 -0
  63. package/assets/reference/docs/examples/process-event-extension/file-signal.mjs +96 -0
  64. package/assets/reference/docs/examples/process-event-extension/firstmate-extension.json +15 -0
  65. package/assets/reference/docs/examples/watched-tools.json +24 -0
  66. package/assets/reference/docs/examples/wedge-alarm +22 -0
  67. package/assets/reference/docs/extension-bindings.md +237 -0
  68. package/assets/reference/docs/fm-test-isolation-proof.json +37 -0
  69. package/assets/reference/docs/fm-test-isolation-proof.md +149 -0
  70. package/assets/reference/docs/fm-test-portable-shards.md +118 -0
  71. package/assets/reference/docs/gitlab-merge-watch.md +275 -0
  72. package/assets/reference/docs/herdr-backend.md +346 -0
  73. package/assets/reference/docs/orca-backend.md +84 -0
  74. package/assets/reference/docs/pi-supervision-branch-poster.svg +125 -0
  75. package/assets/reference/docs/pi-supervision-branch.md +96 -0
  76. package/assets/reference/docs/plans/agentic-engineering-workflow.md +395 -0
  77. package/assets/reference/docs/plans/agentic-factory-implementation-plan.md +615 -0
  78. package/assets/reference/docs/plans/command-factory-enhancement-plan.md +420 -0
  79. package/assets/reference/docs/plans/phase-1-layer3-program-design.md +134 -0
  80. package/assets/reference/docs/plans/phase-2-vertical-slices.md +100 -0
  81. package/assets/reference/docs/plans/phase-3-measurable-goals.md +106 -0
  82. package/assets/reference/docs/plans/phase-4-context-budget.md +106 -0
  83. package/assets/reference/docs/plans/phase-5-pre-mortem-confidence.md +100 -0
  84. package/assets/reference/docs/plans/phase-6-incident-to-agent.md +109 -0
  85. package/assets/reference/docs/remote-secondmates.md +268 -0
  86. package/assets/reference/docs/scripts.md +146 -0
  87. package/assets/reference/docs/sessionstart-nudge.md +115 -0
  88. package/assets/reference/docs/subagent-guard.md +383 -0
  89. package/assets/reference/docs/supervision-protocols/claude.md +27 -0
  90. package/assets/reference/docs/supervision-protocols/codex.md +16 -0
  91. package/assets/reference/docs/supervision-protocols/cursor.md +31 -0
  92. package/assets/reference/docs/supervision-protocols/grok.md +39 -0
  93. package/assets/reference/docs/supervision-protocols/opencode.md +17 -0
  94. package/assets/reference/docs/supervision-protocols/pi.md +33 -0
  95. package/assets/reference/docs/supervision-protocols/unknown.md +13 -0
  96. package/assets/reference/docs/tmux-backend.md +115 -0
  97. package/assets/reference/docs/trace-context.md +117 -0
  98. package/assets/reference/docs/turnend-guard.md +170 -0
  99. package/assets/reference/docs/verification/dispatch-auth.md +204 -0
  100. package/assets/reference/docs/verification/muse.md +221 -0
  101. package/assets/reference/docs/verification/process-event-sources.md +208 -0
  102. package/assets/reference/docs/verification/public-followup.md +119 -0
  103. package/assets/reference/docs/verification/runtime-backends.md +1022 -0
  104. package/assets/reference/docs/verification/stow-memory.md +53 -0
  105. package/assets/reference/docs/verification/supervision.md +534 -0
  106. package/assets/reference/docs/verification/trace-context.md +31 -0
  107. package/assets/reference/docs/voice-relay.md +295 -0
  108. package/assets/reference/docs/watcher-continuity.md +119 -0
  109. package/assets/reference/docs/wedge-alarm.md +39 -0
  110. package/assets/reference/docs/zellij-backend.md +114 -0
  111. package/assets/reference/index.html +1172 -0
  112. package/assets/reference/skills/afk/SKILL.md +241 -0
  113. package/assets/reference/skills/ahoy/SKILL.md +56 -0
  114. package/assets/reference/skills/ask-user-authority/SKILL.md +56 -0
  115. package/assets/reference/skills/bearings/SKILL.md +161 -0
  116. package/assets/reference/skills/bearings/assets/board-template.html +731 -0
  117. package/assets/reference/skills/bootstrap-diagnostics/SKILL.md +68 -0
  118. package/assets/reference/skills/captain-hold-lifecycle/SKILL.md +54 -0
  119. package/assets/reference/skills/decision-hold-lifecycle/SKILL.md +15 -0
  120. package/assets/reference/skills/diagnostic-reasoning/SKILL.md +53 -0
  121. package/assets/reference/skills/firstmate-codexapp/SKILL.md +110 -0
  122. package/assets/reference/skills/firstmate-codexapp/agents/openai.yaml +4 -0
  123. package/assets/reference/skills/firstmate-coding-guidelines/SKILL.md +127 -0
  124. package/assets/reference/skills/firstmate-orca/SKILL.md +92 -0
  125. package/assets/reference/skills/fmx-respond/SKILL.md +283 -0
  126. package/assets/reference/skills/harness-adapters/SKILL.md +95 -0
  127. package/assets/reference/skills/harness-adapters/references/common/control-and-recovery.md +37 -0
  128. package/assets/reference/skills/harness-adapters/references/common/dispatch.md +32 -0
  129. package/assets/reference/skills/harness-adapters/references/common/model-and-effort.md +42 -0
  130. package/assets/reference/skills/harness-adapters/references/common/primary-hooks.md +40 -0
  131. package/assets/reference/skills/harness-adapters/references/harness/claude.md +55 -0
  132. package/assets/reference/skills/harness-adapters/references/harness/codex.md +43 -0
  133. package/assets/reference/skills/harness-adapters/references/harness/cursor.md +75 -0
  134. package/assets/reference/skills/harness-adapters/references/harness/grok.md +69 -0
  135. package/assets/reference/skills/harness-adapters/references/harness/kimi.md +51 -0
  136. package/assets/reference/skills/harness-adapters/references/harness/muse.md +70 -0
  137. package/assets/reference/skills/harness-adapters/references/harness/opencode.md +42 -0
  138. package/assets/reference/skills/harness-adapters/references/harness/pi.md +56 -0
  139. package/assets/reference/skills/process-event-sources/SKILL.md +137 -0
  140. package/assets/reference/skills/project-management/SKILL.md +92 -0
  141. package/assets/reference/skills/quota-array-dispatch/SKILL.md +131 -0
  142. package/assets/reference/skills/secondmate-provisioning/SKILL.md +254 -0
  143. package/assets/reference/skills/stow/SKILL.md +309 -0
  144. package/assets/reference/skills/stuck-crewmate-recovery/SKILL.md +54 -0
  145. package/assets/reference/skills/updatefirstmate/SKILL.md +64 -0
  146. package/assets/skills/README.md +5 -0
  147. package/assets/yggdrasil.html +649 -0
  148. package/assets/ymir-banner-01.png +0 -0
  149. package/assets/ymir-banner-02.png +0 -0
  150. package/assets/ymir-banner-03.png +0 -0
  151. package/assets/ymir-banner-04.png +0 -0
  152. package/assets/ymir-banner-05.png +0 -0
  153. package/assets/ymir-banner-06.png +0 -0
  154. package/assets/ymir-emblem-darksteel.svg +63 -0
  155. package/assets/ymir-emblem-forged.svg +55 -0
  156. package/assets/ymir-emblem-slate.svg +55 -0
  157. package/assets/ymir-mark-algiz-anvil.svg +9 -0
  158. package/assets/ymir-stave.svg +53 -0
  159. package/assets/ymir.html +563 -0
  160. package/bin/ymir-install.sh +6 -1
  161. package/data/learnings.md +33 -0
  162. package/data/local-models.md +34 -0
  163. package/data/operator.md +15 -0
  164. package/data/projects.md +28 -0
  165. package/data/realm.md +1 -0
  166. package/deploy/Containerfile +27 -0
  167. package/deploy/README.md +104 -0
  168. package/deploy/compose/compose.yaml +45 -0
  169. package/deploy/env.example +30 -0
  170. package/deploy/quadlet/ymir.container +57 -0
  171. package/package.json +10 -8
@@ -0,0 +1,257 @@
1
+ // installed by herdr
2
+ // managed by herdr; reinstalling or updating the integration overwrites this file.
3
+ // add custom hooks/plugins beside this file instead of editing it.
4
+ // HERDR_INTEGRATION_ID=pi
5
+ // HERDR_INTEGRATION_VERSION=8
6
+ // @ts-nocheck
7
+
8
+ import net from "node:net";
9
+
10
+ const HERDR_ENV = process.env.HERDR_ENV;
11
+ const socketPath = process.env.HERDR_SOCKET_PATH;
12
+ const socketEndpoint =
13
+ process.platform === "win32" && socketPath ? `\\\\.\\pipe\\${socketPath}` : socketPath;
14
+ const paneId = process.env.HERDR_PANE_ID;
15
+ const source = "herdr:pi";
16
+
17
+ function enabled() {
18
+ return HERDR_ENV === "1" && !!socketPath && !!paneId;
19
+ }
20
+
21
+ function sendRequestAttempt(request: unknown, timeoutMs: number): Promise<boolean> {
22
+ if (!enabled()) {
23
+ return Promise.resolve(true);
24
+ }
25
+
26
+ return new Promise((resolve) => {
27
+ let done = false;
28
+ let timeout: ReturnType<typeof setTimeout> | undefined;
29
+ const finish = (delivered: boolean) => {
30
+ if (done) return;
31
+ done = true;
32
+ if (timeout) {
33
+ clearTimeout(timeout);
34
+ }
35
+ socket.destroy();
36
+ resolve(delivered);
37
+ };
38
+
39
+ const socket = net.createConnection(socketEndpoint!);
40
+ socket.on("error", () => finish(false));
41
+ socket.on("connect", () => socket.write(`${JSON.stringify(request)}\n`));
42
+ socket.on("data", () => finish(true));
43
+ socket.on("end", () => finish(false));
44
+ timeout = setTimeout(() => finish(false), timeoutMs);
45
+ timeout.unref?.();
46
+ });
47
+ }
48
+
49
+ async function sendRequest(request: unknown): Promise<void> {
50
+ if (await sendRequestAttempt(request, 500)) {
51
+ return;
52
+ }
53
+ await sendRequestAttempt(request, 1500);
54
+ }
55
+
56
+ type AgentState = "working" | "blocked" | "idle";
57
+
58
+ type QueuedState = {
59
+ state: AgentState;
60
+ message?: string;
61
+ seq: number;
62
+ };
63
+
64
+ let reportSeq = Date.now() * 1000;
65
+ let currentAgentSessionId: string | undefined;
66
+ let currentAgentSessionPath: string | undefined;
67
+
68
+ function nextReportSeq(): number {
69
+ reportSeq += 1;
70
+ return reportSeq;
71
+ }
72
+
73
+ function updateSessionRef(ctx: any): void {
74
+ try {
75
+ const file = ctx?.sessionManager?.getSessionFile?.();
76
+ currentAgentSessionPath =
77
+ typeof file === "string" && file.startsWith("/") ? file : undefined;
78
+ } catch {
79
+ currentAgentSessionPath = undefined;
80
+ }
81
+
82
+ try {
83
+ const id = ctx?.sessionManager?.getSessionId?.();
84
+ currentAgentSessionId = typeof id === "string" && id.length > 0 ? id : undefined;
85
+ } catch {
86
+ currentAgentSessionId = undefined;
87
+ }
88
+ }
89
+
90
+ function withSessionRef(params: Record<string, unknown>): Record<string, unknown> {
91
+ if (currentAgentSessionPath) {
92
+ return { ...params, agent_session_path: currentAgentSessionPath };
93
+ }
94
+ if (currentAgentSessionId) {
95
+ return { ...params, agent_session_id: currentAgentSessionId };
96
+ }
97
+ return params;
98
+ }
99
+
100
+ function currentSessionRef(): Record<string, unknown> | undefined {
101
+ if (currentAgentSessionPath) {
102
+ return { agent_session_path: currentAgentSessionPath };
103
+ }
104
+ if (currentAgentSessionId) {
105
+ return { agent_session_id: currentAgentSessionId };
106
+ }
107
+ return undefined;
108
+ }
109
+
110
+ function reportSession(sessionStartSource?: string): Promise<void> {
111
+ const sessionRef = currentSessionRef();
112
+ if (!sessionRef) {
113
+ return Promise.resolve();
114
+ }
115
+
116
+ return sendRequest({
117
+ id: `${source}:session:${Date.now()}:${Math.random().toString(36).slice(2)}`,
118
+ method: "pane.report_agent_session",
119
+ params: {
120
+ pane_id: paneId,
121
+ source,
122
+ agent: "pi",
123
+ seq: nextReportSeq(),
124
+ session_start_source: sessionStartSource,
125
+ ...sessionRef,
126
+ },
127
+ });
128
+ }
129
+
130
+ function sendState(state: AgentState, message?: string, seq = nextReportSeq()): Promise<void> {
131
+ return sendRequest({
132
+ id: `${source}:${Date.now()}:${Math.random().toString(36).slice(2)}`,
133
+ method: "pane.report_agent",
134
+ params: withSessionRef({
135
+ pane_id: paneId,
136
+ source,
137
+ agent: "pi",
138
+ state,
139
+ message,
140
+ seq,
141
+ }),
142
+ });
143
+ }
144
+
145
+ let sendInFlight = false;
146
+ let queuedState: QueuedState | undefined;
147
+
148
+ function queueState(state: AgentState, message?: string): void {
149
+ queuedState = { state, message, seq: nextReportSeq() };
150
+ if (!sendInFlight) {
151
+ void drainStateQueue();
152
+ }
153
+ }
154
+
155
+ async function drainStateQueue(): Promise<void> {
156
+ if (sendInFlight) {
157
+ return;
158
+ }
159
+
160
+ sendInFlight = true;
161
+ try {
162
+ while (queuedState) {
163
+ const next = queuedState;
164
+ queuedState = undefined;
165
+ await sendState(next.state, next.message, next.seq);
166
+ }
167
+ } finally {
168
+ sendInFlight = false;
169
+ if (queuedState) {
170
+ void drainStateQueue();
171
+ }
172
+ }
173
+ }
174
+
175
+ export default function (pi) {
176
+ if (!enabled()) {
177
+ return;
178
+ }
179
+
180
+ let agentActive = false;
181
+ let blockedCount = 0;
182
+ let blockedMessage: string | undefined;
183
+ let lastState: AgentState | undefined;
184
+ let lastMessage: string | undefined;
185
+ let rootSession = false;
186
+
187
+ function desiredState() {
188
+ if (blockedCount > 0) {
189
+ return { state: "blocked" as const, message: blockedMessage };
190
+ }
191
+ if (agentActive) {
192
+ return { state: "working" as const, message: undefined };
193
+ }
194
+ return { state: "idle" as const, message: undefined };
195
+ }
196
+
197
+ function publishState(force = false) {
198
+ const next = desiredState();
199
+ if (!force && next.state === lastState && next.message === lastMessage) {
200
+ return;
201
+ }
202
+ lastState = next.state;
203
+ lastMessage = next.message;
204
+ queueState(next.state, next.message);
205
+ }
206
+
207
+ pi.events.on("herdr:blocked", (data) => {
208
+ if (!rootSession) {
209
+ return;
210
+ }
211
+ if (!data?.active) {
212
+ blockedCount = Math.max(0, blockedCount - 1);
213
+ if (blockedCount === 0) {
214
+ blockedMessage = undefined;
215
+ }
216
+ publishState();
217
+ return;
218
+ }
219
+
220
+ blockedCount += 1;
221
+ blockedMessage = data.label;
222
+ publishState();
223
+ });
224
+
225
+ pi.on("session_start", async (event, ctx) => {
226
+ // TUI only: RPC/JSON/print modes are headless (no PTY herdr can display),
227
+ // and RPC still reports hasUI=true, so mode is the reliable gate.
228
+ if (ctx?.mode !== "tui") {
229
+ return;
230
+ }
231
+ rootSession = true;
232
+ updateSessionRef(ctx);
233
+ await reportSession(event?.reason);
234
+ // A reload can replace this extension mid-run without emitting another agent_start.
235
+ agentActive = ctx?.isIdle?.() === false;
236
+ publishState(true);
237
+ });
238
+
239
+ pi.on("agent_start", (_event, ctx) => {
240
+ if (!rootSession) {
241
+ return;
242
+ }
243
+ updateSessionRef(ctx);
244
+ void reportSession();
245
+ agentActive = true;
246
+ publishState();
247
+ });
248
+
249
+ pi.on("agent_settled", (_event, ctx) => {
250
+ if (!rootSession || ctx?.isIdle?.() !== true) {
251
+ return;
252
+ }
253
+
254
+ agentActive = false;
255
+ publishState();
256
+ });
257
+ }