@indigoai-us/hq-cli 5.312.1 → 5.312.2-beta.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 (48) hide show
  1. package/CHANGELOG.md +2 -5
  2. package/dist/command-catalog.generated.d.ts +0 -65
  3. package/dist/command-catalog.generated.js +0 -80
  4. package/dist/commands/cloud.js +1 -0
  5. package/dist/commands/company.js +0 -2
  6. package/dist/commands/core.js +0 -7
  7. package/dist/fast-core.js +3 -10
  8. package/dist/fast-scaffold.d.ts +0 -2
  9. package/dist/fast-scaffold.js +0 -11
  10. package/dist/lib/doctor/checks/work-context.js +1 -9
  11. package/dist/lib/mesh/client.js +5 -23
  12. package/dist/lib/mesh/live/daemon/doctor.d.ts +0 -2
  13. package/dist/lib/mesh/live/daemon/doctor.js +1 -11
  14. package/dist/lib/search-index/embed-lock.d.ts +0 -2
  15. package/dist/lib/search-index/embed-lock.js +1 -10
  16. package/dist/lib/work-context/contract.d.ts +0 -3
  17. package/dist/lib/work-context/contract.schema.json +1 -3
  18. package/dist/lib/work-context/outbox.d.ts +5 -14
  19. package/dist/lib/work-context/outbox.js +5 -48
  20. package/dist/lib/work-context/reconcile.js +5 -26
  21. package/dist/main.d.ts +0 -20
  22. package/dist/main.js +1 -8
  23. package/package.json +1 -1
  24. package/assets/scaffold/core/scripts/lib/work-mesh-live-hook.sh +0 -378
  25. package/assets/scaffold/core/scripts/lib/work-mesh-live-rebind.sh +0 -141
  26. package/assets/scaffold/core/scripts/migrate-policy-triggers.sh +0 -373
  27. package/assets/scaffold/core/scripts/register-project.sh +0 -262
  28. package/assets/scaffold/core/scripts/work-mesh-live-rebind.sh +0 -59
  29. package/dist/commands/company-rename-flag.d.ts +0 -4
  30. package/dist/commands/company-rename-flag.js +0 -7
  31. package/dist/commands/company-rename.d.ts +0 -4
  32. package/dist/commands/company-rename.js +0 -90
  33. package/dist/commands/core-eval-trigger-native.d.ts +0 -4
  34. package/dist/commands/core-eval-trigger-native.js +0 -12
  35. package/dist/commands/core-migrate-policy-triggers-native.d.ts +0 -21
  36. package/dist/commands/core-migrate-policy-triggers-native.js +0 -378
  37. package/dist/commands/core-native-hook-helper-commands.d.ts +0 -4
  38. package/dist/commands/core-native-hook-helper-commands.js +0 -56
  39. package/dist/commands/core-native-hook-helpers-flag.d.ts +0 -4
  40. package/dist/commands/core-native-hook-helpers-flag.js +0 -7
  41. package/dist/commands/core-register-project-native.d.ts +0 -30
  42. package/dist/commands/core-register-project-native.js +0 -347
  43. package/dist/commands/core-work-mesh-live-rebind-native.d.ts +0 -18
  44. package/dist/commands/core-work-mesh-live-rebind-native.js +0 -262
  45. package/dist/lib/mesh/denial-codes.d.ts +0 -5
  46. package/dist/lib/mesh/denial-codes.js +0 -14
  47. package/dist/utils/core-eval-trigger.d.ts +0 -4
  48. package/dist/utils/core-eval-trigger.js +0 -88
