humanish 0.0.1 → 0.15.1

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 (205) hide show
  1. package/AGENTS.md +77 -0
  2. package/CONTRIBUTING.md +39 -0
  3. package/LICENSE +21 -0
  4. package/README.md +437 -8
  5. package/SECURITY.md +34 -0
  6. package/dist/actor-contract.d.ts +107 -0
  7. package/dist/actor-contract.js +286 -0
  8. package/dist/actor-contract.js.map +1 -0
  9. package/dist/actor-registry.d.ts +73 -0
  10. package/dist/actor-registry.js +93 -0
  11. package/dist/actor-registry.js.map +1 -0
  12. package/dist/adapter-extension.d.ts +54 -0
  13. package/dist/adapter-extension.js +214 -0
  14. package/dist/adapter-extension.js.map +1 -0
  15. package/dist/argv.d.ts +1 -0
  16. package/dist/argv.js +8 -0
  17. package/dist/argv.js.map +1 -0
  18. package/dist/artifact-reference.d.ts +22 -0
  19. package/dist/artifact-reference.js +47 -0
  20. package/dist/artifact-reference.js.map +1 -0
  21. package/dist/browser-evidence-hygiene.d.ts +7 -0
  22. package/dist/browser-evidence-hygiene.js +40 -0
  23. package/dist/browser-evidence-hygiene.js.map +1 -0
  24. package/dist/claude-agent-sdk.d.ts +94 -0
  25. package/dist/claude-agent-sdk.js +363 -0
  26. package/dist/claude-agent-sdk.js.map +1 -0
  27. package/dist/cli.d.ts +2 -0
  28. package/dist/cli.js +5 -0
  29. package/dist/cli.js.map +1 -0
  30. package/dist/codex-app-server-ui.d.ts +39 -0
  31. package/dist/codex-app-server-ui.js +357 -0
  32. package/dist/codex-app-server-ui.js.map +1 -0
  33. package/dist/codex-app-server.d.ts +144 -0
  34. package/dist/codex-app-server.js +754 -0
  35. package/dist/codex-app-server.js.map +1 -0
  36. package/dist/command-failure.d.ts +29 -0
  37. package/dist/command-failure.js +54 -0
  38. package/dist/command-failure.js.map +1 -0
  39. package/dist/computer-use-actor.d.ts +52 -0
  40. package/dist/computer-use-actor.js +48 -0
  41. package/dist/computer-use-actor.js.map +1 -0
  42. package/dist/computer-use.d.ts +232 -0
  43. package/dist/computer-use.js +615 -0
  44. package/dist/computer-use.js.map +1 -0
  45. package/dist/concurrency.d.ts +1 -0
  46. package/dist/concurrency.js +27 -0
  47. package/dist/concurrency.js.map +1 -0
  48. package/dist/concurrent-shared-world-lab.d.ts +115 -0
  49. package/dist/concurrent-shared-world-lab.js +1094 -0
  50. package/dist/concurrent-shared-world-lab.js.map +1 -0
  51. package/dist/core/git-state.d.ts +33 -0
  52. package/dist/core/git-state.js +277 -0
  53. package/dist/core/git-state.js.map +1 -0
  54. package/dist/core/git-workspace.d.ts +31 -0
  55. package/dist/core/git-workspace.js +447 -0
  56. package/dist/core/git-workspace.js.map +1 -0
  57. package/dist/core/index.d.ts +4 -0
  58. package/dist/core/index.js +3 -0
  59. package/dist/core/index.js.map +1 -0
  60. package/dist/core/run-primitives.d.ts +66 -0
  61. package/dist/core/run-primitives.js +120 -0
  62. package/dist/core/run-primitives.js.map +1 -0
  63. package/dist/cua-actor-lab.d.ts +621 -0
  64. package/dist/cua-actor-lab.js +2845 -0
  65. package/dist/cua-actor-lab.js.map +1 -0
  66. package/dist/device-presets.d.ts +67 -0
  67. package/dist/device-presets.js +50 -0
  68. package/dist/device-presets.js.map +1 -0
  69. package/dist/e2b-desktop-executor.d.ts +101 -0
  70. package/dist/e2b-desktop-executor.js +309 -0
  71. package/dist/e2b-desktop-executor.js.map +1 -0
  72. package/dist/e2b-desktop-launch.d.ts +144 -0
  73. package/dist/e2b-desktop-launch.js +59 -0
  74. package/dist/e2b-desktop-launch.js.map +1 -0
  75. package/dist/e2b-detached.d.ts +53 -0
  76. package/dist/e2b-detached.js +130 -0
  77. package/dist/e2b-detached.js.map +1 -0
  78. package/dist/e2b-terminal-lab.d.ts +345 -0
  79. package/dist/e2b-terminal-lab.js +1532 -0
  80. package/dist/e2b-terminal-lab.js.map +1 -0
  81. package/dist/env-file.d.ts +14 -0
  82. package/dist/env-file.js +108 -0
  83. package/dist/env-file.js.map +1 -0
  84. package/dist/feedback.d.ts +51 -0
  85. package/dist/feedback.js +351 -0
  86. package/dist/feedback.js.map +1 -0
  87. package/dist/image-evidence.d.ts +2 -0
  88. package/dist/image-evidence.js +33 -0
  89. package/dist/image-evidence.js.map +1 -0
  90. package/dist/index.d.ts +63 -0
  91. package/dist/index.js +33 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/init-templates.d.ts +12 -0
  94. package/dist/init-templates.js +369 -0
  95. package/dist/init-templates.js.map +1 -0
  96. package/dist/init.d.ts +26 -0
  97. package/dist/init.js +429 -0
  98. package/dist/init.js.map +1 -0
  99. package/dist/lab-app-runner.d.ts +78 -0
  100. package/dist/lab-app-runner.js +403 -0
  101. package/dist/lab-app-runner.js.map +1 -0
  102. package/dist/lab-config.d.ts +583 -0
  103. package/dist/lab-config.js +1789 -0
  104. package/dist/lab-config.js.map +1 -0
  105. package/dist/lab-engine.d.ts +77 -0
  106. package/dist/lab-engine.js +216 -0
  107. package/dist/lab-engine.js.map +1 -0
  108. package/dist/lab-preflight.d.ts +67 -0
  109. package/dist/lab-preflight.js +385 -0
  110. package/dist/lab-preflight.js.map +1 -0
  111. package/dist/labs.d.ts +53 -0
  112. package/dist/labs.js +382 -0
  113. package/dist/labs.js.map +1 -0
  114. package/dist/observer-assets.d.ts +2 -0
  115. package/dist/observer-assets.js +2630 -0
  116. package/dist/observer-assets.js.map +1 -0
  117. package/dist/observer-data.d.ts +63 -0
  118. package/dist/observer-data.js +145 -0
  119. package/dist/observer-data.js.map +1 -0
  120. package/dist/observer-static.d.ts +39 -0
  121. package/dist/observer-static.js +306 -0
  122. package/dist/observer-static.js.map +1 -0
  123. package/dist/observer.d.ts +46 -0
  124. package/dist/observer.js +550 -0
  125. package/dist/observer.js.map +1 -0
  126. package/dist/openai-responses-cu.d.ts +113 -0
  127. package/dist/openai-responses-cu.js +545 -0
  128. package/dist/openai-responses-cu.js.map +1 -0
  129. package/dist/oss-lab.d.ts +52 -0
  130. package/dist/oss-lab.js +344 -0
  131. package/dist/oss-lab.js.map +1 -0
  132. package/dist/oss-meta-lab-scoring.d.ts +15 -0
  133. package/dist/oss-meta-lab-scoring.js +145 -0
  134. package/dist/oss-meta-lab-scoring.js.map +1 -0
  135. package/dist/oss-meta-lab.d.ts +277 -0
  136. package/dist/oss-meta-lab.js +4529 -0
  137. package/dist/oss-meta-lab.js.map +1 -0
  138. package/dist/oss-remote-telemetry.d.ts +77 -0
  139. package/dist/oss-remote-telemetry.js +403 -0
  140. package/dist/oss-remote-telemetry.js.map +1 -0
  141. package/dist/persona.d.ts +35 -0
  142. package/dist/persona.js +133 -0
  143. package/dist/persona.js.map +1 -0
  144. package/dist/pi-agent-core.d.ts +77 -0
  145. package/dist/pi-agent-core.js +203 -0
  146. package/dist/pi-agent-core.js.map +1 -0
  147. package/dist/program.d.ts +54 -0
  148. package/dist/program.js +2349 -0
  149. package/dist/program.js.map +1 -0
  150. package/dist/redaction.d.ts +90 -0
  151. package/dist/redaction.js +292 -0
  152. package/dist/redaction.js.map +1 -0
  153. package/dist/run-paths.d.ts +56 -0
  154. package/dist/run-paths.js +340 -0
  155. package/dist/run-paths.js.map +1 -0
  156. package/dist/run.d.ts +794 -0
  157. package/dist/run.js +4844 -0
  158. package/dist/run.js.map +1 -0
  159. package/dist/scripted-browser-actor.d.ts +297 -0
  160. package/dist/scripted-browser-actor.js +1399 -0
  161. package/dist/scripted-browser-actor.js.map +1 -0
  162. package/dist/scripted-browser-lab.d.ts +107 -0
  163. package/dist/scripted-browser-lab.js +788 -0
  164. package/dist/scripted-browser-lab.js.map +1 -0
  165. package/dist/selected-output-paths.d.ts +49 -0
  166. package/dist/selected-output-paths.js +354 -0
  167. package/dist/selected-output-paths.js.map +1 -0
  168. package/dist/shared-world-lab.d.ts +208 -0
  169. package/dist/shared-world-lab.js +1049 -0
  170. package/dist/shared-world-lab.js.map +1 -0
  171. package/dist/source-archive.d.ts +82 -0
  172. package/dist/source-archive.js +408 -0
  173. package/dist/source-archive.js.map +1 -0
  174. package/dist/stop-conditions.d.ts +26 -0
  175. package/dist/stop-conditions.js +66 -0
  176. package/dist/stop-conditions.js.map +1 -0
  177. package/dist/terminal-agent-actor.d.ts +36 -0
  178. package/dist/terminal-agent-actor.js +23 -0
  179. package/dist/terminal-agent-actor.js.map +1 -0
  180. package/docs/architecture/actor-contract.md +431 -0
  181. package/docs/architecture/github-feedback-loop.md +189 -0
  182. package/docs/architecture/local-codex-tui-actor.md +213 -0
  183. package/docs/architecture/observer.md +118 -0
  184. package/docs/architecture/oss-lab-poc.md +250 -0
  185. package/docs/architecture/project-layout.md +166 -0
  186. package/docs/architecture/state-driven-executor.md +203 -0
  187. package/docs/architecture/terminal-product-lane.md +148 -0
  188. package/docs/contracts/adapter-fixtures.md +80 -0
  189. package/docs/contracts/core.md +71 -0
  190. package/docs/contracts/feedback.md +145 -0
  191. package/docs/contracts/policy.md +311 -0
  192. package/docs/contracts/run-bundle.md +358 -0
  193. package/docs/contracts/schemas.md +984 -0
  194. package/docs/goals/current.md +428 -0
  195. package/docs/principles/invariants-and-defaults.md +135 -0
  196. package/docs/principles/self-driving-harness.md +129 -0
  197. package/docs/product/open-source-install-experience.md +237 -0
  198. package/docs/ramp/README.md +207 -0
  199. package/docs/release/open-source-readiness.md +208 -0
  200. package/docs/release/public-readiness-standard.md +205 -0
  201. package/docs/roadmap/world-class-open-source-v0.md +311 -0
  202. package/package.json +102 -8
  203. package/skills/humanish/SKILL.md +244 -0
  204. package/skills/humanish/agents/openai.yaml +7 -0
  205. package/index.js +0 -1
