@indigoai-us/hq-cli 5.345.105 → 5.345.107
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.
- package/CHANGELOG.md +23 -0
- package/assets/scaffold/core/scripts/hq-task.mjs +259 -0
- package/assets/scaffold/core/scripts/hq-task.sh +31 -0
- package/assets/scaffold/core/scripts/pipeline-worker-table.sh +285 -0
- package/dist/command-catalog.generated.d.ts +135 -5
- package/dist/command-catalog.generated.js +161 -5
- package/dist/commands/auth.js +42 -0
- package/dist/commands/core-hq-task-fast.d.ts +4 -0
- package/dist/commands/core-hq-task-fast.js +11 -0
- package/dist/commands/core-hq-task-native.d.ts +20 -0
- package/dist/commands/core-hq-task-native.js +275 -0
- package/dist/commands/core-native-bucket-c-flag.d.ts +3 -0
- package/dist/commands/core-native-bucket-c-flag.js +6 -0
- package/dist/commands/core-native-family-flag.d.ts +0 -2
- package/dist/commands/core-native-family-flag.js +0 -4
- package/dist/commands/core-native-pipeline-flag.d.ts +3 -0
- package/dist/commands/core-native-pipeline-flag.js +6 -0
- package/dist/commands/core-ontology-native.js +24 -30
- package/dist/commands/core-pipeline-workers-command.d.ts +3 -0
- package/dist/commands/core-pipeline-workers-command.js +37 -0
- package/dist/commands/core-pipeline-workers-native.d.ts +13 -0
- package/dist/commands/core-pipeline-workers-native.js +361 -0
- package/dist/commands/core.js +12 -10
- package/dist/commands/lanes.js +32 -7
- package/dist/commands/logout.d.ts +6 -1
- package/dist/commands/logout.js +18 -2
- package/dist/commands/outposts.d.ts +5 -0
- package/dist/commands/outposts.js +5 -0
- package/dist/fast-scaffold.d.ts +14 -1
- package/dist/fast-scaffold.js +149 -5
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +56937 -64550
- package/dist/hq-cloud-sync-runner/package.json +1 -1
- package/dist/index.js +15 -1
- package/dist/lib/daemon/remote-control-pools.d.ts +2 -2
- package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
- package/dist/lib/flag-registry-worker-source.generated.js +1 -1
- package/dist/lib/lanes/reconcile.js +4 -0
- package/dist/lib/lanes/remote-control-lane.d.ts +33 -0
- package/dist/lib/lanes/remote-control-lane.js +276 -0
- package/dist/lib/lanes/spawn.d.ts +5 -0
- package/dist/lib/lanes/spawn.js +65 -14
- package/dist/lib/lanes/store.js +7 -0
- package/dist/lib/lanes/types.d.ts +2 -0
- package/dist/lib/lanes/types.js +1 -1
- package/dist/lib/lanes/watcher.js +8 -1
- package/dist/utils/cognito-config.d.ts +5 -0
- package/dist/utils/cognito-config.js +14 -0
- package/dist/utils/cognito-revoke.d.ts +33 -0
- package/dist/utils/cognito-revoke.js +42 -0
- package/dist/utils/cognito-session.d.ts +12 -4
- package/dist/utils/cognito-session.js +42 -9
- package/dist/utils/token-keychain.d.ts +96 -0
- package/dist/utils/token-keychain.js +218 -0
- package/package.json +2 -2
- package/assets/scaffold/core/scripts/ontology-audience-grant.sh +0 -81
- package/assets/scaffold/core/scripts/ontology-brief.mjs +0 -93
- package/assets/scaffold/core/scripts/ontology-candidate.sh +0 -100
- package/assets/scaffold/core/scripts/ontology-garden.mjs +0 -327
- package/assets/scaffold/core/scripts/ontology-source-worklist.sh +0 -226
- package/assets/scaffold/core/scripts/source-yaml-validate.sh +0 -36
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
export const HQ_TASK_ASSET = "core/scripts/hq-task.sh";
|
|
5
|
+
const USAGE = `hq-task — the global task list on an HQ board
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
hq-task.sh list [--company <slug>] [--all] [--goal <objective-id>]
|
|
9
|
+
hq-task.sh add [--company <slug>] --title "<short title>"
|
|
10
|
+
[--description "<context>"]
|
|
11
|
+
[--criteria "<one done-criterion>"]...
|
|
12
|
+
[--contact "Name <email>|role"]...
|
|
13
|
+
[--goal <objective-id>] [--priority <1-3>]
|
|
14
|
+
hq-task.sh done [--company <slug>] --id T-002
|
|
15
|
+
hq-task.sh block [--company <slug>] --id T-002 --reason "<what is in the way>"
|
|
16
|
+
hq-task.sh reopen [--company <slug>] --id T-002
|
|
17
|
+
hq-task.sh goals [--company <slug>]
|
|
18
|
+
|
|
19
|
+
Default board: personal/board.json. With --company: companies/<slug>/board.json.`;
|
|
20
|
+
function isUnsafeCompanySlug(root, company) {
|
|
21
|
+
if (company.length === 0 || path.isAbsolute(company) || path.win32.isAbsolute(company) ||
|
|
22
|
+
company.includes("..") || /[\\/]/.test(company))
|
|
23
|
+
return true;
|
|
24
|
+
const companiesRoot = path.resolve(root, "companies");
|
|
25
|
+
const target = path.resolve(companiesRoot, company, "board.json");
|
|
26
|
+
const relative = path.relative(companiesRoot, target);
|
|
27
|
+
return relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative);
|
|
28
|
+
}
|
|
29
|
+
function nodeOnPath(env, platform = process.platform) {
|
|
30
|
+
const searchPath = env.PATH || "";
|
|
31
|
+
const names = platform === "win32" ? ["node.exe", "node.cmd", "node.bat"] : ["node"];
|
|
32
|
+
for (const directory of searchPath.split(path.delimiter)) {
|
|
33
|
+
if (!directory)
|
|
34
|
+
continue;
|
|
35
|
+
for (const name of names) {
|
|
36
|
+
try {
|
|
37
|
+
const candidate = path.join(directory, name);
|
|
38
|
+
fs.accessSync(candidate, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
|
|
39
|
+
if (fs.statSync(candidate).isFile())
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// command -v ignores PATH entries that do not contain an executable.
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
function fail(message, code = 1) {
|
|
50
|
+
return { code, stdout: "", stderr: `${message}\n` };
|
|
51
|
+
}
|
|
52
|
+
function parseArgs(argv) {
|
|
53
|
+
const repeatable = new Set(["criteria", "contact"]);
|
|
54
|
+
const bare = new Set(["all"]);
|
|
55
|
+
const flags = {};
|
|
56
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
57
|
+
const token = argv[i];
|
|
58
|
+
if (!token.startsWith("--"))
|
|
59
|
+
return { error: fail(`Unexpected argument: ${token}\n\n${USAGE}`) };
|
|
60
|
+
const key = token.slice(2);
|
|
61
|
+
if (bare.has(key)) {
|
|
62
|
+
flags[key] = true;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const value = argv[i + 1];
|
|
66
|
+
if (value === undefined || value.startsWith("--"))
|
|
67
|
+
return { error: fail(`Flag --${key} needs a value.\n\n${USAGE}`) };
|
|
68
|
+
i += 1;
|
|
69
|
+
if (repeatable.has(key)) {
|
|
70
|
+
const previous = flags[key];
|
|
71
|
+
flags[key] = [...(Array.isArray(previous) ? previous : []), value];
|
|
72
|
+
}
|
|
73
|
+
else
|
|
74
|
+
flags[key] = value;
|
|
75
|
+
}
|
|
76
|
+
return { flags };
|
|
77
|
+
}
|
|
78
|
+
function text(flags, key) {
|
|
79
|
+
const value = flags[key];
|
|
80
|
+
return typeof value === "string" ? value : undefined;
|
|
81
|
+
}
|
|
82
|
+
function boardPath(root, flags) {
|
|
83
|
+
const company = text(flags, "company");
|
|
84
|
+
return company ? path.join(root, "companies", company, "board.json") : path.join(root, "personal", "board.json");
|
|
85
|
+
}
|
|
86
|
+
function load(root, flags) {
|
|
87
|
+
const file = boardPath(root, flags);
|
|
88
|
+
if (!fs.existsSync(file))
|
|
89
|
+
return { error: fail(`No board at ${file}`) };
|
|
90
|
+
try {
|
|
91
|
+
const board = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
92
|
+
board.tasks ||= [];
|
|
93
|
+
return { file, board };
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
return { error: fail(error.message) };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function save(file, board, io = fs) {
|
|
100
|
+
board.updated_at = new Date().toISOString().replace(/\.\d+Z$/, "Z");
|
|
101
|
+
const temporary = path.join(path.dirname(file), `.${path.basename(file)}.${process.pid}.${randomUUID()}.tmp`);
|
|
102
|
+
try {
|
|
103
|
+
const mode = io.statSync(file).mode & 0o7777;
|
|
104
|
+
io.writeFileSync(temporary, `${JSON.stringify(board, null, 2)}\n`, { flag: "wx", mode });
|
|
105
|
+
io.chmodSync(temporary, mode);
|
|
106
|
+
io.renameSync(temporary, file);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
try {
|
|
110
|
+
if (io.existsSync(temporary))
|
|
111
|
+
io.unlinkSync(temporary);
|
|
112
|
+
}
|
|
113
|
+
catch { /* preserve the write or rename error */ }
|
|
114
|
+
return fail(error.message);
|
|
115
|
+
}
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
export const __hqTaskTest = { save };
|
|
119
|
+
function parseContact(raw) {
|
|
120
|
+
let rest = raw;
|
|
121
|
+
let role;
|
|
122
|
+
const bar = rest.indexOf("|");
|
|
123
|
+
if (bar !== -1) {
|
|
124
|
+
role = rest.slice(bar + 1).trim();
|
|
125
|
+
rest = rest.slice(0, bar).trim();
|
|
126
|
+
}
|
|
127
|
+
let email;
|
|
128
|
+
const angle = /<([^>]+)>/.exec(rest);
|
|
129
|
+
if (angle) {
|
|
130
|
+
email = angle[1].trim();
|
|
131
|
+
rest = rest.slice(0, angle.index).trim();
|
|
132
|
+
}
|
|
133
|
+
const contact = { name: rest };
|
|
134
|
+
if (email)
|
|
135
|
+
contact.email = email;
|
|
136
|
+
if (role)
|
|
137
|
+
contact.role = role;
|
|
138
|
+
return contact;
|
|
139
|
+
}
|
|
140
|
+
function goalTitle(board, id) {
|
|
141
|
+
const objective = (board.objectives || []).find((row) => row.id === id);
|
|
142
|
+
return objective ? String(objective.title) : null;
|
|
143
|
+
}
|
|
144
|
+
function runList(root, flags) {
|
|
145
|
+
const loaded = load(root, flags);
|
|
146
|
+
if (loaded.error)
|
|
147
|
+
return loaded.error;
|
|
148
|
+
const board = loaded.board;
|
|
149
|
+
let tasks = board.tasks.filter((task) => flags.all === true || task.status !== "done");
|
|
150
|
+
const goal = text(flags, "goal");
|
|
151
|
+
if (goal)
|
|
152
|
+
tasks = tasks.filter((task) => task.objective_id === goal);
|
|
153
|
+
if (tasks.length === 0)
|
|
154
|
+
return { code: 0, stdout: "No open tasks.\n", stderr: "" };
|
|
155
|
+
const output = [`${text(flags, "company") || "personal"} — ${flags.all ? "all tasks" : "open tasks"} (${tasks.length})\n\n`];
|
|
156
|
+
tasks.sort((a, b) => (a.priority ?? 99) - (b.priority ?? 99) || String(a.id).localeCompare(String(b.id)));
|
|
157
|
+
for (const task of tasks) {
|
|
158
|
+
const mark = task.status === "blocked" ? "!" : task.status === "done" ? "x" : " ";
|
|
159
|
+
output.push(` [${mark}] ${task.id} ${task.title || ""}\n`);
|
|
160
|
+
const goalName = task.objective_id && goalTitle(board, task.objective_id);
|
|
161
|
+
if (goalName)
|
|
162
|
+
output.push(` goal: ${goalName}\n`);
|
|
163
|
+
if (task.status === "blocked" && task.blockedReason)
|
|
164
|
+
output.push(` blocked: ${task.blockedReason}\n`);
|
|
165
|
+
for (const contact of task.contacts || []) {
|
|
166
|
+
const trail = [contact.email, contact.phone].filter(Boolean).join(" · ");
|
|
167
|
+
output.push(` ${contact.name}${trail ? ` — ${trail}` : ""}\n`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return { code: 0, stdout: output.join(""), stderr: "" };
|
|
171
|
+
}
|
|
172
|
+
function runGoals(root, flags) {
|
|
173
|
+
const loaded = load(root, flags);
|
|
174
|
+
if (loaded.error)
|
|
175
|
+
return loaded.error;
|
|
176
|
+
const board = loaded.board;
|
|
177
|
+
const objectives = board.objectives || [];
|
|
178
|
+
if (objectives.length === 0)
|
|
179
|
+
return { code: 0, stdout: "No goals on that board.\n", stderr: "" };
|
|
180
|
+
const output = [];
|
|
181
|
+
for (const objective of objectives) {
|
|
182
|
+
const count = board.tasks.filter((task) => task.objective_id === objective.id && task.status !== "done").length;
|
|
183
|
+
output.push(`${objective.id} ${objective.title} (${count} open task${count === 1 ? "" : "s"})\n`);
|
|
184
|
+
for (const kr of objective.key_results || [])
|
|
185
|
+
output.push(` ${kr.title} — ${kr.current ?? 0}/${kr.target} ${kr.unit || ""}\n`);
|
|
186
|
+
}
|
|
187
|
+
return { code: 0, stdout: output.join(""), stderr: "" };
|
|
188
|
+
}
|
|
189
|
+
export function runHqTask(args, root, env = process.env) {
|
|
190
|
+
if (!nodeOnPath(env))
|
|
191
|
+
return fail("hq-task: node is required but was not found on PATH.");
|
|
192
|
+
const [command, ...rest] = args;
|
|
193
|
+
if (!command || command === "--help" || command === "-h") {
|
|
194
|
+
return { code: command ? 0 : 1, stdout: `${USAGE}\n`, stderr: "" };
|
|
195
|
+
}
|
|
196
|
+
if (!(command in { list: 1, goals: 1, add: 1, done: 1, reopen: 1, block: 1 }))
|
|
197
|
+
return fail(`Unknown command: ${command}\n\n${USAGE}`);
|
|
198
|
+
const parsed = parseArgs(rest);
|
|
199
|
+
if (parsed.error)
|
|
200
|
+
return parsed.error;
|
|
201
|
+
const flags = parsed.flags;
|
|
202
|
+
const company = text(flags, "company");
|
|
203
|
+
if (company !== undefined && isUnsafeCompanySlug(root, company))
|
|
204
|
+
return fail(`Invalid company slug: ${company}`);
|
|
205
|
+
if (command === "list")
|
|
206
|
+
return runList(root, flags);
|
|
207
|
+
if (command === "goals")
|
|
208
|
+
return runGoals(root, flags);
|
|
209
|
+
if (command === "add") {
|
|
210
|
+
const title = text(flags, "title");
|
|
211
|
+
if (!title)
|
|
212
|
+
return fail(`add needs --title.\n\n${USAGE}`);
|
|
213
|
+
const priority = text(flags, "priority");
|
|
214
|
+
if (flags.priority !== undefined && !/^[1-3]$/.test(priority ?? "")) {
|
|
215
|
+
return fail("--priority must be an integer from 1 to 3");
|
|
216
|
+
}
|
|
217
|
+
const loaded = load(root, flags);
|
|
218
|
+
if (loaded.error)
|
|
219
|
+
return loaded.error;
|
|
220
|
+
const board = loaded.board, file = loaded.file;
|
|
221
|
+
const goal = text(flags, "goal");
|
|
222
|
+
if (goal && !goalTitle(board, goal))
|
|
223
|
+
return fail(`No goal ${goal} on that board. Run 'hq-task.sh goals' to list them.`);
|
|
224
|
+
let highest = 0;
|
|
225
|
+
for (const task of board.tasks) {
|
|
226
|
+
const match = /^T-(\d+)$/.exec(task.id || "");
|
|
227
|
+
if (match)
|
|
228
|
+
highest = Math.max(highest, Number(match[1]));
|
|
229
|
+
}
|
|
230
|
+
const criteria = flags.criteria;
|
|
231
|
+
const contacts = flags.contact;
|
|
232
|
+
const task = {
|
|
233
|
+
id: `T-${String(highest + 1).padStart(3, "0")}`,
|
|
234
|
+
title,
|
|
235
|
+
description: text(flags, "description") || title,
|
|
236
|
+
status: "open",
|
|
237
|
+
priority: priority ? Number(priority) : 2,
|
|
238
|
+
objective_id: goal || null,
|
|
239
|
+
criteria: criteria || [`${title} — completed.`],
|
|
240
|
+
contacts: (contacts || []).map(parseContact),
|
|
241
|
+
createdAt: new Date().toISOString().slice(0, 10),
|
|
242
|
+
};
|
|
243
|
+
board.tasks.push(task);
|
|
244
|
+
const error = save(file, board);
|
|
245
|
+
if (error)
|
|
246
|
+
return error;
|
|
247
|
+
return { code: 0, stdout: `Added ${task.id}: ${task.title}\n`, stderr: "" };
|
|
248
|
+
}
|
|
249
|
+
if (command === "block" && !text(flags, "reason"))
|
|
250
|
+
return fail(`block needs --reason.\n\n${USAGE}`);
|
|
251
|
+
const loaded = load(root, flags);
|
|
252
|
+
if (loaded.error)
|
|
253
|
+
return loaded.error;
|
|
254
|
+
const id = text(flags, "id");
|
|
255
|
+
const nextStatus = command === "done" ? "done" : command === "block" ? "blocked" : "open";
|
|
256
|
+
if (!id)
|
|
257
|
+
return fail(`${command} needs --id.\n\n${USAGE}`);
|
|
258
|
+
const task = loaded.board.tasks.find((row) => row.id === id);
|
|
259
|
+
if (!task)
|
|
260
|
+
return fail(`No task ${id} on that board.`);
|
|
261
|
+
task.status = nextStatus;
|
|
262
|
+
if (nextStatus === "done")
|
|
263
|
+
task.closedAt = new Date().toISOString().slice(0, 10);
|
|
264
|
+
else
|
|
265
|
+
delete task.closedAt;
|
|
266
|
+
if (nextStatus === "blocked")
|
|
267
|
+
task.blockedReason = text(flags, "reason") || "";
|
|
268
|
+
else
|
|
269
|
+
delete task.blockedReason;
|
|
270
|
+
const error = save(loaded.file, loaded.board);
|
|
271
|
+
if (error)
|
|
272
|
+
return error;
|
|
273
|
+
return { code: 0, stdout: `${task.id} → ${nextStatus}: ${task.title}\n`, stderr: "" };
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=core-hq-task-native.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { coreNativeFamilyEnabled } from "./core-native-family-flag.js";
|
|
2
|
+
export const CORE_NATIVE_BUCKET_C_FLAG = "core-native-bucket-c";
|
|
3
|
+
export function coreNativeBucketCEnabled() {
|
|
4
|
+
return coreNativeFamilyEnabled(CORE_NATIVE_BUCKET_C_FLAG);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=core-native-bucket-c-flag.js.map
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/** Shared fail-safe readers for shipped native core families. */
|
|
2
2
|
export declare function coreNativeFamilyEnabled(flagKey: string): Promise<boolean>;
|
|
3
3
|
export declare const CORE_NATIVE_DELEGATE_FLAG = "core-native-delegate";
|
|
4
|
-
export declare const CORE_NATIVE_ONTOLOGY_FLAG = "core-native-ontology";
|
|
5
4
|
export declare function coreNativeDelegateEnabled(): Promise<boolean>;
|
|
6
|
-
export declare function coreNativeOntologyEnabled(): Promise<boolean>;
|
|
7
5
|
//# sourceMappingURL=core-native-family-flag.d.ts.map
|
|
@@ -11,11 +11,7 @@ export async function coreNativeFamilyEnabled(flagKey) {
|
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
export const CORE_NATIVE_DELEGATE_FLAG = "core-native-delegate";
|
|
14
|
-
export const CORE_NATIVE_ONTOLOGY_FLAG = "core-native-ontology";
|
|
15
14
|
export function coreNativeDelegateEnabled() {
|
|
16
15
|
return coreNativeFamilyEnabled(CORE_NATIVE_DELEGATE_FLAG);
|
|
17
16
|
}
|
|
18
|
-
export function coreNativeOntologyEnabled() {
|
|
19
|
-
return coreNativeFamilyEnabled(CORE_NATIVE_ONTOLOGY_FLAG);
|
|
20
|
-
}
|
|
21
17
|
//# sourceMappingURL=core-native-family-flag.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { coreNativeFamilyEnabled } from "./core-native-family-flag.js";
|
|
2
|
+
export const CORE_NATIVE_PIPELINE_FLAG = "core-native-pipeline";
|
|
3
|
+
export function coreNativePipelineEnabled() {
|
|
4
|
+
return coreNativeFamilyEnabled(CORE_NATIVE_PIPELINE_FLAG);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=core-native-pipeline-flag.js.map
|
|
@@ -4,15 +4,16 @@ import { spawnSync } from "node:child_process";
|
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import * as path from "node:path";
|
|
6
6
|
import { resolveWindowsExecutable } from "../lib/bot/runtime/windows.js";
|
|
7
|
-
import {
|
|
8
|
-
import { resolveBundledAsset } from "../utils/hq-roots.js";
|
|
7
|
+
import { BUNDLED_ASSET_DIR, packageRoot } from "../utils/hq-roots.js";
|
|
9
8
|
import { planResolvedCommandSpawn } from "../utils/windows-spawn.js";
|
|
10
9
|
import { describeCoreCommand } from "./core-command-catalog.js";
|
|
11
10
|
import { runKnowledgePrefs } from "./core-knowledge-prefs.js";
|
|
12
|
-
const FLAG = "core-native-ontology";
|
|
13
11
|
const ASSET = "core/scripts/";
|
|
14
12
|
const SIGNAL_TYPES = ["decision", "commitment", "risk", "question", "action_item", "key_point", "participant_contribution", "summary"];
|
|
15
13
|
const CANDIDATE_SIGNAL_TYPES = ["action_item", "commitment", "decision", "risk", "question", "key_point", "participant_contribution", "summary"];
|
|
14
|
+
function legacyAssetPath(name) {
|
|
15
|
+
return path.join(packageRoot(), BUNDLED_ASSET_DIR, ASSET, name);
|
|
16
|
+
}
|
|
16
17
|
const ENTITY_TYPES = ["person", "project", "company", "concept"];
|
|
17
18
|
const ok = (stdout = "") => ({ code: 0, stdout, stderr: "" });
|
|
18
19
|
const err = (code, stderr, stdout = "") => ({ code, stdout, stderr });
|
|
@@ -179,7 +180,7 @@ export function candidateCommand(args, root) {
|
|
|
179
180
|
"--company": 50, "--kind": 51, "--type": 52, "--audience": 53,
|
|
180
181
|
"--source-ref": 54, "--body": 55, "--body-file": 56, "--created-by": 57,
|
|
181
182
|
};
|
|
182
|
-
return err(1, `${
|
|
183
|
+
return err(1, `${legacyAssetPath("ontology-candidate.sh")}: line ${lines[name]}: $2: unbound variable\n`);
|
|
183
184
|
}
|
|
184
185
|
values[aliases[name]] = args[++index];
|
|
185
186
|
}
|
|
@@ -677,7 +678,7 @@ export function audienceGrant(args, root) {
|
|
|
677
678
|
const key = args[index];
|
|
678
679
|
if (key === "--company") {
|
|
679
680
|
if (index + 1 >= args.length)
|
|
680
|
-
return err(1, `${
|
|
681
|
+
return err(1, `${legacyAssetPath("ontology-audience-grant.sh")}: line 26: $2: unbound variable\n`);
|
|
681
682
|
company = args[++index];
|
|
682
683
|
}
|
|
683
684
|
else if (key === "--dry-run")
|
|
@@ -707,9 +708,14 @@ export function audienceGrant(args, root) {
|
|
|
707
708
|
if (!cloud)
|
|
708
709
|
return ok("local-only, no grants\n");
|
|
709
710
|
const membersRun = runHq(["members", "--company", company, "list"]);
|
|
710
|
-
const memberLines = membersRun.stdout.split("\n")
|
|
711
|
-
const members =
|
|
712
|
-
|
|
711
|
+
const memberLines = membersRun.stdout.split("\n");
|
|
712
|
+
const members = new Set();
|
|
713
|
+
for (let index = 1; index < memberLines.length; index += 1) {
|
|
714
|
+
const member = memberLines[index].trim().split(/[\t ]+/)[0]?.toLowerCase() ?? "";
|
|
715
|
+
if (member)
|
|
716
|
+
members.add(member);
|
|
717
|
+
}
|
|
718
|
+
if (members.size === 0)
|
|
713
719
|
return err(3, `could not list members of ${company}\n`);
|
|
714
720
|
let granted = 0;
|
|
715
721
|
let skipped = 0;
|
|
@@ -774,7 +780,7 @@ export function audienceGrant(args, root) {
|
|
|
774
780
|
}
|
|
775
781
|
}
|
|
776
782
|
for (const who of principals) {
|
|
777
|
-
if (!/^prs_|^agt_/.test(who) && !members.
|
|
783
|
+
if (!/^prs_|^agt_/.test(who) && !members.has(who)) {
|
|
778
784
|
stderr += `skip ${who} (not a member of ${company})\n`;
|
|
779
785
|
skipped += 1;
|
|
780
786
|
continue;
|
|
@@ -913,7 +919,7 @@ export function worklistCommand(args, root) {
|
|
|
913
919
|
if (key === "--company" || key === "--channel" || key === "--limit" || key === "--mark-done") {
|
|
914
920
|
if (index + 1 >= args.length) {
|
|
915
921
|
const line = key === "--mark-done" ? 30 : 29;
|
|
916
|
-
return err(1, `${
|
|
922
|
+
return err(1, `${legacyAssetPath("ontology-source-worklist.sh")}: line ${line}: $2: unbound variable\n`);
|
|
917
923
|
}
|
|
918
924
|
const value = args[++index];
|
|
919
925
|
if (key === "--company")
|
|
@@ -1069,7 +1075,7 @@ export function worklistCommand(args, root) {
|
|
|
1069
1075
|
if (/^[+-]?\d+$/.test(limit) && count >= Number(limit))
|
|
1070
1076
|
break;
|
|
1071
1077
|
if (!/^[+-]?\d+$/.test(limit)) {
|
|
1072
|
-
process.stderr.write(`${
|
|
1078
|
+
process.stderr.write(`${legacyAssetPath("ontology-source-worklist.sh")}: line 186: [: ${limit}: integer expression expected\n`);
|
|
1073
1079
|
}
|
|
1074
1080
|
count += 1;
|
|
1075
1081
|
const file = path.join(directory, name);
|
|
@@ -1128,12 +1134,12 @@ export function worklistCommand(args, root) {
|
|
|
1128
1134
|
}
|
|
1129
1135
|
export function registerCoreOntologyNativeCommands(ontology, rootFor) {
|
|
1130
1136
|
const entries = [
|
|
1131
|
-
{ name: "audience-grant", summary: "Grant scoped ontology audiences and verify each grant",
|
|
1132
|
-
{ name: "brief", summary: "Render the local ontology company brief",
|
|
1133
|
-
{ name: "candidate", summary: "Write a deterministic ontology candidate",
|
|
1134
|
-
{ name: "garden", summary: "Promote local ontology candidates",
|
|
1135
|
-
{ name: "source-worklist", summary: "List unprocessed source items and their audience",
|
|
1136
|
-
{ name: "source-yaml-validate", summary: "Validate a source.yaml file",
|
|
1137
|
+
{ name: "audience-grant", summary: "Grant scoped ontology audiences and verify each grant", root: "live", run: audienceGrant },
|
|
1138
|
+
{ name: "brief", summary: "Render the local ontology company brief", root: "live", run: (args, root) => briefCommand(args, root) },
|
|
1139
|
+
{ name: "candidate", summary: "Write a deterministic ontology candidate", root: "live", run: candidateCommand },
|
|
1140
|
+
{ name: "garden", summary: "Promote local ontology candidates", root: "live", run: (args, root) => gardenCommand(args, root) },
|
|
1141
|
+
{ name: "source-worklist", summary: "List unprocessed source items and their audience", root: "live", run: worklistCommand },
|
|
1142
|
+
{ name: "source-yaml-validate", summary: "Validate a source.yaml file", root: "cwd", run: (args) => sourceYamlValidate(args[0]) },
|
|
1137
1143
|
];
|
|
1138
1144
|
const rawArgv = process.argv.slice(2);
|
|
1139
1145
|
const coreIndex = rawArgv.indexOf("core");
|
|
@@ -1170,21 +1176,9 @@ export function registerCoreOntologyNativeCommands(ontology, rootFor) {
|
|
|
1170
1176
|
const forwarded = commandIndex >= 0 ? argv.slice(commandIndex + 1)
|
|
1171
1177
|
: commandContext.args.length > 0 ? commandContext.args : args;
|
|
1172
1178
|
const liveRoot = entry.root === "live" ? rootFor() : process.cwd();
|
|
1173
|
-
const { coreNativeOntologyEnabled } = await import("./core-native-family-flag.js");
|
|
1174
|
-
if (!await coreNativeOntologyEnabled()) {
|
|
1175
|
-
const result = runBundledScript({
|
|
1176
|
-
asset: `${ASSET}${entry.asset}`,
|
|
1177
|
-
args: forwarded,
|
|
1178
|
-
cwd: process.cwd(),
|
|
1179
|
-
...(entry.root === "live" ? { hqRoot: liveRoot } : {}),
|
|
1180
|
-
});
|
|
1181
|
-
if (result.code !== 0)
|
|
1182
|
-
process.exitCode = result.code;
|
|
1183
|
-
return;
|
|
1184
|
-
}
|
|
1185
1179
|
writeResult(entry.run(forwarded, entry.root === "live" ? liveRoot : process.cwd()));
|
|
1186
1180
|
});
|
|
1187
|
-
describeCoreCommand(command, { execution: "native",
|
|
1181
|
+
describeCoreCommand(command, { execution: "native", root: entry.root });
|
|
1188
1182
|
}
|
|
1189
1183
|
}
|
|
1190
1184
|
//# sourceMappingURL=core-ontology-native.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { resolveLiveRoot } from "../utils/hq-roots.js";
|
|
2
|
+
import { runBundledScript } from "../utils/run-bundled-script.js";
|
|
3
|
+
import { describeCoreCommand } from "./core-command-catalog.js";
|
|
4
|
+
import { coreNativePipelineEnabled } from "./core-native-pipeline-flag.js";
|
|
5
|
+
import { PIPELINE_WORKER_TABLE_ASSET, pipelineWorkerFallbackArgs, runPipelineWorkerTable, writePipelineWorkerTableResult } from "./core-pipeline-workers-native.js";
|
|
6
|
+
export function registerCorePipelineWorkerTableCommand(core) {
|
|
7
|
+
const pipeline = core.command("pipeline").description("Pipeline orchestration helpers");
|
|
8
|
+
const command = pipeline.command("workers")
|
|
9
|
+
.description("Propose or render the pipeline worker engine table")
|
|
10
|
+
.helpOption(false)
|
|
11
|
+
.allowUnknownOption()
|
|
12
|
+
.allowExcessArguments(true)
|
|
13
|
+
.argument("[args...]")
|
|
14
|
+
.action(async (args, _options, current) => {
|
|
15
|
+
const argv = current.args.length > 0 ? current.args : args;
|
|
16
|
+
const groupHqRoot = core.opts().hqRoot;
|
|
17
|
+
if (!await coreNativePipelineEnabled()) {
|
|
18
|
+
const root = resolveLiveRoot({ hqRoot: groupHqRoot });
|
|
19
|
+
const result = runBundledScript({
|
|
20
|
+
asset: PIPELINE_WORKER_TABLE_ASSET,
|
|
21
|
+
args: pipelineWorkerFallbackArgs(argv, root, process.env),
|
|
22
|
+
cwd: process.cwd(),
|
|
23
|
+
hqRoot: root,
|
|
24
|
+
});
|
|
25
|
+
if (result.code !== 0)
|
|
26
|
+
process.exit(result.code);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const root = resolveLiveRoot({ hqRoot: groupHqRoot });
|
|
30
|
+
const result = runPipelineWorkerTable(argv, root);
|
|
31
|
+
const code = writePipelineWorkerTableResult(result);
|
|
32
|
+
if (code !== 0)
|
|
33
|
+
process.exit(code);
|
|
34
|
+
});
|
|
35
|
+
describeCoreCommand(command, { execution: "native", asset: PIPELINE_WORKER_TABLE_ASSET, root: "live" });
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=core-pipeline-workers-command.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const PIPELINE_WORKER_TABLE_ASSET = "core/scripts/pipeline-worker-table.sh";
|
|
2
|
+
export declare const CORE_NATIVE_PIPELINE_FLAG = "core-native-pipeline";
|
|
3
|
+
type Result = {
|
|
4
|
+
code: number;
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function pipelineWorkerRoots(argsRoots: string[], root: string, env: NodeJS.ProcessEnv): string[];
|
|
9
|
+
export declare function pipelineWorkerFallbackArgs(args: string[], root: string, env: NodeJS.ProcessEnv): string[];
|
|
10
|
+
export declare function runPipelineWorkerTable(args: string[], root: string, env?: NodeJS.ProcessEnv): Result;
|
|
11
|
+
export declare function writePipelineWorkerTableResult(result: Result): number;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=core-pipeline-workers-native.d.ts.map
|