blun-king-cli 9.1.563 → 9.1.565

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 (85) hide show
  1. package/agent-spine-plugin/.claude-plugin/marketplace.json +20 -20
  2. package/agent-spine-plugin/.claude-plugin/plugin.json +14 -14
  3. package/agent-spine-plugin/.codex-plugin/plugin.json +34 -34
  4. package/agent-spine-plugin/.mcp.json +8 -8
  5. package/agent-spine-plugin/CONTRIBUTING.md +52 -0
  6. package/agent-spine-plugin/LICENSE +186 -186
  7. package/agent-spine-plugin/README.md +394 -0
  8. package/agent-spine-plugin/SECURITY.md +47 -0
  9. package/agent-spine-plugin/assets/agentspine-banner.svg +32 -32
  10. package/agent-spine-plugin/bin/agentspine-mcp.js +4 -4
  11. package/agent-spine-plugin/bin/agentspine.js +7 -7
  12. package/agent-spine-plugin/blun.plugin.json +33 -33
  13. package/agent-spine-plugin/hooks/codex.json +47 -47
  14. package/agent-spine-plugin/hooks/hooks.json +106 -106
  15. package/agent-spine-plugin/hooks/version.json +5 -5
  16. package/agent-spine-plugin/package.json +69 -69
  17. package/agent-spine-plugin/scripts/check-hosts.js +199 -199
  18. package/agent-spine-plugin/skill/SKILL.md +76 -76
  19. package/agent-spine-plugin/skills/agent-spine/SKILL.md +85 -85
  20. package/agent-spine-plugin/src/cli.js +1488 -1442
  21. package/agent-spine-plugin/src/hook.js +886 -812
  22. package/agent-spine-plugin/src/index.js +93 -93
  23. package/agent-spine-plugin/src/lib/acceptance.js +333 -333
  24. package/agent-spine-plugin/src/lib/attention.js +755 -755
  25. package/agent-spine-plugin/src/lib/audit.js +351 -342
  26. package/agent-spine-plugin/src/lib/authentication.js +515 -515
  27. package/agent-spine-plugin/src/lib/briefing.js +317 -317
  28. package/agent-spine-plugin/src/lib/catalog.js +167 -167
  29. package/agent-spine-plugin/src/lib/channel-runtime.js +665 -665
  30. package/agent-spine-plugin/src/lib/context.js +154 -154
  31. package/agent-spine-plugin/src/lib/continuity.js +338 -338
  32. package/agent-spine-plugin/src/lib/coordination.js +577 -577
  33. package/agent-spine-plugin/src/lib/documents.js +217 -217
  34. package/agent-spine-plugin/src/lib/feed-transport.js +499 -499
  35. package/agent-spine-plugin/src/lib/filesystem-retry.js +32 -32
  36. package/agent-spine-plugin/src/lib/gateway-runtime.js +1119 -760
  37. package/agent-spine-plugin/src/lib/graph.js +337 -337
  38. package/agent-spine-plugin/src/lib/hook-audit.js +29 -0
  39. package/agent-spine-plugin/src/lib/https-transport.js +392 -392
  40. package/agent-spine-plugin/src/lib/indexed-memory-offline.js +40 -40
  41. package/agent-spine-plugin/src/lib/indexed-memory.js +281 -281
  42. package/agent-spine-plugin/src/lib/learning.js +6923 -6466
  43. package/agent-spine-plugin/src/lib/object-transport.js +206 -206
  44. package/agent-spine-plugin/src/lib/owned-file-lock.js +143 -143
  45. package/agent-spine-plugin/src/lib/paths.js +109 -109
  46. package/agent-spine-plugin/src/lib/peer-transport.js +283 -283
  47. package/agent-spine-plugin/src/lib/persona-runtime.js +581 -581
  48. package/agent-spine-plugin/src/lib/preflight.js +702 -702
  49. package/agent-spine-plugin/src/lib/runtime.js +13 -13
  50. package/agent-spine-plugin/src/lib/selfstarter.js +892 -819
  51. package/agent-spine-plugin/src/lib/sharing.js +969 -969
  52. package/agent-spine-plugin/src/lib/source-roots.js +529 -482
  53. package/agent-spine-plugin/src/lib/sqlite-transport.js +501 -501
  54. package/agent-spine-plugin/src/lib/telegram-adapter.js +119 -119
  55. package/agent-spine-plugin/src/lib/voice-runtime.js +39 -39
  56. package/agent-spine-plugin/src/mcp.js +597 -572
  57. package/agent-spine-plugin/src/version.js +1 -1
  58. package/agent-spine-plugin/src/worker.js +202 -195
  59. package/bin/active-steer-priority-policy.cjs +24 -0
  60. package/bin/launcher-runtime.js +8 -1
  61. package/bin/mnemo-tool-agent-policy.cjs +22 -0
  62. package/bin/thinking-activity-status-policy.cjs +132 -0
  63. package/bin/thinking-only-guard.cjs +75 -0
  64. package/bin/tool-call-loop-policy.cjs +53 -0
  65. package/bin/turn-thinking-policy.cjs +25 -1
  66. package/blun.mjs +554 -64
  67. package/package.json +4 -1
  68. package/standard-skills/translate-native/LICENSE +21 -21
  69. package/standard-skills/translate-native/references/evaluation-protocol.md +95 -95
  70. package/standard-skills/translate-native/references/native-orthography.md +79 -79
  71. package/standard-skills/translate-native/references/native-translation-standard.md +94 -94
  72. package/standard-skills/translate-native/references/structured-content.md +72 -72
  73. package/standard-skills/translate-native/references/translationese-review.md +77 -77
  74. package/standard-skills/translate-native/scripts/blun_language_guard.py +697 -697
  75. package/standard-skills/translate-native/scripts/check_diacritics.py +353 -353
  76. package/standard-skills/translate-native/scripts/guard_service_client.py +264 -264
  77. package/standard-skills/translate-native/scripts/language_gateway.py +62 -62
  78. package/standard-skills/translate-native/scripts/language_quality.py +377 -377
  79. package/standard-skills/translate-native/scripts/pre_output_guard.py +64 -64
  80. package/standard-skills/translate-native/scripts/translation_guard.py +916 -916
  81. package/standard-tools/language-guard/blun_language_guard.py +697 -697
  82. package/standard-tools/language-guard/check_diacritics.py +353 -353
  83. package/standard-tools/language-guard/guard_service_client.py +264 -264
  84. package/standard-tools/language-guard/language_quality.py +377 -377
  85. package/standard-tools/language-guard/translation_guard.py +916 -916