@@ -0,0 +1,447 @@
1
+ import { constants } from "node:fs";
2
+ import { lstat, open, readdir, realpath } from "node:fs/promises";
3
+ import path from "node:path";
4
+ export const GIT_METADATA_INSPECTION_FAILED_NOTE = "Git metadata could not be inspected safely.";
5
+ export const GIT_METADATA_CONTAINMENT_FAILED_NOTE = "Git metadata failed containment validation.";
6
+ /**
7
+ * Resolve one physical Git worktree without trusting ambient Git discovery.
8
+ *
9
+ * A regular `.git` file is accepted only for Git's exact linked-worktree
10
+ * topology: `<common>/.git/worktrees/<name>` plus single-link `commondir` and
11
+ * `gitdir` backpointer files. Arbitrary `gitdir:` redirects (including valid
12
+ * separate-git-dir repositories) are deliberately unavailable because they
13
+ * delegate metadata authority outside the selected project without a
14
+ * verifiable backlink.
15
+ */
16
+ export async function inspectVerifiedGitWorkspace(cwdInput) {
17
+ let current;
18
+ try {
19
+ current = await realpath(path.resolve(cwdInput));
20
+ const cwdStats = await lstat(current);
21
+ if (cwdStats.isSymbolicLink() || !cwdStats.isDirectory()) {
22
+ return unsafeInspection(current, GIT_METADATA_INSPECTION_FAILED_NOTE);
23
+ }
24
+ }
25
+ catch {
26
+ return unsafeInspection(path.resolve(cwdInput), GIT_METADATA_INSPECTION_FAILED_NOTE);
27
+ }
28
+ while (true) {
29
+ const dotGitPath = path.join(current, ".git");
30
+ let dotGitStats;
31
+ try {
32
+ dotGitStats = await lstat(dotGitPath, { bigint: true });
33
+ }
34
+ catch (error) {
35
+ if (!isNodeError(error) || error.code !== "ENOENT") {
36
+ return unsafeInspection(current, GIT_METADATA_INSPECTION_FAILED_NOTE);
37
+ }
38
+ const parent = path.dirname(current);
39
+ if (parent === current) {
40
+ return { status: "missing" };
41
+ }
42
+ current = parent;
43
+ continue;
44
+ }
45
+ if (dotGitStats.isSymbolicLink()) {
46
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
47
+ }
48
+ if (dotGitStats.isDirectory()) {
49
+ try {
50
+ if (await realpath(dotGitPath) !== dotGitPath) {
51
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
52
+ }
53
+ // A normal worktree does not need commondir. Accepting one here would
54
+ // let a contained `.git/` silently redirect config, refs, and objects.
55
+ if (await pathExists(path.join(dotGitPath, "commondir"))) {
56
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
57
+ }
58
+ const configOverrides = [];
59
+ const workspace = {
60
+ commonDir: dotGitPath,
61
+ configOverrides,
62
+ gitDir: dotGitPath,
63
+ kind: "directory",
64
+ trustRoot: current,
65
+ worktreeRoot: current
66
+ };
67
+ return await validateCriticalGitMetadata(workspace)
68
+ ? { status: "verified", workspace: freezeVerifiedWorkspace(workspace, configOverrides) }
69
+ : unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
70
+ }
71
+ catch {
72
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
73
+ }
74
+ }
75
+ if (!dotGitStats.isFile() || dotGitStats.nlink !== 1n) {
76
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
77
+ }
78
+ try {
79
+ const dotGit = await readSingleLinkRegularFile(dotGitPath);
80
+ const declaredGitDir = dotGit ? parseGitdirFile(dotGit.text) : null;
81
+ if (!dotGit || !declaredGitDir) {
82
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
83
+ }
84
+ const gitDir = await realpath(path.isAbsolute(declaredGitDir)
85
+ ? declaredGitDir
86
+ : path.resolve(current, declaredGitDir));
87
+ if (!await isPhysicalDirectory(gitDir)) {
88
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
89
+ }
90
+ const commondir = await readSingleLinkRegularFile(path.join(gitDir, "commondir"));
91
+ const backpointer = await readSingleLinkRegularFile(path.join(gitDir, "gitdir"));
92
+ const declaredCommonDir = commondir ? parseSinglePathLine(commondir.text) : null;
93
+ const declaredBackpointer = backpointer ? parseSinglePathLine(backpointer.text) : null;
94
+ if (!commondir || !backpointer || !declaredCommonDir || !declaredBackpointer) {
95
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
96
+ }
97
+ const commonDir = await realpath(path.resolve(gitDir, declaredCommonDir));
98
+ if (!await isPhysicalDirectory(commonDir)
99
+ || path.basename(commonDir) !== ".git"
100
+ || path.dirname(gitDir) !== path.join(commonDir, "worktrees")
101
+ || path.basename(gitDir).length === 0) {
102
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
103
+ }
104
+ const physicalBackpointer = await realpath(path.isAbsolute(declaredBackpointer)
105
+ ? declaredBackpointer
106
+ : path.resolve(gitDir, declaredBackpointer));
107
+ if (physicalBackpointer !== dotGitPath) {
108
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
109
+ }
110
+ const trustRoot = path.dirname(commonDir);
111
+ if (!await isPhysicalDirectory(trustRoot)
112
+ || await realpath(path.join(trustRoot, ".git")) !== commonDir
113
+ || !await stillSameSingleLinkFile(dotGitPath, dotGit.identity)
114
+ || !await stillSameSingleLinkFile(path.join(gitDir, "commondir"), commondir.identity)
115
+ || !await stillSameSingleLinkFile(path.join(gitDir, "gitdir"), backpointer.identity)) {
116
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
117
+ }
118
+ const configOverrides = [];
119
+ const workspace = {
120
+ commonDir,
121
+ configOverrides,
122
+ gitDir,
123
+ kind: "linked-worktree",
124
+ trustRoot,
125
+ worktreeRoot: current
126
+ };
127
+ return await validateCriticalGitMetadata(workspace)
128
+ ? { status: "verified", workspace: freezeVerifiedWorkspace(workspace, configOverrides) }
129
+ : unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
130
+ }
131
+ catch {
132
+ return unsafeInspection(current, GIT_METADATA_CONTAINMENT_FAILED_NOTE);
133
+ }
134
+ }
135
+ }
136
+ async function validateCriticalGitMetadata(workspace) {
137
+ if (!await isPhysicalDirectory(workspace.gitDir)
138
+ || !await isPhysicalDirectory(workspace.commonDir)
139
+ || !await isPhysicalDirectory(workspace.worktreeRoot)) {
140
+ return false;
141
+ }
142
+ const criticalFiles = new Set([
143
+ path.join(workspace.gitDir, "HEAD"),
144
+ path.join(workspace.gitDir, "index"),
145
+ path.join(workspace.gitDir, "config.worktree"),
146
+ path.join(workspace.commonDir, "config"),
147
+ path.join(workspace.commonDir, "config.worktree"),
148
+ path.join(workspace.commonDir, "info", "attributes"),
149
+ path.join(workspace.commonDir, "info", "exclude"),
150
+ path.join(workspace.commonDir, "packed-refs")
151
+ ]);
152
+ for (const filePath of criticalFiles) {
153
+ if (!await isSingleLinkRegularFileOrMissing(filePath)) {
154
+ return false;
155
+ }
156
+ }
157
+ // Split indexes are selected by the contained index but read as sibling
158
+ // metadata. Do not let one redirect Git through a symlink or hardlink.
159
+ const gitDirEntries = await readdir(workspace.gitDir).catch(() => []);
160
+ for (const entry of gitDirEntries) {
161
+ if (/^sharedindex\.[0-9a-f]+$/i.test(entry)) {
162
+ if (!await isSingleLinkRegularFileOrMissing(path.join(workspace.gitDir, entry))) {
163
+ return false;
164
+ }
165
+ }
166
+ }
167
+ for (const directory of [
168
+ path.join(workspace.commonDir, "objects"),
169
+ path.join(workspace.commonDir, "refs")
170
+ ]) {
171
+ if (!await isPhysicalDirectoryOrMissing(directory)) {
172
+ return false;
173
+ }
174
+ }
175
+ const head = await readSingleLinkRegularFile(path.join(workspace.gitDir, "HEAD"), true);
176
+ if (head && !await validateHeadReference(workspace, head.text)) {
177
+ return false;
178
+ }
179
+ const alternatesPath = path.join(workspace.commonDir, "objects", "info", "alternates");
180
+ if (!await isSingleLinkRegularFileOrMissing(alternatesPath)) {
181
+ return false;
182
+ }
183
+ const alternates = await readSingleLinkRegularFile(alternatesPath, true);
184
+ if (alternates && !await alternatesStayInsideCommonDir(workspace.commonDir, alternates.text)) {
185
+ return false;
186
+ }
187
+ const overrides = await collectExecutableConfigOverrides(workspace);
188
+ if (!overrides) {
189
+ return false;
190
+ }
191
+ workspace.configOverrides.push(...overrides);
192
+ return true;
193
+ }
194
+ async function collectExecutableConfigOverrides(workspace) {
195
+ const filters = new Set();
196
+ const diffs = new Set();
197
+ for (const configPath of new Set([
198
+ path.join(workspace.commonDir, "config"),
199
+ path.join(workspace.gitDir, "config.worktree")
200
+ ])) {
201
+ const config = await readSingleLinkRegularFile(configPath, true);
202
+ if (!config)
203
+ continue;
204
+ for (const line of config.text.split(/\r?\n/)) {
205
+ if (/^\s*\[\s*include(?:\s*\]|if\b)/i.test(line)) {
206
+ // Includes can introduce executable config from an unbound path after
207
+ // this file was inspected. Provenance capture does not need them.
208
+ return null;
209
+ }
210
+ const sectionStart = /^\s*\[\s*(filter|diff)\b/i.exec(line);
211
+ if (!sectionStart)
212
+ continue;
213
+ const section = /^\s*\[\s*(filter|diff)\s+(?:"((?:\\.|[^"\\])*)"|\.\s*([^\]\s]+))\s*\]\s*(?:[#;].*)?$/i.exec(line);
214
+ if (!section)
215
+ return null;
216
+ const rawDriver = section[2] === undefined ? section[3] : unescapeGitConfigSubsection(section[2]);
217
+ if (!rawDriver || !/^[A-Za-z0-9_.-]+$/.test(rawDriver))
218
+ return null;
219
+ if (section[1]?.toLowerCase() === "filter")
220
+ filters.add(rawDriver);
221
+ else
222
+ diffs.add(rawDriver);
223
+ }
224
+ }
225
+ const overrides = [];
226
+ for (const driver of [...filters].sort()) {
227
+ overrides.push(`filter.${driver}.clean=`, `filter.${driver}.smudge=`, `filter.${driver}.process=`, `filter.${driver}.required=false`);
228
+ }
229
+ for (const driver of [...diffs].sort()) {
230
+ overrides.push(`diff.${driver}.command=`, `diff.${driver}.textconv=`);
231
+ }
232
+ return overrides;
233
+ }
234
+ function unescapeGitConfigSubsection(value) {
235
+ let result = "";
236
+ for (let index = 0; index < value.length; index += 1) {
237
+ const char = value[index];
238
+ if (char !== "\\") {
239
+ result += char;
240
+ continue;
241
+ }
242
+ const escaped = value[index + 1];
243
+ if (escaped !== "\\" && escaped !== "\"")
244
+ return null;
245
+ result += escaped;
246
+ index += 1;
247
+ }
248
+ return result;
249
+ }
250
+ function freezeVerifiedWorkspace(workspace, configOverrides) {
251
+ Object.freeze(configOverrides);
252
+ return Object.freeze(workspace);
253
+ }
254
+ async function validateHeadReference(workspace, headText) {
255
+ const value = headText.trim();
256
+ if (/^[0-9a-f]{40}(?:[0-9a-f]{24})?$/i.test(value)) {
257
+ return true;
258
+ }
259
+ if (!value.startsWith("ref: ")) {
260
+ return false;
261
+ }
262
+ const ref = value.slice("ref: ".length);
263
+ if (!isSafeGitRef(ref)) {
264
+ return false;
265
+ }
266
+ // Normal branch refs live under the common directory. Per-worktree refs may
267
+ // live under the admin directory. Validate either existing path without
268
+ // requiring an unborn branch to have a loose ref.
269
+ const candidates = [path.join(workspace.commonDir, ...ref.split("/"))];
270
+ if (workspace.gitDir !== workspace.commonDir) {
271
+ candidates.push(path.join(workspace.gitDir, ...ref.split("/")));
272
+ }
273
+ for (const candidate of candidates) {
274
+ if (!await validateOptionalContainedFileChain(candidate.startsWith(`${workspace.gitDir}${path.sep}`) ? workspace.gitDir : workspace.commonDir, candidate)) {
275
+ return false;
276
+ }
277
+ }
278
+ return true;
279
+ }
280
+ async function validateOptionalContainedFileChain(root, filePath) {
281
+ const relative = path.relative(root, filePath);
282
+ if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
283
+ return false;
284
+ }
285
+ let current = root;
286
+ const segments = relative.split(path.sep);
287
+ for (const [index, segment] of segments.entries()) {
288
+ current = path.join(current, segment);
289
+ let stats;
290
+ try {
291
+ stats = await lstat(current, { bigint: true });
292
+ }
293
+ catch (error) {
294
+ return isNodeError(error) && error.code === "ENOENT";
295
+ }
296
+ if (stats.isSymbolicLink())
297
+ return false;
298
+ if (index < segments.length - 1) {
299
+ if (!stats.isDirectory())
300
+ return false;
301
+ }
302
+ else if (!stats.isFile() || stats.nlink !== 1n) {
303
+ return false;
304
+ }
305
+ }
306
+ return true;
307
+ }
308
+ async function alternatesStayInsideCommonDir(commonDir, text) {
309
+ const objectDir = path.join(commonDir, "objects");
310
+ for (const line of text.split(/\r?\n/).map((value) => value.trim()).filter(Boolean)) {
311
+ const candidate = path.isAbsolute(line) ? line : path.resolve(objectDir, line);
312
+ let physical;
313
+ try {
314
+ physical = await realpath(candidate);
315
+ }
316
+ catch {
317
+ return false;
318
+ }
319
+ const relative = path.relative(commonDir, physical);
320
+ if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
321
+ return false;
322
+ }
323
+ }
324
+ return true;
325
+ }
326
+ function parseGitdirFile(text) {
327
+ const match = /^gitdir:\s*([^\r\n]+)\r?\n?$/.exec(text);
328
+ return match?.[1]?.trim() || null;
329
+ }
330
+ function parseSinglePathLine(text) {
331
+ const match = /^([^\r\n]+)\r?\n?$/.exec(text);
332
+ return match?.[1]?.trim() || null;
333
+ }
334
+ function isSafeGitRef(value) {
335
+ return value.startsWith("refs/")
336
+ && !value.includes("\\")
337
+ && !value.includes("\0")
338
+ && !value.includes("//")
339
+ && value.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
340
+ }
341
+ async function readSingleLinkRegularFile(filePath, allowMissing = false) {
342
+ let before;
343
+ try {
344
+ before = await lstat(filePath, { bigint: true });
345
+ }
346
+ catch (error) {
347
+ if (allowMissing && isNodeError(error) && error.code === "ENOENT") {
348
+ return null;
349
+ }
350
+ throw error;
351
+ }
352
+ if (before.isSymbolicLink() || !before.isFile() || before.nlink !== 1n) {
353
+ return null;
354
+ }
355
+ const handle = await open(filePath, constants.O_RDONLY | constants.O_NOFOLLOW);
356
+ try {
357
+ const opened = await handle.stat({ bigint: true });
358
+ if (!opened.isFile()
359
+ || opened.nlink !== 1n
360
+ || opened.dev !== before.dev
361
+ || opened.ino !== before.ino) {
362
+ return null;
363
+ }
364
+ const text = await handle.readFile("utf8");
365
+ return Object.freeze({
366
+ identity: Object.freeze({ dev: opened.dev, ino: opened.ino }),
367
+ text
368
+ });
369
+ }
370
+ finally {
371
+ await handle.close();
372
+ }
373
+ }
374
+ async function isSingleLinkRegularFileOrMissing(filePath) {
375
+ let before;
376
+ try {
377
+ before = await lstat(filePath, { bigint: true });
378
+ }
379
+ catch (error) {
380
+ return isNodeError(error) && error.code === "ENOENT";
381
+ }
382
+ if (before.isSymbolicLink() || !before.isFile() || before.nlink !== 1n) {
383
+ return false;
384
+ }
385
+ const handle = await open(filePath, constants.O_RDONLY | constants.O_NOFOLLOW).catch(() => null);
386
+ if (!handle)
387
+ return false;
388
+ try {
389
+ const opened = await handle.stat({ bigint: true });
390
+ return opened.isFile()
391
+ && opened.nlink === 1n
392
+ && opened.dev === before.dev
393
+ && opened.ino === before.ino;
394
+ }
395
+ finally {
396
+ await handle.close();
397
+ }
398
+ }
399
+ async function stillSameSingleLinkFile(filePath, identity) {
400
+ try {
401
+ const stats = await lstat(filePath, { bigint: true });
402
+ return !stats.isSymbolicLink()
403
+ && stats.isFile()
404
+ && stats.nlink === 1n
405
+ && stats.dev === identity.dev
406
+ && stats.ino === identity.ino;
407
+ }
408
+ catch {
409
+ return false;
410
+ }
411
+ }
412
+ async function isPhysicalDirectory(directory) {
413
+ try {
414
+ const stats = await lstat(directory);
415
+ return !stats.isSymbolicLink() && stats.isDirectory() && await realpath(directory) === directory;
416
+ }
417
+ catch {
418
+ return false;
419
+ }
420
+ }
421
+ async function isPhysicalDirectoryOrMissing(directory) {
422
+ try {
423
+ const stats = await lstat(directory);
424
+ return !stats.isSymbolicLink() && stats.isDirectory() && await realpath(directory) === directory;
425
+ }
426
+ catch (error) {
427
+ return isNodeError(error) && error.code === "ENOENT";
428
+ }
429
+ }
430
+ async function pathExists(filePath) {
431
+ try {
432
+ await lstat(filePath);
433
+ return true;
434
+ }
435
+ catch (error) {
436
+ if (isNodeError(error) && error.code === "ENOENT")
437
+ return false;
438
+ throw error;
439
+ }
440
+ }
441
+ function unsafeInspection(worktreeRoot, note) {
442
+ return { note, status: "unsafe", worktreeRoot };
443
+ }
444
+ function isNodeError(error) {
445
+ return error instanceof Error && "code" in error;
446
+ }
447
+ //# sourceMappingURL=git-workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-workspace.js","sourceRoot":"","sources":["../../src/core/git-workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,mCAAmC,GAAG,6CAA6C,CAAC;AACjG,MAAM,CAAC,MAAM,oCAAoC,GAAG,6CAA6C,CAAC;AAyBlG;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,QAAgB;IAChE,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YACzD,OAAO,gBAAgB,CAAC,OAAO,EAAE,mCAAmC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,mCAAmC,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,WAAW,CAAC;QAChB,IAAI,CAAC;YACH,WAAW,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnD,OAAO,gBAAgB,CAAC,OAAO,EAAE,mCAAmC,CAAC,CAAC;YACxE,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YAC/B,CAAC;YACD,OAAO,GAAG,MAAM,CAAC;YACjB,SAAS;QACX,CAAC;QAED,IAAI,WAAW,CAAC,cAAc,EAAE,EAAE,CAAC;YACjC,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,IAAI,MAAM,QAAQ,CAAC,UAAU,CAAC,KAAK,UAAU,EAAE,CAAC;oBAC9C,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;gBACzE,CAAC;gBACD,sEAAsE;gBACtE,uEAAuE;gBACvE,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;oBACzD,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;gBACzE,CAAC;gBACD,MAAM,eAAe,GAAa,EAAE,CAAC;gBACrC,MAAM,SAAS,GAAyB;oBACtC,SAAS,EAAE,UAAU;oBACrB,eAAe;oBACf,MAAM,EAAE,UAAU;oBAClB,IAAI,EAAE,WAAW;oBACjB,SAAS,EAAE,OAAO;oBAClB,YAAY,EAAE,OAAO;iBACtB,CAAC;gBACF,OAAO,MAAM,2BAA2B,CAAC,SAAS,CAAC;oBACjD,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,uBAAuB,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE;oBACxF,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACtE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,WAAW,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;YACtD,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,UAAU,CAAC,CAAC;YAC3D,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACpE,IAAI,CAAC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC/B,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAC3B,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC;gBAC7B,CAAC,CAAC,cAAc;gBAChB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,CAC1C,CAAC;YACF,IAAI,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvC,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;YAClF,MAAM,WAAW,GAAG,MAAM,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;YACjF,MAAM,iBAAiB,GAAG,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjF,MAAM,mBAAmB,GAAG,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACvF,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,IAAI,CAAC,iBAAiB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7E,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;YAC1E,IACE,CAAC,MAAM,mBAAmB,CAAC,SAAS,CAAC;mBAClC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,MAAM;mBACnC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC;mBAC1D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EACrC,CAAC;gBACD,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CACxC,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;gBAClC,CAAC,CAAC,mBAAmB;gBACrB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAC9C,CAAC;YACF,IAAI,mBAAmB,KAAK,UAAU,EAAE,CAAC;gBACvC,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC1C,IACE,CAAC,MAAM,mBAAmB,CAAC,SAAS,CAAC;mBAClC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,SAAS;mBAC1D,CAAC,MAAM,uBAAuB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC;mBAC3D,CAAC,MAAM,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC;mBAClF,CAAC,MAAM,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,EACpF,CAAC;gBACD,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,eAAe,GAAa,EAAE,CAAC;YACrC,MAAM,SAAS,GAAyB;gBACtC,SAAS;gBACT,eAAe;gBACf,MAAM;gBACN,IAAI,EAAE,iBAAiB;gBACvB,SAAS;gBACT,YAAY,EAAE,OAAO;aACtB,CAAC;YACF,OAAO,MAAM,2BAA2B,CAAC,SAAS,CAAC;gBACjD,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,uBAAuB,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE;gBACxF,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,gBAAgB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,2BAA2B,CAAC,SAA+B;IACxE,IACE,CAAC,MAAM,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC;WACzC,CAAC,MAAM,mBAAmB,CAAC,SAAS,CAAC,SAAS,CAAC;WAC/C,CAAC,MAAM,mBAAmB,CAAC,SAAS,CAAC,YAAY,CAAC,EACrD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,iBAAiB,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC;KAC9C,CAAC,CAAC;IACH,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,gCAAgC,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,uEAAuE;IACvE,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACtE,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,IAAI,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;gBAChF,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,MAAM,SAAS,IAAI;QACtB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;KACvC,EAAE,CAAC;QACF,IAAI,CAAC,MAAM,4BAA4B,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IACxF,IAAI,IAAI,IAAI,CAAC,MAAM,qBAAqB,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACvF,IAAI,CAAC,MAAM,gCAAgC,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,yBAAyB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACzE,IAAI,UAAU,IAAI,CAAC,MAAM,6BAA6B,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7F,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,gCAAgC,CAAC,SAAS,CAAC,CAAC;IACpE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IACA,SAAS,CAAC,eAA4B,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,gCAAgC,CAAC,SAA+B;IAC7E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,UAAU,IAAI,IAAI,GAAG,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;KAC/C,CAAC,EAAE,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,IAAI,iCAAiC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjD,sEAAsE;gBACtE,kEAAkE;gBAClE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,YAAY,GAAG,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,CAAC,YAAY;gBAAE,SAAS;YAC5B,MAAM,OAAO,GAAG,uFAAuF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnH,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAClG,IAAI,CAAC,SAAS,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpE,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,QAAQ;gBAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;;gBAC9D,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,SAAS,CAAC,IAAI,CACZ,UAAU,MAAM,SAAS,EACzB,UAAU,MAAM,UAAU,EAC1B,UAAU,MAAM,WAAW,EAC3B,UAAU,MAAM,iBAAiB,CAClC,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,SAAS,CAAC,IAAI,CAAC,QAAQ,MAAM,WAAW,EAAE,QAAQ,MAAM,YAAY,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAa;IAChD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,IAAI,CAAC;YACf,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACjC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACtD,MAAM,IAAI,OAAO,CAAC;QAClB,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,uBAAuB,CAC9B,SAA+B,EAC/B,eAAyB;IAEzB,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,SAA+B,EAAE,QAAgB;IACpF,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4EAA4E;IAC5E,wEAAwE;IACxE,kDAAkD;IAClD,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvE,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,SAAS,EAAE,CAAC;QAC7C,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,kCAAkC,CAC3C,SAAS,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,EAC/F,SAAS,CACV,EAAE,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,kCAAkC,CAAC,IAAY,EAAE,QAAgB;IAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxG,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1C,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAClD,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;QACvD,CAAC;QACD,IAAI,KAAK,CAAC,cAAc,EAAE;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,OAAO,KAAK,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,6BAA6B,CAAC,SAAiB,EAAE,IAAY;IAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAClD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACpF,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/E,IAAI,QAAgB,CAAC;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACpD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3F,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,KAAK,GAAG,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AACpC,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AACpC,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;WAC3B,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;WACrB,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;WACrB,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;WACrB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC;AACtG,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,QAAgB,EAChB,YAAY,GAAG,KAAK;IAEpB,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,YAAY,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IAC/E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,IACE,CAAC,MAAM,CAAC,MAAM,EAAE;eACb,MAAM,CAAC,KAAK,KAAK,EAAE;eACnB,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG;eACzB,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,EAC5B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;YAC7D,IAAI;SACL,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gCAAgC,CAAC,QAAgB;IAC9D,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;IACvD,CAAC;IACD,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;QACvE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACjG,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC,MAAM,EAAE;eACjB,MAAM,CAAC,KAAK,KAAK,EAAE;eACnB,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG;eACzB,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC;IACjC,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,QAAgB,EAAE,QAAsB;IAC7E,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE;eACzB,KAAK,CAAC,MAAM,EAAE;eACd,KAAK,CAAC,KAAK,KAAK,EAAE;eAClB,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG;eAC1B,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IAClD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,MAAM,QAAQ,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;IACnG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,4BAA4B,CAAC,SAAiB;IAC3D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,MAAM,QAAQ,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;IACnG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;IACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAChE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,YAAoB,EACpB,IAA8F;IAE9F,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC;AACnD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { CORE_RUN_ID_PATTERN, HISTORY_ENTRY_SCHEMA, LATEST_POINTER_SCHEMA, assertRunId, buildArtifactLayout, buildRunId, createHistoryEntry, createLatestPointer, createLifecycleEvent, isValidRunId, summarizeTiming } from "./run-primitives.js";
2
+ export type { ArtifactLayout, BuildRunIdOptions, CoreLifecycleEvent, CoreRunMode, LatestRunPointer, RunHistoryEntry, TimingSummary } from "./run-primitives.js";
3
+ export { GIT_STATE_SCHEMA, captureGitState, summarizePorcelainStatus } from "./git-state.js";
4
+ export type { CapturedGitState, GitCommandResult, GitCommandRunner, GitRefState, GitStateChangeSummary, GitStateStatus } from "./git-state.js";
@@ -0,0 +1,3 @@
1
+ export { CORE_RUN_ID_PATTERN, HISTORY_ENTRY_SCHEMA, LATEST_POINTER_SCHEMA, assertRunId, buildArtifactLayout, buildRunId, createHistoryEntry, createLatestPointer, createLifecycleEvent, isValidRunId, summarizeTiming } from "./run-primitives.js";
2
+ export { GIT_STATE_SCHEMA, captureGitState, summarizePorcelainStatus } from "./git-state.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAU7B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACzB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,66 @@
1
+ export declare const CORE_RUN_ID_PATTERN: RegExp;
2
+ export declare const LATEST_POINTER_SCHEMA = "humanish.latest-run.v1";
3
+ export declare const HISTORY_ENTRY_SCHEMA = "humanish.run-history-entry.v1";
4
+ export type CoreRunMode = "dry-run" | "live";
5
+ export interface BuildRunIdOptions {
6
+ prefix: string;
7
+ createdAt: Date | string;
8
+ entropy: string;
9
+ }
10
+ export interface ArtifactLayout {
11
+ artifactRoot: string;
12
+ run: string;
13
+ reviewJson: string;
14
+ reviewMarkdown: string;
15
+ observerData: string;
16
+ events: string;
17
+ latestPointer: string;
18
+ }
19
+ export interface LatestRunPointer {
20
+ schema: typeof LATEST_POINTER_SCHEMA;
21
+ runId: string;
22
+ path: string;
23
+ updatedAt: string;
24
+ }
25
+ export interface RunHistoryEntry {
26
+ schema: typeof HISTORY_ENTRY_SCHEMA;
27
+ runId: string;
28
+ createdAt: string;
29
+ mode: CoreRunMode;
30
+ path: string;
31
+ }
32
+ export interface CoreLifecycleEvent {
33
+ at: string;
34
+ event: string;
35
+ message: string;
36
+ }
37
+ export interface TimingSummary {
38
+ startedAt: string;
39
+ endedAt: string | null;
40
+ durationMs: number | null;
41
+ status: "running" | "complete";
42
+ }
43
+ export declare function buildRunId(options: BuildRunIdOptions): string;
44
+ export declare function isValidRunId(value: string): boolean;
45
+ export declare function assertRunId(value: string): void;
46
+ export declare function buildArtifactLayout(runId: string, runsRoot?: string): ArtifactLayout;
47
+ export declare function createLatestPointer(options: {
48
+ runId: string;
49
+ artifactRoot: string;
50
+ updatedAt: Date | string;
51
+ }): LatestRunPointer;
52
+ export declare function createHistoryEntry(options: {
53
+ runId: string;
54
+ createdAt: Date | string;
55
+ mode: CoreRunMode;
56
+ artifactRoot: string;
57
+ }): RunHistoryEntry;
58
+ export declare function createLifecycleEvent(options: {
59
+ at: Date | string;
60
+ event: string;
61
+ message: string;
62
+ }): CoreLifecycleEvent;
63
+ export declare function summarizeTiming(options: {
64
+ startedAt: Date | string;
65
+ endedAt?: Date | string;
66
+ }): TimingSummary;
@@ -0,0 +1,120 @@
1
+ export const CORE_RUN_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,127}$/;
2
+ export const LATEST_POINTER_SCHEMA = "humanish.latest-run.v1";
3
+ export const HISTORY_ENTRY_SCHEMA = "humanish.run-history-entry.v1";
4
+ export function buildRunId(options) {
5
+ const prefix = toSafeSegment(options.prefix, "run");
6
+ const entropy = toSafeSegment(options.entropy, "proof");
7
+ const timestamp = toTimestampSegment(options.createdAt);
8
+ const runId = `${prefix}-${timestamp}-${entropy}`;
9
+ assertRunId(runId);
10
+ return runId;
11
+ }
12
+ export function isValidRunId(value) {
13
+ return CORE_RUN_ID_PATTERN.test(value) && !value.includes("--");
14
+ }
15
+ export function assertRunId(value) {
16
+ if (!isValidRunId(value)) {
17
+ throw new Error(`Invalid run id: ${value}`);
18
+ }
19
+ }
20
+ export function buildArtifactLayout(runId, runsRoot = ".humanish/runs") {
21
+ assertRunId(runId);
22
+ const normalizedRoot = normalizeRelativePath(runsRoot);
23
+ const artifactRoot = `${normalizedRoot}/${runId}`;
24
+ return {
25
+ artifactRoot,
26
+ run: `${artifactRoot}/run.json`,
27
+ reviewJson: `${artifactRoot}/review.json`,
28
+ reviewMarkdown: `${artifactRoot}/review.md`,
29
+ observerData: `${artifactRoot}/observer/observer-data.json`,
30
+ events: `${artifactRoot}/events.ndjson`,
31
+ latestPointer: `${normalizedRoot}/latest.json`
32
+ };
33
+ }
34
+ export function createLatestPointer(options) {
35
+ assertRunId(options.runId);
36
+ return {
37
+ schema: LATEST_POINTER_SCHEMA,
38
+ runId: options.runId,
39
+ path: normalizeRelativePath(options.artifactRoot),
40
+ updatedAt: toIsoString(options.updatedAt)
41
+ };
42
+ }
43
+ export function createHistoryEntry(options) {
44
+ assertRunId(options.runId);
45
+ return {
46
+ schema: HISTORY_ENTRY_SCHEMA,
47
+ runId: options.runId,
48
+ createdAt: toIsoString(options.createdAt),
49
+ mode: options.mode,
50
+ path: normalizeRelativePath(options.artifactRoot)
51
+ };
52
+ }
53
+ export function createLifecycleEvent(options) {
54
+ const event = options.event.trim();
55
+ const message = options.message.trim();
56
+ if (event.length === 0) {
57
+ throw new Error("Lifecycle event is required.");
58
+ }
59
+ if (message.length === 0) {
60
+ throw new Error("Lifecycle message is required.");
61
+ }
62
+ return {
63
+ at: toIsoString(options.at),
64
+ event,
65
+ message
66
+ };
67
+ }
68
+ export function summarizeTiming(options) {
69
+ const startedAt = toIsoString(options.startedAt);
70
+ if (options.endedAt === undefined) {
71
+ return {
72
+ startedAt,
73
+ endedAt: null,
74
+ durationMs: null,
75
+ status: "running"
76
+ };
77
+ }
78
+ const endedAt = toIsoString(options.endedAt);
79
+ const durationMs = new Date(endedAt).getTime() - new Date(startedAt).getTime();
80
+ if (durationMs < 0) {
81
+ throw new Error("Timing summary endedAt must be after startedAt.");
82
+ }
83
+ return {
84
+ startedAt,
85
+ endedAt,
86
+ durationMs,
87
+ status: "complete"
88
+ };
89
+ }
90
+ function toTimestampSegment(value) {
91
+ return toIsoString(value).toLowerCase().replace(/[:.]/g, "-");
92
+ }
93
+ function toIsoString(value) {
94
+ const date = value instanceof Date ? value : new Date(value);
95
+ if (Number.isNaN(date.getTime())) {
96
+ throw new Error(`Invalid date: ${String(value)}`);
97
+ }
98
+ return date.toISOString();
99
+ }
100
+ function toSafeSegment(value, fallback) {
101
+ const normalized = value
102
+ .trim()
103
+ .toLowerCase()
104
+ .replace(/[^a-z0-9]+/g, "-")
105
+ .replace(/^-+|-+$/g, "")
106
+ .slice(0, 48);
107
+ return normalized.length > 0 ? normalized : fallback;
108
+ }
109
+ function normalizeRelativePath(value) {
110
+ const normalized = value.replace(/\\/g, "/");
111
+ if (normalized.startsWith("/") || /^[A-Za-z]:\//.test(normalized)) {
112
+ throw new Error(`Artifact paths must be relative: ${value}`);
113
+ }
114
+ const parts = normalized.split("/").filter((part) => part.length > 0);
115
+ if (parts.length === 0 || parts.some((part) => part === "." || part === "..")) {
116
+ throw new Error(`Artifact path contains an unsafe segment: ${value}`);
117
+ }
118
+ return parts.join("/");
119
+ }
120
+ //# sourceMappingURL=run-primitives.js.map