@@ -1,347 +0,0 @@
1
- /** Native implementation of core/scripts/register-project.sh. */
2
- import * as fs from "node:fs";
3
- import * as os from "node:os";
4
- import * as path from "node:path";
5
- import { spawnSync } from "node:child_process";
6
- import { serializeJqJson } from "../lib/core-utils/jq-json-serializer.js";
7
- import { resolveBundledAsset } from "../utils/hq-roots.js";
8
- export const REGISTER_PROJECT_ASSET = "core/scripts/register-project.sh";
9
- const USAGE = "usage: register-project.sh <company> <project> | --audit <company> | --backfill <company> --only-active [--yes] | --retry-pending <company>";
10
- const MIN_HQ_CLI = "5.139.0";
11
- export function createRegisterProjectHqRunner(spawn = spawnSync) {
12
- return (args, options) => {
13
- const result = spawn("hq", args, {
14
- cwd: options.cwd,
15
- env: options.env,
16
- encoding: "utf8",
17
- // Shell hq children inherit fd 0 even when their output is captured or discarded.
18
- stdio: options.capture ? ["inherit", "pipe", "pipe"] : ["inherit", "ignore", "ignore"],
19
- });
20
- return {
21
- code: result.status ?? 127,
22
- stdout: options.capture ? String(result.stdout ?? "") : "",
23
- stderr: options.capture ? String(result.stderr ?? "") : "",
24
- };
25
- };
26
- }
27
- const defaultRunHq = createRegisterProjectHqRunner();
28
- function errorResult(message, code = 1) { return { code, stdout: "", stderr: `${message}\n` }; }
29
- function asRecord(value) {
30
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
31
- }
32
- function jqOr(value, fallback) { return value === null || value === undefined || value === false ? fallback : value; }
33
- function jqString(value) {
34
- if (typeof value === "string")
35
- return value;
36
- if (value === null || value === undefined || value === false)
37
- return "";
38
- return typeof value === "object" ? JSON.stringify(value) : String(value);
39
- }
40
- function readJson(fileSystem, file) {
41
- return JSON.parse(fileSystem.readFileSync(file, "utf8"));
42
- }
43
- function timestamp(deps) { return deps.now().toISOString().replace(/\.\d{3}Z$/, "Z"); }
44
- function companyUid(company, deps) {
45
- const direct = deps.env.HQ_COMPANY_UID ?? "";
46
- if (direct)
47
- return direct;
48
- const file = path.join(deps.root, "companies", company, ".company-uid");
49
- try {
50
- return deps.fs.readFileSync(file, "utf8").replace(/[\s\u0085\u00a0]+/g, "");
51
- }
52
- catch {
53
- return null;
54
- }
55
- }
56
- function boardPath(company, deps) { return path.join(deps.root, "companies", company, "board.json"); }
57
- function runHelpProbe(deps) {
58
- return deps.runHq(["mesh", "project", "ensure", "--help"], { cwd: deps.cwd, env: deps.env, capture: false }).code === 0;
59
- }
60
- function prdName(prd, deps) {
61
- const value = readJson(deps.fs, prd);
62
- return jqString(jqOr(asRecord(value)?.name, ""));
63
- }
64
- function boardData(company, board, deps) {
65
- if (!deps.fs.existsSync(board))
66
- return { company, projects: [] };
67
- const value = asRecord(readJson(deps.fs, board));
68
- if (!value)
69
- throw new Error("board.json must contain an object");
70
- return value;
71
- }
72
- function projectRows(board) {
73
- const projects = jqOr(board.projects, []);
74
- if (!Array.isArray(projects))
75
- throw new Error("board.json projects must be an array");
76
- return projects.map((item) => {
77
- const record = asRecord(item);
78
- if (!record)
79
- throw new Error("board.json project must be an object");
80
- return record;
81
- });
82
- }
83
- function matchesProject(row, id, rel) {
84
- return row.id === id || row.prd_path === rel || row.mesh_project_id === id;
85
- }
86
- function atomicJqWrite(target, value, deps, initialize = false) {
87
- deps.fs.mkdirSync(path.dirname(target), { recursive: true });
88
- if (initialize && !deps.fs.existsSync(target))
89
- deps.fs.writeFileSync(target, serializeJqJson(value, "pretty"), { encoding: "utf8", mode: 0o666 });
90
- const temporary = path.join(path.dirname(target), `.register-project.${process.pid}.${Math.random().toString(16).slice(2)}`);
91
- deps.fs.writeFileSync(temporary, serializeJqJson(value, "pretty"), { encoding: "utf8", mode: 0o600, flag: "wx" });
92
- deps.fs.chmodSync(temporary, 0o600);
93
- deps.fs.renameSync(temporary, target);
94
- }
95
- function markPending(company, project, deps) {
96
- const board = boardPath(company, deps);
97
- const prd = path.join(deps.root, "companies", company, "projects", project, "prd.json");
98
- const rel = `companies/${company}/projects/${project}/prd.json`;
99
- const now = timestamp(deps);
100
- let title = "";
101
- try {
102
- title = prdName(prd, deps);
103
- }
104
- catch { /* shell suppresses title jq errors */ }
105
- if (!title)
106
- title = project;
107
- const document = boardData(company, board, deps);
108
- const rows = projectRows(document);
109
- if (rows.some((row) => matchesProject(row, project, rel))) {
110
- document.projects = rows.map((row) => matchesProject(row, project, rel)
111
- ? { ...row, pending_registration: true, updated_at: now, prd_path: jqOr(row.prd_path, rel) }
112
- : row);
113
- }
114
- else {
115
- document.projects = [...rows, {
116
- id: project, title, status: "prd_created", scope: "company", prd_path: rel,
117
- pending_registration: true, created_at: now, updated_at: now,
118
- }];
119
- }
120
- atomicJqWrite(board, document, deps, true);
121
- }
122
- function ensureOne(company, project, deps) {
123
- const prd = path.join(deps.root, "companies", company, "projects", project, "prd.json");
124
- if (!deps.fs.existsSync(prd))
125
- return errorResult(`registration incomplete: missing ${prd}`);
126
- if (!runHelpProbe(deps)) {
127
- try {
128
- markPending(company, project, deps);
129
- }
130
- catch { /* legacy jq/write errors remain a failed registration */ }
131
- return errorResult(`hq-cli ${MIN_HQ_CLI} or newer is required; ${company}/${project} stays local until then`);
132
- }
133
- const ensure = deps.runHq(["mesh", "project", "ensure", project, "--company", company, "--stories-file", prd, "--json"], {
134
- cwd: deps.cwd, env: deps.env, capture: true,
135
- });
136
- if (ensure.code !== 0)
137
- return errorResult(`registration incomplete: hq mesh project ensure failed for ${company}/${project}`);
138
- let result;
139
- try {
140
- result = asRecord(JSON.parse(ensure.stdout));
141
- }
142
- catch {
143
- return errorResult("registration incomplete: ensure output missing threadId");
144
- }
145
- if (result?.threadId === null || result?.threadId === undefined || result?.threadId === false)
146
- return errorResult("registration incomplete: ensure output missing threadId");
147
- if (result?.channelId === null || result?.channelId === undefined || result?.channelId === false)
148
- return errorResult("registration incomplete: ensure output missing channelId");
149
- const thread = jqString(result.threadId);
150
- const channel = jqString(result.channelId);
151
- if (!thread)
152
- return errorResult("registration incomplete: empty threadId");
153
- if (!channel)
154
- return errorResult("registration incomplete: empty channelId");
155
- const board = boardPath(company, deps);
156
- const rel = `companies/${company}/projects/${project}/prd.json`;
157
- const now = timestamp(deps);
158
- let title = prdName(prd, deps);
159
- if (!title)
160
- title = project;
161
- const document = boardData(company, board, deps);
162
- const rows = projectRows(document);
163
- if (rows.some((row) => matchesProject(row, project, rel))) {
164
- document.projects = rows.map((row) => {
165
- if (!matchesProject(row, project, rel))
166
- return row;
167
- const updated = { ...row, threadId: thread, channelId: channel, updated_at: now, prd_path: jqOr(row.prd_path, rel), mesh_project_id: project };
168
- delete updated.pending_registration;
169
- return updated;
170
- });
171
- }
172
- else {
173
- document.projects = [...rows, {
174
- id: project, title, status: "prd_created", scope: "company", prd_path: rel,
175
- threadId: thread, channelId: channel, mesh_project_id: project, created_at: now, updated_at: now,
176
- }];
177
- }
178
- try {
179
- atomicJqWrite(board, document, deps, true);
180
- }
181
- catch {
182
- return errorResult("registration incomplete: board.json write failed");
183
- }
184
- const written = boardData(company, board, deps);
185
- const verified = projectRows(written).some((row) => matchesProject(row, project, rel) && row.threadId === thread && row.channelId === channel);
186
- if (!verified)
187
- return errorResult(`registration incomplete: board.json entry for ${project} did not verify`);
188
- return { code: 0, stdout: `registered ${company}/${project} thread=${thread} channel=${channel}\n`, stderr: "" };
189
- }
190
- function audit(company, deps) {
191
- if (!company)
192
- return errorResult("usage: register-project.sh --audit <company>");
193
- const directory = path.join(deps.root, "companies", company, "projects");
194
- let projects;
195
- try {
196
- projects = deps.fs.readdirSync(directory).sort();
197
- }
198
- catch {
199
- return { code: 0, stdout: "", stderr: "" };
200
- }
201
- let stderr = "";
202
- const unregistered = projects.filter((project) => {
203
- if (project.startsWith("."))
204
- return false;
205
- const prd = path.join(directory, project, "prd.json");
206
- try {
207
- if (!deps.fs.statSync(prd).isFile())
208
- return false;
209
- const uid = companyUid(company, deps);
210
- if (uid === null) {
211
- stderr += `no company uid for ${company} (set HQ_COMPANY_UID or companies/${company}/.company-uid)\n`;
212
- return true;
213
- }
214
- return !deps.fs.existsSync(path.join(deps.env.HOME || os.homedir(), ".hq/work-mesh/cache/projects", uid, `${project}.json`));
215
- }
216
- catch {
217
- return false;
218
- }
219
- });
220
- return { code: 0, stdout: unregistered.length ? `${unregistered.join("\n")}\n` : "", stderr };
221
- }
222
- function storyNotDone(prd, deps, diagnostics) {
223
- try {
224
- const stories = asRecord(readJson(deps.fs, prd))?.userStories;
225
- if (!Array.isArray(stories))
226
- return false;
227
- return stories.some((story) => jqOr(asRecord(story)?.status, "") !== "done");
228
- }
229
- catch {
230
- const jq = spawnSync("jq", ["-e", '[.userStories[]? | select((.status // "") != "done")] | length > 0', prd], {
231
- cwd: deps.cwd, env: deps.env, encoding: "utf8",
232
- });
233
- if (jq.stderr)
234
- diagnostics.push(jq.stderr);
235
- else if (jq.error?.code === "ENOENT") {
236
- const script = resolveBundledAsset(REGISTER_PROJECT_ASSET);
237
- diagnostics.push(`${script}: line 34: jq: command not found\n`);
238
- }
239
- return false;
240
- }
241
- }
242
- function backfill(args, deps) {
243
- let company = "", only = false, yes = false;
244
- for (const arg of args) {
245
- if (arg === "--only-active")
246
- only = true;
247
- else if (arg === "--yes")
248
- yes = true;
249
- else if (arg.startsWith("--"))
250
- return errorResult(`unknown flag ${arg}`);
251
- else
252
- company = arg;
253
- }
254
- if (!company)
255
- return errorResult("usage: register-project.sh --backfill <company> --only-active [--yes]");
256
- if (!only)
257
- return errorResult("--backfill requires --only-active");
258
- const directory = path.join(deps.root, "companies", company, "projects");
259
- let projects;
260
- try {
261
- projects = deps.fs.readdirSync(directory).sort();
262
- }
263
- catch {
264
- return { code: 0, stdout: "", stderr: "" };
265
- }
266
- projects = projects.filter((project) => !project.startsWith("."));
267
- const diagnostics = [];
268
- const targets = projects.filter((project) => {
269
- const pdir = path.join(directory, project);
270
- const prd = path.join(pdir, "prd.json");
271
- try {
272
- if (!deps.fs.statSync(prd).isFile() || !storyNotDone(prd, deps, diagnostics))
273
- return false;
274
- return Math.floor(deps.now().getTime() / 1000) - Math.floor(deps.fs.statSync(pdir).mtimeMs / 1000) < 30 * 86400;
275
- }
276
- catch {
277
- return false;
278
- }
279
- });
280
- let stderr = diagnostics.join("");
281
- if (!yes)
282
- return { code: 0, stdout: targets.map((project) => `would register ${company}/${project}\n`).join(""), stderr };
283
- let stdout = "";
284
- for (const project of targets) {
285
- const output = ensureOne(company, project, deps);
286
- stdout += output.stdout;
287
- stderr += output.stderr;
288
- if (output.code !== 0)
289
- return { ...output, stdout, stderr };
290
- }
291
- return { code: 0, stdout, stderr };
292
- }
293
- function retryPending(company, deps) {
294
- if (!company)
295
- return errorResult("usage: register-project.sh --retry-pending <company>");
296
- if (!runHelpProbe(deps))
297
- return { code: 0, stdout: "", stderr: "" };
298
- const board = boardPath(company, deps);
299
- if (!deps.fs.existsSync(board))
300
- return { code: 0, stdout: "", stderr: "" };
301
- let rows;
302
- try {
303
- rows = projectRows(boardData(company, board, deps));
304
- }
305
- catch {
306
- return { code: 0, stdout: "", stderr: "" };
307
- }
308
- let stdout = "", stderr = "";
309
- const ids = rows.filter((item) => item.pending_registration === true)
310
- .map((row) => jqString(jqOr(row.id, ""))).filter(Boolean).slice(0, 3);
311
- for (const id of ids) {
312
- const result = ensureOne(company, id, deps);
313
- stdout += result.stdout;
314
- stderr += result.stderr;
315
- }
316
- return { code: 0, stdout, stderr };
317
- }
318
- export function runRegisterProject(args, deps) {
319
- try {
320
- const [mode, arg1, ...rest] = args;
321
- if (mode === "--audit")
322
- return audit(arg1 ?? "", deps);
323
- if (mode === "--backfill")
324
- return backfill([arg1 ?? "", ...rest].filter((value, index) => index > 0 || value !== ""), deps);
325
- if (mode === "--retry-pending")
326
- return retryPending(arg1 ?? "", deps);
327
- if (args.length === 2)
328
- return ensureOne(args[0], args[1], deps);
329
- return errorResult(USAGE);
330
- }
331
- catch (err) {
332
- return errorResult(err instanceof Error ? err.message : String(err));
333
- }
334
- }
335
- export async function runRegisterProjectFast(args, _stdin, cwd, root) {
336
- const chosenRoot = root || process.env.HQ_ROOT || cwd;
337
- const result = runRegisterProject(args, {
338
- root: chosenRoot, cwd, env: process.env, fs, now: () => new Date(),
339
- runHq: (argv, opts) => defaultRunHq(argv, opts),
340
- });
341
- if (result.stdout)
342
- process.stdout.write(result.stdout);
343
- if (result.stderr)
344
- process.stderr.write(result.stderr);
345
- return result.code;
346
- }
347
- //# sourceMappingURL=core-register-project-native.js.map
@@ -1,18 +0,0 @@
1
- /** Native implementation of core/scripts/work-mesh-live-rebind.sh. */
2
- import * as fs from "node:fs";
3
- export declare const WORK_MESH_LIVE_REBIND_ASSET = "core/scripts/work-mesh-live-rebind.sh";
4
- export type WorkMeshLiveRebindDeps = {
5
- cwd: string;
6
- root: string;
7
- env: NodeJS.ProcessEnv;
8
- fs: typeof fs;
9
- now: () => Date;
10
- ulid: (date: Date) => string;
11
- };
12
- export declare function runWorkMeshLiveRebind(args: readonly string[], deps: WorkMeshLiveRebindDeps): {
13
- code: number;
14
- stdout: string;
15
- stderr: string;
16
- };
17
- export declare function runWorkMeshLiveRebindFast(args: readonly string[], _stdin: string, cwd: string, root?: string): Promise<number>;
18
- //# sourceMappingURL=core-work-mesh-live-rebind-native.d.ts.map
@@ -1,262 +0,0 @@
1
- /** Native implementation of core/scripts/work-mesh-live-rebind.sh. */
2
- import * as fs from "node:fs";
3
- import * as os from "node:os";
4
- import * as path from "node:path";
5
- import { generateUlid } from "../lib/mesh/live/ulid.js";
6
- import { formatSpoolLine } from "../lib/mesh/live/format-spool-line.js";
7
- export const WORK_MESH_LIVE_REBIND_ASSET = "core/scripts/work-mesh-live-rebind.sh";
8
- const WORK_MESH_LIVE_REBIND_LIBRARY_ASSET = "core/scripts/lib/work-mesh-live-rebind.sh";
9
- const USAGE = "usage: work-mesh-live-rebind.sh --session <sid> ...\n";
10
- function defaultDeps(root, cwd, env) {
11
- return { root, cwd, env, fs, now: () => new Date(), ulid: (date) => generateUlid(date.getTime()) };
12
- }
13
- function stateRoot(deps) { return deps.env.WORK_MESH_HOME || deps.env.HOME || os.homedir(); }
14
- function markerPath(sid, deps) { return path.join(stateRoot(deps), ".hq/work-context/sessions", `${sid}.live-binding`); }
15
- class MarkerWriteError extends Error {
16
- target;
17
- constructor(target, cause) {
18
- super("live binding marker write failed", { cause });
19
- this.target = target;
20
- }
21
- }
22
- function readMarker(sid, deps) {
23
- try {
24
- const body = deps.fs.readFileSync(markerPath(sid, deps), "utf8").replace(/\r/g, "");
25
- const value = (key) => {
26
- const line = body.split("\n").find((row) => row.startsWith(`${key}=`));
27
- return line === undefined ? "" : line.slice(key.length + 1).split("=", 1)[0];
28
- };
29
- return [value("companySlug"), value("project"), value("task")];
30
- }
31
- catch {
32
- return ["", "", ""];
33
- }
34
- }
35
- function writeMarker(sid, company, project, task, deps) {
36
- const target = markerPath(sid, deps);
37
- const directory = path.dirname(target);
38
- try {
39
- deps.fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
40
- }
41
- catch { /* shell mkdir is best effort */ }
42
- try {
43
- deps.fs.chmodSync(directory, 0o700);
44
- }
45
- catch { /* shell chmod is best effort */ }
46
- try {
47
- deps.fs.writeFileSync(target, `companySlug=${company}\nproject=${project}\ntask=${task}\n`);
48
- }
49
- catch (error) {
50
- throw new MarkerWriteError(target, error);
51
- }
52
- try {
53
- deps.fs.chmodSync(target, 0o600);
54
- }
55
- catch { /* shell chmod is best effort */ }
56
- }
57
- function readState(sid, deps) {
58
- const file = path.join(stateRoot(deps), ".hq/work-context/sessions", `${sid}.json`);
59
- if (!deps.fs.existsSync(file))
60
- return null;
61
- try {
62
- const parsed = JSON.parse(deps.fs.readFileSync(file, "utf8"));
63
- const raw = (key) => {
64
- const value = parsed?.[key];
65
- if (value === null || value === undefined || value === false)
66
- return "";
67
- return typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value);
68
- };
69
- return { company: raw("companySlug"), project: raw("projectId"), task: raw("taskId") };
70
- }
71
- catch {
72
- return null;
73
- }
74
- }
75
- function nextSeq(sid, deps) {
76
- const directory = deps.env.WORK_MESH_SEQ_DIR || path.join(deps.env.HOME || os.homedir(), ".hq/work-mesh/seq");
77
- try {
78
- if (!deps.fs.existsSync(directory)) {
79
- deps.fs.mkdirSync(directory, { recursive: true });
80
- try {
81
- deps.fs.chmodSync(directory, 0o700);
82
- }
83
- catch { /* best effort */ }
84
- }
85
- }
86
- catch { /* next write will fail */ }
87
- const file = path.join(directory, sid);
88
- let current = "0";
89
- try {
90
- current = deps.fs.readFileSync(file, "utf8").replace(/\s/g, "");
91
- }
92
- catch { /* first event */ }
93
- if (!/^\d+$/.test(current))
94
- current = "0";
95
- const value = Number(current) + 1;
96
- if (!Number.isSafeInteger(value))
97
- return null;
98
- try {
99
- deps.fs.writeFileSync(file, `${value}\n`);
100
- return value;
101
- }
102
- catch {
103
- return null;
104
- }
105
- }
106
- function enqueueLifecycle(kind, sid, harness, adapter, company, project, task, deps) {
107
- const seq = nextSeq(sid, deps);
108
- if (seq === null)
109
- return false;
110
- const now = deps.now();
111
- const event = {
112
- v: 1,
113
- eventId: deps.ulid(now),
114
- kind,
115
- sessionId: sid,
116
- harness: harness,
117
- adapterVersion: adapter,
118
- at: `${now.toISOString().slice(0, 19)}.000Z`,
119
- seq,
120
- cwd: deps.env.PWD ?? "",
121
- hqRoot: deps.env.HQ_ROOT ?? deps.root,
122
- };
123
- if (company)
124
- event.companySlug = company;
125
- if (project)
126
- event.project = project;
127
- if (task)
128
- event.task = task;
129
- const spool = deps.env.WORK_MESH_SPOOL || path.join(deps.env.HOME || os.homedir(), ".hq/work-mesh/spool.jsonl");
130
- try {
131
- if (!deps.fs.existsSync(spool)) {
132
- try {
133
- deps.fs.mkdirSync(path.dirname(spool), { recursive: true, mode: 0o700 });
134
- }
135
- catch { /* legacy mkdir is best effort */ }
136
- try {
137
- deps.fs.chmodSync(path.dirname(spool), 0o700);
138
- }
139
- catch { /* best effort */ }
140
- deps.fs.writeFileSync(spool, "", { encoding: "utf8", mode: 0o600 });
141
- try {
142
- deps.fs.chmodSync(spool, 0o600);
143
- }
144
- catch { /* best effort */ }
145
- }
146
- const fd = deps.fs.openSync(spool, fs.constants.O_APPEND | fs.constants.O_WRONLY);
147
- try {
148
- deps.fs.writeSync(fd, `${formatSpoolLine(event)}\n`);
149
- }
150
- finally {
151
- deps.fs.closeSync(fd);
152
- }
153
- }
154
- catch { /* work_mesh_enqueue is called with `|| true` by the shell library */ }
155
- return true;
156
- }
157
- function normalizedHarness(env) {
158
- let value = env.HQ_HARNESS || env.HQ_WORK_MESH_HARNESS || env.HQ_CHECKPOINT_RUNTIME || "claude-code";
159
- if (["claude", "Claude", "ClaudeCode"].includes(value))
160
- value = "claude-code";
161
- else if (value === "Codex")
162
- value = "codex";
163
- else if (value === "Grok")
164
- value = "grok";
165
- return value;
166
- }
167
- function runRebind(sid, oldCompany, oldProject, oldTask, company, project, task, deps) {
168
- if (!sid || !project)
169
- return 1;
170
- if (oldProject === project) {
171
- writeMarker(sid, company, project, task, deps);
172
- return 0;
173
- }
174
- const harness = normalizedHarness(deps.env);
175
- const adapter = deps.env.HQ_ADAPTER_CONTRACT_VERSION || "1.0.0";
176
- if (oldProject && !enqueueLifecycle("session_end", sid, harness, adapter, oldCompany, oldProject, oldTask, deps))
177
- return 1;
178
- if (!enqueueLifecycle("session_start", sid, harness, adapter, company, project, task, deps))
179
- return 1;
180
- writeMarker(sid, company, project, task, deps);
181
- return 0;
182
- }
183
- function runWorkMeshLiveRebindUnsafe(args, deps) {
184
- let sid = "", oldCompany = "", oldProject = "", oldTask = "", company = "", project = "", task = "", fromState = false;
185
- const takesValue = {
186
- "--session": "sid", "--session-id": "sid", "--old-company": "oldCompany", "--old-project": "oldProject", "--old-task": "oldTask",
187
- "--company": "company", "--company-slug": "company", "--project": "project", "--task": "task",
188
- };
189
- for (let i = 0; i < args.length;) {
190
- const arg = args[i];
191
- const key = takesValue[arg];
192
- if (key) {
193
- if (i + 1 >= args.length)
194
- return { code: 1, stdout: "", stderr: `assets/scaffold/${WORK_MESH_LIVE_REBIND_ASSET}: line 27: shift: shift count out of range\n` };
195
- const value = args[i + 1] ?? "";
196
- if (key === "sid")
197
- sid = value;
198
- else if (key === "oldCompany")
199
- oldCompany = value;
200
- else if (key === "oldProject")
201
- oldProject = value;
202
- else if (key === "oldTask")
203
- oldTask = value;
204
- else if (key === "company")
205
- company = value;
206
- else if (key === "project")
207
- project = value;
208
- else
209
- task = value;
210
- i += 2;
211
- }
212
- else if (arg === "--from-state") {
213
- fromState = true;
214
- i += 1;
215
- }
216
- else
217
- i += 1;
218
- }
219
- if (!sid)
220
- return { code: 1, stdout: "", stderr: USAGE };
221
- if (fromState || !project) {
222
- const current = readState(sid, deps);
223
- if (!current?.project)
224
- return { code: 0, stdout: "", stderr: "" };
225
- const [previousCompany, previousProject, previousTask] = readMarker(sid, deps);
226
- if (!previousProject || previousProject === current.project) {
227
- writeMarker(sid, current.company, current.project, current.task, deps);
228
- return { code: 0, stdout: "", stderr: "" };
229
- }
230
- return { code: runRebind(sid, previousCompany, previousProject, previousTask, current.company, current.project, current.task, deps), stdout: "", stderr: "" };
231
- }
232
- if (!oldProject)
233
- [oldCompany, oldProject, oldTask] = readMarker(sid, deps);
234
- return { code: runRebind(sid, oldCompany, oldProject, oldTask, company, project, task, deps), stdout: "", stderr: "" };
235
- }
236
- export function runWorkMeshLiveRebind(args, deps) {
237
- try {
238
- return runWorkMeshLiveRebindUnsafe(args, deps);
239
- }
240
- catch (error) {
241
- if (!(error instanceof MarkerWriteError))
242
- throw error;
243
- const cause = error.cause;
244
- const message = cause?.code === "EISDIR" ? "Is a directory"
245
- : cause?.code === "EACCES" || cause?.code === "EPERM" ? "Permission denied"
246
- : cause?.code === "EROFS" ? "Read-only file system"
247
- : cause?.code === "ENOSPC" ? "No space left on device"
248
- : "Input/output error";
249
- const script = path.join(deps.root, WORK_MESH_LIVE_REBIND_LIBRARY_ASSET);
250
- return { code: 1, stdout: "", stderr: `${script}: line 34: ${error.target}: ${message}\n` };
251
- }
252
- }
253
- export async function runWorkMeshLiveRebindFast(args, _stdin, cwd, root) {
254
- const chosenRoot = process.env.HQ_ROOT || root || cwd;
255
- const result = runWorkMeshLiveRebind(args, defaultDeps(chosenRoot, cwd, process.env));
256
- if (result.stdout)
257
- process.stdout.write(result.stdout);
258
- if (result.stderr)
259
- process.stderr.write(result.stderr);
260
- return result.code;
261
- }
262
- //# sourceMappingURL=core-work-mesh-live-rebind-native.js.map
@@ -1,5 +0,0 @@
1
- /** Explicit 401/403 codes returned by hq-pro's work-session registration path. */
2
- export declare const WORK_SESSION_DENIAL_CODES: readonly ["AUTH_REQUIRED", "AGENT_IDENTITY_UNVERIFIED", "IMPERSONATION_FORBIDDEN", "NO_PERSON_ENTITY", "INVALID_COMPANY", "WORK_REGISTRY_DISABLED"];
3
- export type WorkSessionDenialCode = (typeof WORK_SESSION_DENIAL_CODES)[number];
4
- export declare function isWorkSessionDenialCode(value: unknown): value is WorkSessionDenialCode;
5
- //# sourceMappingURL=denial-codes.d.ts.map
@@ -1,14 +0,0 @@
1
- /** Explicit 401/403 codes returned by hq-pro's work-session registration path. */
2
- export const WORK_SESSION_DENIAL_CODES = [
3
- "AUTH_REQUIRED",
4
- "AGENT_IDENTITY_UNVERIFIED",
5
- "IMPERSONATION_FORBIDDEN",
6
- "NO_PERSON_ENTITY",
7
- "INVALID_COMPANY",
8
- "WORK_REGISTRY_DISABLED",
9
- ];
10
- export function isWorkSessionDenialCode(value) {
11
- return typeof value === "string" &&
12
- WORK_SESSION_DENIAL_CODES.includes(value);
13
- }
14
- //# sourceMappingURL=denial-codes.js.map
@@ -1,4 +0,0 @@
1
- /** Return shell-compatible 0/1/2: true, false, or malformed. */
2
- export declare function evaluateTrigger(expr: string, facts?: string): number;
3
- export declare function checkTriggerExpressions(stdin: string): string;
4
- //# sourceMappingURL=core-eval-trigger.d.ts.map