@indigoai-us/hq-cli 5.282.0 → 5.283.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.
- package/CHANGELOG.md +22 -0
- package/assets/scaffold/.claude/hooks/validate-policy-frontmatter.sh +485 -0
- package/assets/scaffold/core/scripts/eval-trigger.sh +193 -0
- package/assets/scaffold/core/scripts/policy-age-report.sh +156 -0
- package/assets/scaffold/core/scripts/policy-retire.sh +199 -0
- package/assets/scaffold/core/scripts/read-policy-frontmatter.sh +32 -0
- package/dist/command-catalog.generated.d.ts +67 -0
- package/dist/command-catalog.generated.js +83 -0
- package/dist/commands/core-knowledge-prefs.d.ts +10 -0
- package/dist/commands/core-knowledge-prefs.js +125 -0
- package/dist/commands/core-native-policy-flag.d.ts +9 -0
- package/dist/commands/core-native-policy-flag.js +12 -0
- package/dist/commands/core-ontology-native.d.ts +0 -1
- package/dist/commands/core-ontology-native.js +2 -30
- package/dist/commands/core-ontology.d.ts +4 -0
- package/dist/commands/core-ontology.js +8 -3
- package/dist/commands/core-policy-frontmatter.d.ts +8 -0
- package/dist/commands/core-policy-frontmatter.js +52 -0
- package/dist/commands/core-policy.d.ts +15 -0
- package/dist/commands/core-policy.js +982 -0
- package/dist/commands/core.js +14 -1
- package/dist/commands/lanes-shared.d.ts +4 -1
- package/dist/commands/lanes-shared.js +2 -1
- package/dist/commands/lanes.d.ts +8 -0
- package/dist/commands/lanes.js +294 -86
- package/dist/fast-lanes-list-route.d.ts +8 -0
- package/dist/fast-lanes-list-route.js +30 -0
- package/dist/fast-lanes-list.d.ts +3 -0
- package/dist/fast-lanes-list.js +252 -0
- package/dist/fast-scaffold.d.ts +5 -0
- package/dist/fast-scaffold.js +10 -0
- package/dist/index.js +10 -1
- package/dist/lib/checkpoint-ontology/merge-copies.d.ts +24 -1
- package/dist/lib/checkpoint-ontology/merge-copies.js +70 -1
- package/dist/lib/lanes/flag-keys.d.ts +3 -0
- package/dist/lib/lanes/flag-keys.js +3 -0
- package/dist/lib/lanes/index.d.ts +1 -1
- package/dist/lib/lanes/index.js +1 -1
- package/dist/lib/lanes/outpost-dispatch.d.ts +1 -1
- package/dist/lib/lanes/outpost-dispatch.js +4 -2
- package/dist/lib/lanes/outpost-hire-cache.d.ts +3 -0
- package/dist/lib/lanes/outpost-hire-cache.js +11 -3
- package/dist/lib/lanes/outpost-snapshot-cache.d.ts +26 -0
- package/dist/lib/lanes/outpost-snapshot-cache.js +215 -0
- package/dist/lib/lanes/store.d.ts +4 -0
- package/dist/lib/lanes/store.js +39 -0
- package/dist/lib/policy-validator.d.ts +2 -0
- package/dist/lib/policy-validator.js +136 -0
- package/dist/native-fast-route.d.ts +2 -0
- package/dist/native-fast-route.js +6 -2
- package/dist/utils/contribution-table.d.ts +1 -1
- package/package.json +1 -1
|
@@ -5179,6 +5179,9 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
5179
5179
|
}, {
|
|
5180
5180
|
readonly flags: "--delete";
|
|
5181
5181
|
readonly description: "delete fully merged copies from the vault by exact key (after sync pushed the merge)";
|
|
5182
|
+
}, {
|
|
5183
|
+
readonly flags: "--variants";
|
|
5184
|
+
readonly description: "merge two-file duplicate groups whose names differ only in case, spacing or punctuation (checkpoint.ontology.merge-variants)";
|
|
5182
5185
|
}, {
|
|
5183
5186
|
readonly flags: "--limit <n>";
|
|
5184
5187
|
readonly description: "handle at most this many copies";
|
|
@@ -5376,6 +5379,67 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
5376
5379
|
readonly options: readonly [];
|
|
5377
5380
|
readonly subcommands: readonly [];
|
|
5378
5381
|
}];
|
|
5382
|
+
}, {
|
|
5383
|
+
readonly name: "knowledge-prefs";
|
|
5384
|
+
readonly description: "Resolve a company knowledge-store preference";
|
|
5385
|
+
readonly aliases: readonly [];
|
|
5386
|
+
readonly hidden: false;
|
|
5387
|
+
readonly usage: "[args...]";
|
|
5388
|
+
readonly arguments: readonly [{
|
|
5389
|
+
readonly name: "args";
|
|
5390
|
+
readonly required: false;
|
|
5391
|
+
readonly variadic: true;
|
|
5392
|
+
}];
|
|
5393
|
+
readonly options: readonly [];
|
|
5394
|
+
readonly subcommands: readonly [];
|
|
5395
|
+
}, {
|
|
5396
|
+
readonly name: "policy";
|
|
5397
|
+
readonly description: "Policy maintenance commands";
|
|
5398
|
+
readonly aliases: readonly [];
|
|
5399
|
+
readonly hidden: false;
|
|
5400
|
+
readonly usage: "[options] [command]";
|
|
5401
|
+
readonly arguments: readonly [];
|
|
5402
|
+
readonly options: readonly [];
|
|
5403
|
+
readonly subcommands: readonly [{
|
|
5404
|
+
readonly name: "age-report";
|
|
5405
|
+
readonly description: "Report policy usage and retirement candidates";
|
|
5406
|
+
readonly aliases: readonly [];
|
|
5407
|
+
readonly hidden: false;
|
|
5408
|
+
readonly usage: "[args...]";
|
|
5409
|
+
readonly arguments: readonly [{
|
|
5410
|
+
readonly name: "args";
|
|
5411
|
+
readonly required: false;
|
|
5412
|
+
readonly variadic: true;
|
|
5413
|
+
}];
|
|
5414
|
+
readonly options: readonly [];
|
|
5415
|
+
readonly subcommands: readonly [];
|
|
5416
|
+
}, {
|
|
5417
|
+
readonly name: "retire";
|
|
5418
|
+
readonly description: "Retire or restore a policy";
|
|
5419
|
+
readonly aliases: readonly [];
|
|
5420
|
+
readonly hidden: false;
|
|
5421
|
+
readonly usage: "[args...]";
|
|
5422
|
+
readonly arguments: readonly [{
|
|
5423
|
+
readonly name: "args";
|
|
5424
|
+
readonly required: false;
|
|
5425
|
+
readonly variadic: true;
|
|
5426
|
+
}];
|
|
5427
|
+
readonly options: readonly [];
|
|
5428
|
+
readonly subcommands: readonly [];
|
|
5429
|
+
}, {
|
|
5430
|
+
readonly name: "frontmatter";
|
|
5431
|
+
readonly description: "Extract policy frontmatter";
|
|
5432
|
+
readonly aliases: readonly [];
|
|
5433
|
+
readonly hidden: false;
|
|
5434
|
+
readonly usage: "[args...]";
|
|
5435
|
+
readonly arguments: readonly [{
|
|
5436
|
+
readonly name: "args";
|
|
5437
|
+
readonly required: false;
|
|
5438
|
+
readonly variadic: true;
|
|
5439
|
+
}];
|
|
5440
|
+
readonly options: readonly [];
|
|
5441
|
+
readonly subcommands: readonly [];
|
|
5442
|
+
}];
|
|
5379
5443
|
}, {
|
|
5380
5444
|
readonly name: "generate-workers-registry";
|
|
5381
5445
|
readonly description: "Regenerate the derived workers registry";
|
|
@@ -7692,6 +7756,9 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
7692
7756
|
}, {
|
|
7693
7757
|
readonly flags: "--active";
|
|
7694
7758
|
readonly description: "Include only lanes that are not terminal";
|
|
7759
|
+
}, {
|
|
7760
|
+
readonly flags: "--fresh";
|
|
7761
|
+
readonly description: "Wait for fresh remote owner summaries";
|
|
7695
7762
|
}, {
|
|
7696
7763
|
readonly flags: "--json";
|
|
7697
7764
|
readonly description: "Emit JSON on stdout (default)";
|
|
@@ -6696,6 +6696,10 @@ export const COMMAND_CATALOG = [
|
|
|
6696
6696
|
"flags": "--delete",
|
|
6697
6697
|
"description": "delete fully merged copies from the vault by exact key (after sync pushed the merge)"
|
|
6698
6698
|
},
|
|
6699
|
+
{
|
|
6700
|
+
"flags": "--variants",
|
|
6701
|
+
"description": "merge two-file duplicate groups whose names differ only in case, spacing or punctuation (checkpoint.ontology.merge-variants)"
|
|
6702
|
+
},
|
|
6699
6703
|
{
|
|
6700
6704
|
"flags": "--limit <n>",
|
|
6701
6705
|
"description": "handle at most this many copies"
|
|
@@ -6942,6 +6946,81 @@ export const COMMAND_CATALOG = [
|
|
|
6942
6946
|
}
|
|
6943
6947
|
]
|
|
6944
6948
|
},
|
|
6949
|
+
{
|
|
6950
|
+
"name": "knowledge-prefs",
|
|
6951
|
+
"description": "Resolve a company knowledge-store preference",
|
|
6952
|
+
"aliases": [],
|
|
6953
|
+
"hidden": false,
|
|
6954
|
+
"usage": "[args...]",
|
|
6955
|
+
"arguments": [
|
|
6956
|
+
{
|
|
6957
|
+
"name": "args",
|
|
6958
|
+
"required": false,
|
|
6959
|
+
"variadic": true
|
|
6960
|
+
}
|
|
6961
|
+
],
|
|
6962
|
+
"options": [],
|
|
6963
|
+
"subcommands": []
|
|
6964
|
+
},
|
|
6965
|
+
{
|
|
6966
|
+
"name": "policy",
|
|
6967
|
+
"description": "Policy maintenance commands",
|
|
6968
|
+
"aliases": [],
|
|
6969
|
+
"hidden": false,
|
|
6970
|
+
"usage": "[options] [command]",
|
|
6971
|
+
"arguments": [],
|
|
6972
|
+
"options": [],
|
|
6973
|
+
"subcommands": [
|
|
6974
|
+
{
|
|
6975
|
+
"name": "age-report",
|
|
6976
|
+
"description": "Report policy usage and retirement candidates",
|
|
6977
|
+
"aliases": [],
|
|
6978
|
+
"hidden": false,
|
|
6979
|
+
"usage": "[args...]",
|
|
6980
|
+
"arguments": [
|
|
6981
|
+
{
|
|
6982
|
+
"name": "args",
|
|
6983
|
+
"required": false,
|
|
6984
|
+
"variadic": true
|
|
6985
|
+
}
|
|
6986
|
+
],
|
|
6987
|
+
"options": [],
|
|
6988
|
+
"subcommands": []
|
|
6989
|
+
},
|
|
6990
|
+
{
|
|
6991
|
+
"name": "retire",
|
|
6992
|
+
"description": "Retire or restore a policy",
|
|
6993
|
+
"aliases": [],
|
|
6994
|
+
"hidden": false,
|
|
6995
|
+
"usage": "[args...]",
|
|
6996
|
+
"arguments": [
|
|
6997
|
+
{
|
|
6998
|
+
"name": "args",
|
|
6999
|
+
"required": false,
|
|
7000
|
+
"variadic": true
|
|
7001
|
+
}
|
|
7002
|
+
],
|
|
7003
|
+
"options": [],
|
|
7004
|
+
"subcommands": []
|
|
7005
|
+
},
|
|
7006
|
+
{
|
|
7007
|
+
"name": "frontmatter",
|
|
7008
|
+
"description": "Extract policy frontmatter",
|
|
7009
|
+
"aliases": [],
|
|
7010
|
+
"hidden": false,
|
|
7011
|
+
"usage": "[args...]",
|
|
7012
|
+
"arguments": [
|
|
7013
|
+
{
|
|
7014
|
+
"name": "args",
|
|
7015
|
+
"required": false,
|
|
7016
|
+
"variadic": true
|
|
7017
|
+
}
|
|
7018
|
+
],
|
|
7019
|
+
"options": [],
|
|
7020
|
+
"subcommands": []
|
|
7021
|
+
}
|
|
7022
|
+
]
|
|
7023
|
+
},
|
|
6945
7024
|
{
|
|
6946
7025
|
"name": "generate-workers-registry",
|
|
6947
7026
|
"description": "Regenerate the derived workers registry",
|
|
@@ -9935,6 +10014,10 @@ export const COMMAND_CATALOG = [
|
|
|
9935
10014
|
"flags": "--active",
|
|
9936
10015
|
"description": "Include only lanes that are not terminal"
|
|
9937
10016
|
},
|
|
10017
|
+
{
|
|
10018
|
+
"flags": "--fresh",
|
|
10019
|
+
"description": "Wait for fresh remote owner summaries"
|
|
10020
|
+
},
|
|
9938
10021
|
{
|
|
9939
10022
|
"flags": "--json",
|
|
9940
10023
|
"description": "Emit JSON on stdout (default)"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export declare const KNOWLEDGE_PREFS_ASSET = "core/scripts/knowledge-prefs.sh";
|
|
3
|
+
export type CoreCommandResult = {
|
|
4
|
+
code: number;
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function runKnowledgePrefs(args: readonly string[], root: string): CoreCommandResult;
|
|
9
|
+
export declare function registerCoreKnowledgePrefsCommand(core: Command): void;
|
|
10
|
+
//# sourceMappingURL=core-knowledge-prefs.d.ts.map
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native port of core/scripts/knowledge-prefs.sh.
|
|
3
|
+
*
|
|
4
|
+
* The shell command reads only HQ_ROOT (the CLI resolves and supplies that
|
|
5
|
+
* source root) and scans top-level scalar lines without parsing YAML.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { resolveLiveRoot } from '../utils/hq-roots.js';
|
|
10
|
+
import { runBundledScript } from '../utils/run-bundled-script.js';
|
|
11
|
+
import { describeCoreCommand } from './core-command-catalog.js';
|
|
12
|
+
import { coreNativePolicyEnabled } from './core-native-policy-flag.js';
|
|
13
|
+
export const KNOWLEDGE_PREFS_ASSET = 'core/scripts/knowledge-prefs.sh';
|
|
14
|
+
const DEFAULTS = {
|
|
15
|
+
signals_enabled: 'true',
|
|
16
|
+
ontology_enabled: 'true',
|
|
17
|
+
signals_capture: 'false',
|
|
18
|
+
ontology_capture: 'false',
|
|
19
|
+
meeting_notes_source: 'hq-native',
|
|
20
|
+
notetaker: 'recall',
|
|
21
|
+
};
|
|
22
|
+
const USAGE = 'usage: knowledge-prefs.sh get <company> <field>\n';
|
|
23
|
+
function readField(filePath, field) {
|
|
24
|
+
let body;
|
|
25
|
+
try {
|
|
26
|
+
body = fs.readFileSync(filePath, 'utf8');
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
const code = error.code;
|
|
30
|
+
if (code === 'ENOENT' || code === 'ENOTDIR' || code === 'EACCES' || code === 'ELOOP')
|
|
31
|
+
return undefined;
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
for (const line of body.split(/\n/)) {
|
|
35
|
+
if (!line.startsWith(field + ':'))
|
|
36
|
+
continue;
|
|
37
|
+
let value = line.slice(field.length + 1).replace(/^[\s]+/, '');
|
|
38
|
+
value = value.replace(/[\s]+#.*$/, '');
|
|
39
|
+
value = value.replace(/^["']|["']$/g, '');
|
|
40
|
+
if (value.length > 0)
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
export function runKnowledgePrefs(args, root) {
|
|
46
|
+
if (args[0] !== 'get' || !args[1] || !args[2]) {
|
|
47
|
+
return { code: 2, stdout: '', stderr: USAGE };
|
|
48
|
+
}
|
|
49
|
+
const company = args[1];
|
|
50
|
+
const field = args[2];
|
|
51
|
+
const fallback = DEFAULTS[field];
|
|
52
|
+
if (fallback === undefined) {
|
|
53
|
+
return {
|
|
54
|
+
code: 2,
|
|
55
|
+
stdout: '',
|
|
56
|
+
stderr: "knowledge-prefs: unknown field '" + field + "'\n",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
let companyExists = false;
|
|
60
|
+
try {
|
|
61
|
+
companyExists = fs.statSync(path.join(root, 'companies', company)).isDirectory();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
// `test -d` returns false for missing, unreadable, or non-directory paths.
|
|
65
|
+
const code = error.code;
|
|
66
|
+
if (code !== 'ENOENT' && code !== 'ENOTDIR' && code !== 'EACCES' && code !== 'ELOOP') {
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!companyExists) {
|
|
71
|
+
return {
|
|
72
|
+
code: 2,
|
|
73
|
+
stdout: '',
|
|
74
|
+
stderr: "knowledge-prefs: no company '" + company + "'\n",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const companyValue = readField(path.join(root, 'companies', company, 'settings', 'knowledge', 'preferences.yaml'), field);
|
|
78
|
+
const personalValue = companyValue === undefined
|
|
79
|
+
? readField(path.join(root, 'personal', 'settings', 'knowledge-preferences.yaml'), field)
|
|
80
|
+
: undefined;
|
|
81
|
+
return {
|
|
82
|
+
code: 0,
|
|
83
|
+
stdout: (companyValue ?? personalValue ?? fallback) + '\n',
|
|
84
|
+
stderr: '',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function registerCoreKnowledgePrefsCommand(core) {
|
|
88
|
+
const command = core
|
|
89
|
+
.command('knowledge-prefs')
|
|
90
|
+
.description('Resolve a company knowledge-store preference')
|
|
91
|
+
.allowUnknownOption()
|
|
92
|
+
.allowExcessArguments()
|
|
93
|
+
.helpOption(false)
|
|
94
|
+
.argument('[args...]', 'arguments passed through to the script')
|
|
95
|
+
.action(async (args = [], _options, cmd) => {
|
|
96
|
+
const operands = cmd.args.length > 0 ? cmd.args : args;
|
|
97
|
+
const hqRoot = resolveLiveRoot({
|
|
98
|
+
hqRoot: core.opts().hqRoot,
|
|
99
|
+
});
|
|
100
|
+
if (!await coreNativePolicyEnabled()) {
|
|
101
|
+
const result = runBundledScript({
|
|
102
|
+
asset: KNOWLEDGE_PREFS_ASSET,
|
|
103
|
+
args: operands,
|
|
104
|
+
cwd: hqRoot,
|
|
105
|
+
hqRoot,
|
|
106
|
+
});
|
|
107
|
+
if (result.code !== 0)
|
|
108
|
+
process.exitCode = result.code;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const result = runKnowledgePrefs(operands, hqRoot);
|
|
112
|
+
if (result.stdout)
|
|
113
|
+
process.stdout.write(result.stdout);
|
|
114
|
+
if (result.stderr)
|
|
115
|
+
process.stderr.write(result.stderr);
|
|
116
|
+
if (result.code !== 0)
|
|
117
|
+
process.exitCode = result.code;
|
|
118
|
+
});
|
|
119
|
+
describeCoreCommand(command, {
|
|
120
|
+
execution: 'native',
|
|
121
|
+
asset: KNOWLEDGE_PREFS_ASSET,
|
|
122
|
+
root: 'live',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=core-knowledge-prefs.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default-off rollout gate shared by the native knowledge and policy commands.
|
|
3
|
+
*
|
|
4
|
+
* The flag reader is loaded only after command selection. Its process gate reads
|
|
5
|
+
* the in-memory hq-flags snapshot synchronously and falls back to false.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CORE_NATIVE_POLICY_FLAG = "core-native-policy";
|
|
8
|
+
export declare function coreNativePolicyEnabled(): Promise<boolean>;
|
|
9
|
+
//# sourceMappingURL=core-native-policy-flag.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default-off rollout gate shared by the native knowledge and policy commands.
|
|
3
|
+
*
|
|
4
|
+
* The flag reader is loaded only after command selection. Its process gate reads
|
|
5
|
+
* the in-memory hq-flags snapshot synchronously and falls back to false.
|
|
6
|
+
*/
|
|
7
|
+
export const CORE_NATIVE_POLICY_FLAG = 'core-native-policy';
|
|
8
|
+
export async function coreNativePolicyEnabled() {
|
|
9
|
+
const { resolveProcessFlagGate } = await import('../lib/flag-registry.js');
|
|
10
|
+
return resolveProcessFlagGate(CORE_NATIVE_POLICY_FLAG, { fallback: false }, () => false);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=core-native-policy-flag.js.map
|
|
@@ -5,7 +5,6 @@ export interface ScriptResult {
|
|
|
5
5
|
stdout: string;
|
|
6
6
|
stderr: string;
|
|
7
7
|
}
|
|
8
|
-
export declare function preferenceValue(root: string, company: string, field: string): ScriptResult;
|
|
9
8
|
export declare function sourceYamlValidate(file: string | undefined): ScriptResult;
|
|
10
9
|
export declare function candidateCommand(args: string[], root: string): ScriptResult;
|
|
11
10
|
export declare function briefCommand(args: string[], defaultRoot: string): ScriptResult;
|
|
@@ -7,19 +7,12 @@ import { resolveProcessFlagGate } from "../lib/flag-registry.js";
|
|
|
7
7
|
import { runBundledScript } from "../utils/run-bundled-script.js";
|
|
8
8
|
import { resolveBundledAsset } from "../utils/hq-roots.js";
|
|
9
9
|
import { describeCoreCommand } from "./core-command-catalog.js";
|
|
10
|
+
import { runKnowledgePrefs } from "./core-knowledge-prefs.js";
|
|
10
11
|
const FLAG = "core-native-ontology";
|
|
11
12
|
const ASSET = "core/scripts/";
|
|
12
13
|
const SIGNAL_TYPES = ["decision", "commitment", "risk", "question", "action_item", "key_point", "participant_contribution", "summary"];
|
|
13
14
|
const CANDIDATE_SIGNAL_TYPES = ["action_item", "commitment", "decision", "risk", "question", "key_point", "participant_contribution", "summary"];
|
|
14
15
|
const ENTITY_TYPES = ["person", "project", "company", "concept"];
|
|
15
|
-
const DEFAULT_PREFS = {
|
|
16
|
-
signals_enabled: "true",
|
|
17
|
-
ontology_enabled: "true",
|
|
18
|
-
signals_capture: "false",
|
|
19
|
-
ontology_capture: "false",
|
|
20
|
-
meeting_notes_source: "hq-native",
|
|
21
|
-
notetaker: "recall",
|
|
22
|
-
};
|
|
23
16
|
const ok = (stdout = "") => ({ code: 0, stdout, stderr: "" });
|
|
24
17
|
const err = (code, stderr, stdout = "") => ({ code, stdout, stderr });
|
|
25
18
|
const shellSubstitution = (value) => value.replace(/\n+$/, "");
|
|
@@ -64,24 +57,6 @@ function awkField(file, field, stripComment) {
|
|
|
64
57
|
value = value.replace(/[\t\n\v\f\r ]+#.*$/, "");
|
|
65
58
|
return value.replace(/^["']|["']$/g, "");
|
|
66
59
|
}
|
|
67
|
-
export function preferenceValue(root, company, field) {
|
|
68
|
-
if (!(field in DEFAULT_PREFS))
|
|
69
|
-
return err(2, `knowledge-prefs: unknown field '${field}'\n`);
|
|
70
|
-
const companyDir = path.join(root, "companies", company);
|
|
71
|
-
if (!fs.existsSync(companyDir) || !fs.statSync(companyDir).isDirectory()) {
|
|
72
|
-
return err(2, `knowledge-prefs: no company '${company}'\n`);
|
|
73
|
-
}
|
|
74
|
-
const files = [
|
|
75
|
-
path.join(companyDir, "settings", "knowledge", "preferences.yaml"),
|
|
76
|
-
path.join(root, "personal", "settings", "knowledge-preferences.yaml"),
|
|
77
|
-
];
|
|
78
|
-
for (const file of files) {
|
|
79
|
-
const value = awkField(file, field, true);
|
|
80
|
-
if (value.length > 0)
|
|
81
|
-
return ok(`${value}\n`);
|
|
82
|
-
}
|
|
83
|
-
return ok(`${DEFAULT_PREFS[field]}\n`);
|
|
84
|
-
}
|
|
85
60
|
function normalizeAudience(value) {
|
|
86
61
|
const entries = value.split(",")
|
|
87
62
|
.map((item) => item.replace(/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g, ""))
|
|
@@ -98,9 +73,6 @@ function audienceKey(value) {
|
|
|
98
73
|
const key = createHash("sha256").update(normalizeAudience(audience)).digest("hex").slice(0, 16);
|
|
99
74
|
return ok(`${key}\n`);
|
|
100
75
|
}
|
|
101
|
-
function readKnowledgePreference(root, company, field) {
|
|
102
|
-
return preferenceValue(root, company, field);
|
|
103
|
-
}
|
|
104
76
|
export function sourceYamlValidate(file) {
|
|
105
77
|
if (!file)
|
|
106
78
|
return err(2, "usage: source-yaml-validate.sh <source.yaml>\n");
|
|
@@ -205,7 +177,7 @@ export function candidateCommand(args, root) {
|
|
|
205
177
|
const allowed = kind === "signal" ? CANDIDATE_SIGNAL_TYPES : ENTITY_TYPES;
|
|
206
178
|
if (!allowed.includes(type))
|
|
207
179
|
return err(2, `ontology-candidate: unknown ${kind} type '${type}' (allowed: ${allowed.join(" ")})\n`);
|
|
208
|
-
const enabled =
|
|
180
|
+
const enabled = runKnowledgePrefs(["get", company, preference], root);
|
|
209
181
|
if (enabled.code !== 0)
|
|
210
182
|
return err(2, enabled.stderr);
|
|
211
183
|
if (shellSubstitution(enabled.stdout) !== "true")
|
|
@@ -30,6 +30,7 @@ export declare function runOntologyDuplicates(hqRoot: string, slug: string | und
|
|
|
30
30
|
export interface MergeCopiesCommandOptions {
|
|
31
31
|
apply?: boolean;
|
|
32
32
|
delete?: boolean;
|
|
33
|
+
variants?: boolean;
|
|
33
34
|
limit?: number;
|
|
34
35
|
json?: boolean;
|
|
35
36
|
}
|
|
@@ -38,6 +39,9 @@ export interface MergeCopiesCommandOptions {
|
|
|
38
39
|
* original (`--apply`), then delete merged copies from the vault
|
|
39
40
|
* (`--delete`). Without either it only reports. Gated by
|
|
40
41
|
* `checkpoint.ontology.merge-copies` and `checkpoint.ontology.multi-writer`.
|
|
42
|
+
* With `--variants`, merges two-file duplicate groups whose names differ only
|
|
43
|
+
* in case, spacing or punctuation instead, gated by
|
|
44
|
+
* `checkpoint.ontology.merge-variants`.
|
|
41
45
|
*/
|
|
42
46
|
export declare function runOntologyMergeCopies(hqRoot: string, slug: string | undefined, options: MergeCopiesCommandOptions, deps?: OntologyCommandDeps): Promise<string>;
|
|
43
47
|
export declare function registerCoreOntologyCommand(core: Command): void;
|
|
@@ -17,7 +17,7 @@ import { applyOntologyRun, ApplyError } from "../lib/checkpoint-ontology/apply.j
|
|
|
17
17
|
import { resolveOntologyCompany, WriteBoundsError } from "../lib/checkpoint-ontology/company.js";
|
|
18
18
|
import { findDuplicateGroups, summarizeMergeBack, } from "../lib/checkpoint-ontology/multi-writer.js";
|
|
19
19
|
import { buildEntityIndex } from "../lib/checkpoint-ontology/tree.js";
|
|
20
|
-
import { MERGE_COPIES_FLAG, mergeCopies, } from "../lib/checkpoint-ontology/merge-copies.js";
|
|
20
|
+
import { MERGE_COPIES_FLAG, MERGE_VARIANTS_FLAG, mergeCopies, } from "../lib/checkpoint-ontology/merge-copies.js";
|
|
21
21
|
import { callDeleteEndpoint } from "./files.js";
|
|
22
22
|
import { resolveVaultCredential } from "../utils/resolve-vault-credential.js";
|
|
23
23
|
import { registerCoreOntologyNativeCommands } from "./core-ontology-native.js";
|
|
@@ -145,7 +145,7 @@ async function companyVaultDeleter(companyUid) {
|
|
|
145
145
|
function mergeCopiesSummary(report) {
|
|
146
146
|
const held = report.plans.filter((plan) => plan.held).length;
|
|
147
147
|
const lines = [
|
|
148
|
-
`ontology merge-copies (${report.mode.replace("_", " ")}) in ${report.company}: ${report.plans.length} of ${report.copies_found} copies, ${held} held, ${report.skipped.length} skipped`,
|
|
148
|
+
`ontology merge-copies (${report.mode.replace("_", " ")}) in ${report.company} (${report.pair_kind}): ${report.plans.length} of ${report.copies_found} copies, ${held} held, ${report.skipped.length} skipped`,
|
|
149
149
|
` merged ${report.merged.length}, relinked ${report.relinked.length}, deleted ${report.deleted.length}, not ready ${report.not_ready.length}, errors ${report.errors.length}`,
|
|
150
150
|
` duplicate groups ${report.duplicate_groups_before} -> ${report.duplicate_groups_after}; broken entity links ${report.broken_links_before} -> ${report.broken_links_after}`,
|
|
151
151
|
];
|
|
@@ -160,6 +160,9 @@ function mergeCopiesSummary(report) {
|
|
|
160
160
|
* original (`--apply`), then delete merged copies from the vault
|
|
161
161
|
* (`--delete`). Without either it only reports. Gated by
|
|
162
162
|
* `checkpoint.ontology.merge-copies` and `checkpoint.ontology.multi-writer`.
|
|
163
|
+
* With `--variants`, merges two-file duplicate groups whose names differ only
|
|
164
|
+
* in case, spacing or punctuation instead, gated by
|
|
165
|
+
* `checkpoint.ontology.merge-variants`.
|
|
163
166
|
*/
|
|
164
167
|
export async function runOntologyMergeCopies(hqRoot, slug, options, deps = {}) {
|
|
165
168
|
if (options.apply && options.delete) {
|
|
@@ -173,7 +176,7 @@ export async function runOntologyMergeCopies(hqRoot, slug, options, deps = {}) {
|
|
|
173
176
|
throw new OntologyUsageError(`ontology: company rejected: ${resolution.reason}`);
|
|
174
177
|
const company = resolution.company;
|
|
175
178
|
const readFlag = deps.readFlag ?? registryFlagReader;
|
|
176
|
-
for (const flag of [MERGE_COPIES_FLAG, MULTI_WRITER_FLAG]) {
|
|
179
|
+
for (const flag of [options.variants ? MERGE_VARIANTS_FLAG : MERGE_COPIES_FLAG, MULTI_WRITER_FLAG]) {
|
|
177
180
|
if (!(await readFlag(flag, company))) {
|
|
178
181
|
return options.json ? JSON.stringify({ company: company.slug, skipped: `${flag} off` }) : `ontology merge-copies: skipped (${flag} is off)`;
|
|
179
182
|
}
|
|
@@ -190,6 +193,7 @@ export async function runOntologyMergeCopies(hqRoot, slug, options, deps = {}) {
|
|
|
190
193
|
company,
|
|
191
194
|
mode,
|
|
192
195
|
now: deps.now?.() ?? new Date(),
|
|
196
|
+
...(options.variants ? { pairKind: "variants" } : {}),
|
|
193
197
|
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
194
198
|
...(deleteVaultKey ? { deleteVaultKey } : {}),
|
|
195
199
|
});
|
|
@@ -242,6 +246,7 @@ export function registerCoreOntologyCommand(core) {
|
|
|
242
246
|
.requiredOption("--company <slug>", "company to change")
|
|
243
247
|
.option("--apply", "merge each copy into its original and re-point links (writes entity files)")
|
|
244
248
|
.option("--delete", "delete fully merged copies from the vault by exact key (after sync pushed the merge)")
|
|
249
|
+
.option("--variants", "merge two-file duplicate groups whose names differ only in case, spacing or punctuation (checkpoint.ontology.merge-variants)")
|
|
245
250
|
.option("--limit <n>", "handle at most this many copies", (value) => Number(value))
|
|
246
251
|
.option("--json", "print JSON")
|
|
247
252
|
.option("--hq-root <path>", "HQ installation to operate on")
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type FrontmatterResult = {
|
|
2
|
+
code: number;
|
|
3
|
+
stdout: Buffer;
|
|
4
|
+
stderr: Buffer;
|
|
5
|
+
};
|
|
6
|
+
/** Byte-preserving port of core/scripts/read-policy-frontmatter.sh. */
|
|
7
|
+
export declare function runPolicyFrontmatter(args: readonly string[], cwd: string): FrontmatterResult;
|
|
8
|
+
//# sourceMappingURL=core-policy-frontmatter.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
const USAGE = Buffer.from('USAGE: read-policy-frontmatter.sh <policy-file>\n');
|
|
4
|
+
/** Byte-preserving port of core/scripts/read-policy-frontmatter.sh. */
|
|
5
|
+
export function runPolicyFrontmatter(args, cwd) {
|
|
6
|
+
const first = args[0];
|
|
7
|
+
if (first === undefined)
|
|
8
|
+
return { code: 1, stdout: Buffer.alloc(0), stderr: USAGE };
|
|
9
|
+
const filePath = path.isAbsolute(first) ? first : path.resolve(cwd, first);
|
|
10
|
+
let source;
|
|
11
|
+
try {
|
|
12
|
+
fs.accessSync(filePath, fs.constants.R_OK);
|
|
13
|
+
source = fs.readFileSync(filePath);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const code = error.code;
|
|
17
|
+
if (code === 'EISDIR') {
|
|
18
|
+
return {
|
|
19
|
+
code: 0,
|
|
20
|
+
stdout: Buffer.alloc(0),
|
|
21
|
+
stderr: Buffer.from(`awk: warning: command line argument \`${first}' is a directory: skipped\n`),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (code === 'ENOENT' || code === 'ENOTDIR' || code === 'EACCES' || code === 'ELOOP') {
|
|
25
|
+
return {
|
|
26
|
+
code: 1,
|
|
27
|
+
stdout: Buffer.alloc(0),
|
|
28
|
+
stderr: Buffer.from(`ERROR: File not readable: ${first}\n`),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
const output = [];
|
|
34
|
+
let markers = 0;
|
|
35
|
+
let start = 0;
|
|
36
|
+
while (start < source.length) {
|
|
37
|
+
const end = source.indexOf(0x0a, start);
|
|
38
|
+
const lineEnd = end < 0 ? source.length : end;
|
|
39
|
+
const line = source.subarray(start, lineEnd);
|
|
40
|
+
if (line.length === 3 && line[0] === 0x2d && line[1] === 0x2d && line[2] === 0x2d) {
|
|
41
|
+
markers += 1;
|
|
42
|
+
}
|
|
43
|
+
else if (markers === 1) {
|
|
44
|
+
output.push(line, Buffer.from('\n'));
|
|
45
|
+
}
|
|
46
|
+
if (end < 0)
|
|
47
|
+
break;
|
|
48
|
+
start = end + 1;
|
|
49
|
+
}
|
|
50
|
+
return { code: 0, stdout: Buffer.concat(output), stderr: Buffer.alloc(0) };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=core-policy-frontmatter.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { type FrontmatterResult } from './core-policy-frontmatter.js';
|
|
3
|
+
export declare const POLICY_AGE_REPORT_ASSET = "core/scripts/policy-age-report.sh";
|
|
4
|
+
export declare const POLICY_RETIRE_ASSET = "core/scripts/policy-retire.sh";
|
|
5
|
+
export declare const POLICY_FRONTMATTER_ASSET = "core/scripts/read-policy-frontmatter.sh";
|
|
6
|
+
export type CorePolicyResult = {
|
|
7
|
+
code: number;
|
|
8
|
+
stdout: Buffer;
|
|
9
|
+
stderr: Buffer;
|
|
10
|
+
};
|
|
11
|
+
export declare function runPolicyAgeReport(args: readonly string[], root: string, env?: NodeJS.ProcessEnv, nowEpoch?: number): CorePolicyResult;
|
|
12
|
+
export declare function runPolicyFrontmatter(args: readonly string[], cwd: string): FrontmatterResult;
|
|
13
|
+
export declare function runPolicyRetire(args: readonly string[], root: string, cwd: string, env?: NodeJS.ProcessEnv, now?: Date): CorePolicyResult;
|
|
14
|
+
export declare function registerCorePolicyCommand(core: Command): void;
|
|
15
|
+
//# sourceMappingURL=core-policy.d.ts.map
|