@@ -1,167 +1,167 @@
1
- import { randomUUID } from "node:crypto";
2
- import { open, readFile, stat, unlink, writeFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
- import { setTimeout as delay } from "node:timers/promises";
5
- import { canonicalPath, comparablePath, isInside, projectStateDir, stateRoot } from "./paths.js";
6
- import { discoverDocuments } from "./documents.js";
7
- import { isFileLockContention, replaceFileWithRetry } from "./filesystem-retry.js";
8
-
9
- export const CATALOG_SCHEMA = "agentspine.catalog/v1";
10
-
11
- export function catalogScanPolicy(root, env = process.env) {
12
- return {
13
- stateRoot: isInside(comparablePath(root), comparablePath(stateRoot(env))) ? "excluded" : "outside",
14
- authority: "scanner-boundary-only"
15
- };
16
- }
17
-
18
- export function catalogForStateRoot(catalog, root) {
19
- if (!catalog || catalog.schema !== CATALOG_SCHEMA || typeof root !== "string" || !root) {
20
- throw new Error("a resolved catalog and state root are required");
21
- }
22
- if (catalog.root === root) return catalog;
23
- return {
24
- schema: CATALOG_SCHEMA,
25
- generatedAt: catalog.generatedAt,
26
- root,
27
- scanPolicy: catalogScanPolicy(root),
28
- preservation: "source-files-are-read-only",
29
- documents: [],
30
- conflicts: [],
31
- summary: { total: 0, protected: 0, conflicts: 0, byLayer: {} }
32
- };
33
- }
34
-
35
- function catalogConflicts(documents) {
36
- const byPath = new Map(documents.map((document) => [document.relativePath, document]));
37
- const conflicts = [];
38
- for (const document of documents) {
39
- for (const target of document.links) {
40
- if (!byPath.has(target)) {
41
- conflicts.push({ type: "broken-link", source: document.relativePath, target });
42
- }
43
- }
44
- }
45
- const byDirectory = new Map();
46
- for (const document of documents) {
47
- const directory = document.relativePath.includes("/")
48
- ? document.relativePath.slice(0, document.relativePath.lastIndexOf("/"))
49
- : ".";
50
- const key = `${directory}\0${document.layer}\0${document.hosts.join(",")}`;
51
- if (!byDirectory.has(key)) byDirectory.set(key, []);
52
- byDirectory.get(key).push(document);
53
- }
54
- for (const entries of byDirectory.values()) {
55
- if (entries.length < 2 || !["constitution", "soul", "memory-index"].includes(entries[0].layer)) continue;
56
- const names = entries.map((entry) => entry.relativePath).sort();
57
- const knownOverride = names.some((name) => /(?:AGENTS\.override|CLAUDE\.local)\.md$/.test(name));
58
- conflicts.push({
59
- type: knownOverride ? "native-precedence" : "multiple-candidates",
60
- layer: entries[0].layer,
61
- documents: names,
62
- resolution: knownOverride ? "host-native-order" : "agent-review-required"
63
- });
64
- }
65
- return conflicts.sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
66
- }
67
-
68
- export async function buildCatalog(inputRoot = process.cwd(), { env = process.env } = {}) {
69
- const root = await canonicalPath(inputRoot);
70
- const documents = await discoverDocuments(root, { excludeRoots: [stateRoot(env)] });
71
- const conflicts = catalogConflicts(documents);
72
- const byLayer = Object.fromEntries(
73
- [...new Set(documents.map((document) => document.layer))]
74
- .sort()
75
- .map((layer) => [layer, documents.filter((document) => document.layer === layer).length])
76
- );
77
- return {
78
- schema: CATALOG_SCHEMA,
79
- generatedAt: new Date().toISOString(),
80
- root,
81
- scanPolicy: catalogScanPolicy(root, env),
82
- preservation: "source-files-are-read-only",
83
- documents,
84
- conflicts,
85
- summary: {
86
- total: documents.length,
87
- protected: documents.filter((document) => document.protected).length,
88
- conflicts: conflicts.length,
89
- byLayer
90
- }
91
- };
92
- }
93
-
94
- export async function saveCatalog(catalog) {
95
- const directory = await projectStateDir(catalog.root);
96
- const target = join(directory, "catalog.json");
97
- const lockPath = `${target}.lock`;
98
- let handle;
99
- for (let attempt = 0; attempt < 40; attempt += 1) {
100
- try {
101
- handle = await open(lockPath, "wx", 0o600);
102
- break;
103
- } catch (error) {
104
- if (!isFileLockContention(error)) throw error;
105
- try {
106
- const metadata = await stat(lockPath);
107
- if (Date.now() - metadata.mtimeMs > 15000) await unlink(lockPath);
108
- } catch (lockError) {
109
- if (lockError.code !== "ENOENT") throw lockError;
110
- }
111
- await delay(25);
112
- }
113
- }
114
- if (!handle) throw new Error("catalog state is busy; retry later");
115
- const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`;
116
- try {
117
- await writeFile(temporary, `${JSON.stringify(catalog, null, 2)}\n`, { mode: 0o600 });
118
- await replaceFileWithRetry(temporary, target);
119
- return target;
120
- } finally {
121
- await handle.close();
122
- await unlink(temporary).catch((error) => { if (error.code !== "ENOENT") throw error; });
123
- await unlink(lockPath).catch((error) => { if (error.code !== "ENOENT") throw error; });
124
- }
125
- }
126
-
127
- export async function scanAndSave(root) {
128
- const catalog = await buildCatalog(root);
129
- const catalogPath = await saveCatalog(catalog);
130
- return { catalog, catalogPath };
131
- }
132
-
133
- export async function loadCatalog(inputRoot = process.cwd()) {
134
- const root = await canonicalPath(inputRoot);
135
- const directory = await projectStateDir(root);
136
- const path = join(directory, "catalog.json");
137
- const content = await readFile(path, "utf8");
138
- return { catalog: JSON.parse(content), catalogPath: path };
139
- }
140
-
141
- export async function verifyCatalog(inputRoot = process.cwd()) {
142
- let previous;
143
- try {
144
- previous = await loadCatalog(inputRoot);
145
- } catch (error) {
146
- if (error.code === "ENOENT") {
147
- return { ok: false, reason: "no-catalog", added: [], removed: [], changed: [] };
148
- }
149
- throw error;
150
- }
151
- const current = await buildCatalog(previous.catalog.root);
152
- const before = new Map(previous.catalog.documents.map((doc) => [doc.relativePath, doc]));
153
- const after = new Map(current.documents.map((doc) => [doc.relativePath, doc]));
154
- const removed = [...before.keys()].filter((path) => !after.has(path)).sort();
155
- const added = [...after.keys()].filter((path) => !before.has(path)).sort();
156
- const changed = [...after.keys()]
157
- .filter((path) => before.has(path) && before.get(path).sha256 !== after.get(path).sha256)
158
- .sort();
159
- return {
160
- ok: removed.length === 0 && added.length === 0 && changed.length === 0,
161
- reason: "compared",
162
- added,
163
- removed,
164
- changed,
165
- catalogPath: previous.catalogPath
166
- };
167
- }
1
+ import { randomUUID } from "node:crypto";
2
+ import { open, readFile, stat, unlink, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { setTimeout as delay } from "node:timers/promises";
5
+ import { canonicalPath, comparablePath, isInside, projectStateDir, stateRoot } from "./paths.js";
6
+ import { discoverDocuments } from "./documents.js";
7
+ import { isFileLockContention, replaceFileWithRetry } from "./filesystem-retry.js";
8
+
9
+ export const CATALOG_SCHEMA = "agentspine.catalog/v1";
10
+
11
+ export function catalogScanPolicy(root, env = process.env) {
12
+ return {
13
+ stateRoot: isInside(comparablePath(root), comparablePath(stateRoot(env))) ? "excluded" : "outside",
14
+ authority: "scanner-boundary-only"
15
+ };
16
+ }
17
+
18
+ export function catalogForStateRoot(catalog, root) {
19
+ if (!catalog || catalog.schema !== CATALOG_SCHEMA || typeof root !== "string" || !root) {
20
+ throw new Error("a resolved catalog and state root are required");
21
+ }
22
+ if (catalog.root === root) return catalog;
23
+ return {
24
+ schema: CATALOG_SCHEMA,
25
+ generatedAt: catalog.generatedAt,
26
+ root,
27
+ scanPolicy: catalogScanPolicy(root),
28
+ preservation: "source-files-are-read-only",
29
+ documents: [],
30
+ conflicts: [],
31
+ summary: { total: 0, protected: 0, conflicts: 0, byLayer: {} }
32
+ };
33
+ }
34
+
35
+ function catalogConflicts(documents) {
36
+ const byPath = new Map(documents.map((document) => [document.relativePath, document]));
37
+ const conflicts = [];
38
+ for (const document of documents) {
39
+ for (const target of document.links) {
40
+ if (!byPath.has(target)) {
41
+ conflicts.push({ type: "broken-link", source: document.relativePath, target });
42
+ }
43
+ }
44
+ }
45
+ const byDirectory = new Map();
46
+ for (const document of documents) {
47
+ const directory = document.relativePath.includes("/")
48
+ ? document.relativePath.slice(0, document.relativePath.lastIndexOf("/"))
49
+ : ".";
50
+ const key = `${directory}\0${document.layer}\0${document.hosts.join(",")}`;
51
+ if (!byDirectory.has(key)) byDirectory.set(key, []);
52
+ byDirectory.get(key).push(document);
53
+ }
54
+ for (const entries of byDirectory.values()) {
55
+ if (entries.length < 2 || !["constitution", "soul", "memory-index"].includes(entries[0].layer)) continue;
56
+ const names = entries.map((entry) => entry.relativePath).sort();
57
+ const knownOverride = names.some((name) => /(?:AGENTS\.override|CLAUDE\.local)\.md$/.test(name));
58
+ conflicts.push({
59
+ type: knownOverride ? "native-precedence" : "multiple-candidates",
60
+ layer: entries[0].layer,
61
+ documents: names,
62
+ resolution: knownOverride ? "host-native-order" : "agent-review-required"
63
+ });
64
+ }
65
+ return conflicts.sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
66
+ }
67
+
68
+ export async function buildCatalog(inputRoot = process.cwd(), { env = process.env } = {}) {
69
+ const root = await canonicalPath(inputRoot);
70
+ const documents = await discoverDocuments(root, { excludeRoots: [stateRoot(env)] });
71
+ const conflicts = catalogConflicts(documents);
72
+ const byLayer = Object.fromEntries(
73
+ [...new Set(documents.map((document) => document.layer))]
74
+ .sort()
75
+ .map((layer) => [layer, documents.filter((document) => document.layer === layer).length])
76
+ );
77
+ return {
78
+ schema: CATALOG_SCHEMA,
79
+ generatedAt: new Date().toISOString(),
80
+ root,
81
+ scanPolicy: catalogScanPolicy(root, env),
82
+ preservation: "source-files-are-read-only",
83
+ documents,
84
+ conflicts,
85
+ summary: {
86
+ total: documents.length,
87
+ protected: documents.filter((document) => document.protected).length,
88
+ conflicts: conflicts.length,
89
+ byLayer
90
+ }
91
+ };
92
+ }
93
+
94
+ export async function saveCatalog(catalog) {
95
+ const directory = await projectStateDir(catalog.root);
96
+ const target = join(directory, "catalog.json");
97
+ const lockPath = `${target}.lock`;
98
+ let handle;
99
+ for (let attempt = 0; attempt < 40; attempt += 1) {
100
+ try {
101
+ handle = await open(lockPath, "wx", 0o600);
102
+ break;
103
+ } catch (error) {
104
+ if (!isFileLockContention(error)) throw error;
105
+ try {
106
+ const metadata = await stat(lockPath);
107
+ if (Date.now() - metadata.mtimeMs > 15000) await unlink(lockPath);
108
+ } catch (lockError) {
109
+ if (lockError.code !== "ENOENT") throw lockError;
110
+ }
111
+ await delay(25);
112
+ }
113
+ }
114
+ if (!handle) throw new Error("catalog state is busy; retry later");
115
+ const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`;
116
+ try {
117
+ await writeFile(temporary, `${JSON.stringify(catalog, null, 2)}\n`, { mode: 0o600 });
118
+ await replaceFileWithRetry(temporary, target);
119
+ return target;
120
+ } finally {
121
+ await handle.close();
122
+ await unlink(temporary).catch((error) => { if (error.code !== "ENOENT") throw error; });
123
+ await unlink(lockPath).catch((error) => { if (error.code !== "ENOENT") throw error; });
124
+ }
125
+ }
126
+
127
+ export async function scanAndSave(root) {
128
+ const catalog = await buildCatalog(root);
129
+ const catalogPath = await saveCatalog(catalog);
130
+ return { catalog, catalogPath };
131
+ }
132
+
133
+ export async function loadCatalog(inputRoot = process.cwd()) {
134
+ const root = await canonicalPath(inputRoot);
135
+ const directory = await projectStateDir(root);
136
+ const path = join(directory, "catalog.json");
137
+ const content = await readFile(path, "utf8");
138
+ return { catalog: JSON.parse(content), catalogPath: path };
139
+ }
140
+
141
+ export async function verifyCatalog(inputRoot = process.cwd()) {
142
+ let previous;
143
+ try {
144
+ previous = await loadCatalog(inputRoot);
145
+ } catch (error) {
146
+ if (error.code === "ENOENT") {
147
+ return { ok: false, reason: "no-catalog", added: [], removed: [], changed: [] };
148
+ }
149
+ throw error;
150
+ }
151
+ const current = await buildCatalog(previous.catalog.root);
152
+ const before = new Map(previous.catalog.documents.map((doc) => [doc.relativePath, doc]));
153
+ const after = new Map(current.documents.map((doc) => [doc.relativePath, doc]));
154
+ const removed = [...before.keys()].filter((path) => !after.has(path)).sort();
155
+ const added = [...after.keys()].filter((path) => !before.has(path)).sort();
156
+ const changed = [...after.keys()]
157
+ .filter((path) => before.has(path) && before.get(path).sha256 !== after.get(path).sha256)
158
+ .sort();
159
+ return {
160
+ ok: removed.length === 0 && added.length === 0 && changed.length === 0,
161
+ reason: "compared",
162
+ added,
163
+ removed,
164
+ changed,
165
+ catalogPath: previous.catalogPath
166
+ };
167
+ }