@massa-ai/tools-api 1.55.0 → 1.57.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/dist/index.js +188 -5
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -601,15 +601,18 @@ var init_massa_ai_config = __esm(() => {
|
|
|
601
601
|
security: {
|
|
602
602
|
corsOrigins: []
|
|
603
603
|
},
|
|
604
|
-
scheduler: DEFAULT_SCHEDULER_CONFIG
|
|
604
|
+
scheduler: DEFAULT_SCHEDULER_CONFIG,
|
|
605
|
+
bootstrap: { rules: {} }
|
|
605
606
|
};
|
|
606
607
|
});
|
|
607
608
|
|
|
608
609
|
// ../../packages/shared/dist/config/config-loader.js
|
|
609
610
|
var exports_config_loader = {};
|
|
610
611
|
__export(exports_config_loader, {
|
|
612
|
+
writeRawConfig: () => writeRawConfig,
|
|
611
613
|
writeFileAtomically: () => writeFileAtomically,
|
|
612
614
|
saveConfig: () => saveConfig,
|
|
615
|
+
readRawConfigStrict: () => readRawConfigStrict,
|
|
613
616
|
migrateDataDirOnce: () => migrateDataDirOnce,
|
|
614
617
|
mergeSchedulerSection: () => mergeSchedulerSection,
|
|
615
618
|
loadRawUserConfig: () => loadRawUserConfig,
|
|
@@ -620,12 +623,23 @@ __export(exports_config_loader, {
|
|
|
620
623
|
getConfigForEnv: () => getConfigForEnv,
|
|
621
624
|
getConfigDir: () => getConfigDir,
|
|
622
625
|
configExists: () => configExists,
|
|
623
|
-
__resetMigrationForTests: () => __resetMigrationForTests
|
|
626
|
+
__resetMigrationForTests: () => __resetMigrationForTests,
|
|
627
|
+
ConfigWriteConflictError: () => ConfigWriteConflictError,
|
|
628
|
+
ConfigParseError: () => ConfigParseError
|
|
624
629
|
});
|
|
625
630
|
import fs from "fs";
|
|
626
631
|
import path3 from "path";
|
|
627
632
|
import os2 from "os";
|
|
628
633
|
import crypto2 from "crypto";
|
|
634
|
+
function readConfigFileOrEmpty() {
|
|
635
|
+
try {
|
|
636
|
+
return fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
637
|
+
} catch (error) {
|
|
638
|
+
if (error?.code === "ENOENT")
|
|
639
|
+
return "";
|
|
640
|
+
throw error;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
629
643
|
function getConfigDir() {
|
|
630
644
|
return CONFIG_DIR;
|
|
631
645
|
}
|
|
@@ -692,6 +706,21 @@ function loadRawUserConfig() {
|
|
|
692
706
|
return {};
|
|
693
707
|
}
|
|
694
708
|
}
|
|
709
|
+
function readRawConfigStrict() {
|
|
710
|
+
const raw2 = readConfigFileOrEmpty();
|
|
711
|
+
if (raw2 === "")
|
|
712
|
+
return {};
|
|
713
|
+
let parsed;
|
|
714
|
+
try {
|
|
715
|
+
parsed = JSON.parse(raw2);
|
|
716
|
+
} catch (error) {
|
|
717
|
+
throw new ConfigParseError(CONFIG_FILE, error);
|
|
718
|
+
}
|
|
719
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
720
|
+
throw new ConfigParseError(CONFIG_FILE, new Error("parsed value is not a JSON object"));
|
|
721
|
+
}
|
|
722
|
+
return parsed;
|
|
723
|
+
}
|
|
695
724
|
function loadConfigSafe() {
|
|
696
725
|
try {
|
|
697
726
|
return loadConfig();
|
|
@@ -746,6 +775,43 @@ function writeFileAtomically(targetPath, content) {
|
|
|
746
775
|
function saveConfig(config) {
|
|
747
776
|
writeFileAtomically(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
748
777
|
}
|
|
778
|
+
function writeRawConfig(doc, opts) {
|
|
779
|
+
const onDiskAtStart = readConfigFileOrEmpty();
|
|
780
|
+
if (onDiskAtStart === opts.expectedBytes) {
|
|
781
|
+
writeFileAtomically(CONFIG_FILE, JSON.stringify(doc, null, 2));
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
let original;
|
|
785
|
+
let current;
|
|
786
|
+
try {
|
|
787
|
+
original = opts.expectedBytes === "" ? {} : JSON.parse(opts.expectedBytes);
|
|
788
|
+
} catch (error) {
|
|
789
|
+
throw new ConfigParseError(`${CONFIG_FILE} (caller-supplied expectedBytes)`, error);
|
|
790
|
+
}
|
|
791
|
+
try {
|
|
792
|
+
current = onDiskAtStart === "" ? {} : JSON.parse(onDiskAtStart);
|
|
793
|
+
} catch (error) {
|
|
794
|
+
throw new ConfigParseError(CONFIG_FILE, error);
|
|
795
|
+
}
|
|
796
|
+
const reapplied = { ...current };
|
|
797
|
+
const touchedKeys = new Set([...Object.keys(original), ...Object.keys(doc)]);
|
|
798
|
+
for (const key of touchedKeys) {
|
|
799
|
+
const before = JSON.stringify(original[key]);
|
|
800
|
+
const after = JSON.stringify(doc[key]);
|
|
801
|
+
if (before === after)
|
|
802
|
+
continue;
|
|
803
|
+
if (Object.prototype.hasOwnProperty.call(doc, key)) {
|
|
804
|
+
reapplied[key] = doc[key];
|
|
805
|
+
} else {
|
|
806
|
+
delete reapplied[key];
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
const onDiskImmediatelyBeforeWrite = readConfigFileOrEmpty();
|
|
810
|
+
if (onDiskImmediatelyBeforeWrite !== onDiskAtStart) {
|
|
811
|
+
throw new ConfigWriteConflictError(CONFIG_FILE);
|
|
812
|
+
}
|
|
813
|
+
writeFileAtomically(CONFIG_FILE, JSON.stringify(reapplied, null, 2));
|
|
814
|
+
}
|
|
749
815
|
function initConfig() {
|
|
750
816
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
751
817
|
saveConfig(defaultMassaAiConfig);
|
|
@@ -772,12 +838,25 @@ function getConfigForEnv() {
|
|
|
772
838
|
env.ENABLE_METRICS = String(config.logging.enableMetrics);
|
|
773
839
|
return env;
|
|
774
840
|
}
|
|
775
|
-
var CONFIG_DIR, CONFIG_FILE, migrationAttempted = false, tempFileCounter = 0;
|
|
841
|
+
var CONFIG_DIR, CONFIG_FILE, ConfigParseError, ConfigWriteConflictError, migrationAttempted = false, tempFileCounter = 0;
|
|
776
842
|
var init_config_loader = __esm(() => {
|
|
777
843
|
init_massa_ai_config();
|
|
778
844
|
init_xdg();
|
|
779
845
|
CONFIG_DIR = configDir("massa-ai");
|
|
780
846
|
CONFIG_FILE = path3.join(CONFIG_DIR, "config.json");
|
|
847
|
+
ConfigParseError = class ConfigParseError extends Error {
|
|
848
|
+
constructor(filePath, cause) {
|
|
849
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
850
|
+
super(`Failed to parse ${filePath}: ${reason}`);
|
|
851
|
+
this.name = "ConfigParseError";
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
ConfigWriteConflictError = class ConfigWriteConflictError extends Error {
|
|
855
|
+
constructor(filePath) {
|
|
856
|
+
super(`${filePath} changed on disk twice while writing \u2014 refusing to overwrite a ` + `concurrent update. Re-read the file and retry.`);
|
|
857
|
+
this.name = "ConfigWriteConflictError";
|
|
858
|
+
}
|
|
859
|
+
};
|
|
781
860
|
});
|
|
782
861
|
|
|
783
862
|
// ../../packages/shared/dist/env.js
|
|
@@ -8572,6 +8651,105 @@ function findRepoRootWithMarker(startDir, marker, maxLevels) {
|
|
|
8572
8651
|
}
|
|
8573
8652
|
var init_repo_root = () => {};
|
|
8574
8653
|
|
|
8654
|
+
// ../../packages/shared/dist/bootstrap/rules.js
|
|
8655
|
+
var BOOTSTRAP_RULES, RULES_BY_ID;
|
|
8656
|
+
var init_rules = __esm(() => {
|
|
8657
|
+
BOOTSTRAP_RULES = [
|
|
8658
|
+
{
|
|
8659
|
+
id: "caveman",
|
|
8660
|
+
defaultEnabled: true,
|
|
8661
|
+
description: "Keep communication compressed while preserving technical accuracy."
|
|
8662
|
+
},
|
|
8663
|
+
{
|
|
8664
|
+
id: "massa-ai-router",
|
|
8665
|
+
defaultEnabled: true,
|
|
8666
|
+
description: "Load the massa-ai skill as the workflow router before substantive work."
|
|
8667
|
+
},
|
|
8668
|
+
{
|
|
8669
|
+
id: "persona-router",
|
|
8670
|
+
defaultEnabled: true,
|
|
8671
|
+
description: "Select one cataloged specialist persona after massa-ai context is available."
|
|
8672
|
+
},
|
|
8673
|
+
{
|
|
8674
|
+
id: "dedupe-guardrails",
|
|
8675
|
+
defaultEnabled: true,
|
|
8676
|
+
description: "Reuse already-loaded massa-ai context instead of bulk-loading workflows or references."
|
|
8677
|
+
},
|
|
8678
|
+
{
|
|
8679
|
+
id: "plan-challenge",
|
|
8680
|
+
defaultEnabled: true,
|
|
8681
|
+
description: "Run The Fool as a post-plan challenge gate per the configured policy."
|
|
8682
|
+
},
|
|
8683
|
+
{
|
|
8684
|
+
id: "conversation-feedback",
|
|
8685
|
+
defaultEnabled: true,
|
|
8686
|
+
description: "Emit chat-visible status updates for massa-ai workflow progress."
|
|
8687
|
+
},
|
|
8688
|
+
{
|
|
8689
|
+
id: "indexing-hygiene",
|
|
8690
|
+
defaultEnabled: true,
|
|
8691
|
+
description: "Ignore build output, dependency, and secret paths during indexing and context loading."
|
|
8692
|
+
},
|
|
8693
|
+
{
|
|
8694
|
+
id: "english-code",
|
|
8695
|
+
defaultEnabled: true,
|
|
8696
|
+
description: "Write generated code, identifiers, comments, and commit-facing artifacts in English regardless of conversational language."
|
|
8697
|
+
},
|
|
8698
|
+
{
|
|
8699
|
+
id: "code-comments",
|
|
8700
|
+
defaultEnabled: false,
|
|
8701
|
+
description: "Require API doc blocks and rationale comments on generated code, per code-annotation.md \xA71/\xA72."
|
|
8702
|
+
}
|
|
8703
|
+
];
|
|
8704
|
+
RULES_BY_ID = new Map(BOOTSTRAP_RULES.map((rule) => [rule.id, rule]));
|
|
8705
|
+
});
|
|
8706
|
+
|
|
8707
|
+
// ../../packages/shared/dist/bootstrap/state.js
|
|
8708
|
+
var BOOTSTRAP_STATE_KEY = "bootstrap", BOOTSTRAP_RULES_KEY = "rules", BOOTSTRAP_STATE_PATH;
|
|
8709
|
+
var init_state2 = __esm(() => {
|
|
8710
|
+
init_config_loader();
|
|
8711
|
+
init_rules();
|
|
8712
|
+
BOOTSTRAP_STATE_PATH = `${BOOTSTRAP_STATE_KEY}.${BOOTSTRAP_RULES_KEY}`;
|
|
8713
|
+
});
|
|
8714
|
+
|
|
8715
|
+
// ../../packages/shared/dist/bootstrap/render.js
|
|
8716
|
+
var init_render = __esm(() => {
|
|
8717
|
+
init_rules();
|
|
8718
|
+
init_state2();
|
|
8719
|
+
});
|
|
8720
|
+
|
|
8721
|
+
// ../../packages/shared/dist/bootstrap/report.js
|
|
8722
|
+
var CLEAN_STATUSES;
|
|
8723
|
+
var init_report = __esm(() => {
|
|
8724
|
+
CLEAN_STATUSES = new Set(["written", "skipped"]);
|
|
8725
|
+
});
|
|
8726
|
+
|
|
8727
|
+
// ../../packages/shared/dist/bootstrap/engine.js
|
|
8728
|
+
var init_engine2 = __esm(() => {
|
|
8729
|
+
init_config_loader();
|
|
8730
|
+
init_hosts();
|
|
8731
|
+
init_state();
|
|
8732
|
+
init_render();
|
|
8733
|
+
init_report();
|
|
8734
|
+
init_state2();
|
|
8735
|
+
});
|
|
8736
|
+
|
|
8737
|
+
// ../../packages/shared/dist/bootstrap/format.js
|
|
8738
|
+
var init_format = __esm(() => {
|
|
8739
|
+
init_rules();
|
|
8740
|
+
});
|
|
8741
|
+
|
|
8742
|
+
// ../../packages/shared/dist/bootstrap/index.js
|
|
8743
|
+
var init_bootstrap = __esm(() => {
|
|
8744
|
+
init_rules();
|
|
8745
|
+
init_state2();
|
|
8746
|
+
init_render();
|
|
8747
|
+
init_report();
|
|
8748
|
+
init_engine2();
|
|
8749
|
+
init_format();
|
|
8750
|
+
init_config_loader();
|
|
8751
|
+
});
|
|
8752
|
+
|
|
8575
8753
|
// ../../packages/shared/dist/index.js
|
|
8576
8754
|
var init_dist = __esm(() => {
|
|
8577
8755
|
init_env();
|
|
@@ -8582,6 +8760,7 @@ var init_dist = __esm(() => {
|
|
|
8582
8760
|
init_engine();
|
|
8583
8761
|
init_variant_sync();
|
|
8584
8762
|
init_repo_root();
|
|
8763
|
+
init_bootstrap();
|
|
8585
8764
|
init_types();
|
|
8586
8765
|
init_interfaces();
|
|
8587
8766
|
init_utils();
|
|
@@ -183398,6 +183577,8 @@ function sseFrame(data) {
|
|
|
183398
183577
|
`);
|
|
183399
183578
|
}
|
|
183400
183579
|
var KNOWN_GENERATOR_FILENAMES = ["generate-skill-artifacts.ts", "generate-subagent-artifacts.ts"];
|
|
183580
|
+
var SH_C_WRAPPER = /^sh -c '(.*)' --$/;
|
|
183581
|
+
var GENERATOR_SEGMENT = /^bun\s+(\S+\.ts)(?:\s+"\$@")?$/;
|
|
183401
183582
|
function deriveGeneratorScripts(root2) {
|
|
183402
183583
|
const pkgPath = path42.join(root2, "package.json");
|
|
183403
183584
|
let raw2;
|
|
@@ -183417,12 +183598,14 @@ function deriveGeneratorScripts(root2) {
|
|
|
183417
183598
|
if (typeof command !== "string" || command.trim().length === 0) {
|
|
183418
183599
|
throw new Error(`${pkgPath}'s scripts."generate:artifacts" is missing or not a string`);
|
|
183419
183600
|
}
|
|
183420
|
-
const
|
|
183601
|
+
const wrapped = SH_C_WRAPPER.exec(command.trim());
|
|
183602
|
+
const chain = wrapped ? wrapped[1] : command;
|
|
183603
|
+
const segments = chain.split("&&").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
183421
183604
|
if (segments.length === 0) {
|
|
183422
183605
|
throw new Error(`"generate:artifacts" parsed to zero commands: ${JSON.stringify(command)}`);
|
|
183423
183606
|
}
|
|
183424
183607
|
return segments.map((segment) => {
|
|
183425
|
-
const match2 =
|
|
183608
|
+
const match2 = GENERATOR_SEGMENT.exec(segment);
|
|
183426
183609
|
if (!match2) {
|
|
183427
183610
|
throw new Error(`"generate:artifacts" segment does not match the expected "bun <script.ts>" shape: ${JSON.stringify(segment)}`);
|
|
183428
183611
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massa-ai/tools-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.57.0",
|
|
4
4
|
"author": "luizgmassa",
|
|
5
5
|
"description": "massa-ai REST API server - Semantic code search, memory, and context compression",
|
|
6
6
|
"type": "module",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"test": "bun scripts/run-tests-isolated.ts"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@massa-ai/core": "^1.
|
|
25
|
-
"@massa-ai/shared": "^1.
|
|
24
|
+
"@massa-ai/core": "^1.57.0",
|
|
25
|
+
"@massa-ai/shared": "^1.57.0",
|
|
26
26
|
"elysia": "^1.2.25",
|
|
27
27
|
"@elysiajs/swagger": "^1.2.0",
|
|
28
28
|
"@elysiajs/cors": "^1.2.0",
|