@launchsecure/launch-kit 0.0.33 → 0.0.34
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/server/chart-serve.js +167 -2
- package/dist/server/cli.js +249 -41
- package/dist/server/council-entry.js +0 -0
- package/dist/server/course-entry.js +1 -1
- package/dist/server/fb-wizard.js +0 -0
- package/dist/server/graph-mcp-entry.js +180 -4
- package/dist/server/init-entry.js +438 -43
- package/dist/server/launch-radar-entry.js +45 -0
- package/dist/server/parse-worker-entry.js +167 -2
- package/dist/server/radar-docker-init-entry.js +444 -39
- package/dist/server/radar-entrypoint-entry.js +0 -0
- package/dist/server/radar-teardown-entry.js +23 -22
- package/dist/server/rover-entry.js +20122 -0
- package/package.json +28 -25
- package/scaffolds/ls-marketplace/plugins/kit/commands/standup.md +6 -6
- package/scaffolds/ls-marketplace/plugins/kit/skills/analyse/SKILL.md +6 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/brief/SKILL.md +40 -48
- package/scaffolds/ls-marketplace/plugins/kit/skills/debug/SKILL.md +45 -20
- package/scaffolds/ls-marketplace/plugins/kit/skills/deploy-check/SKILL.md +76 -67
- package/scaffolds/ls-marketplace/plugins/kit/skills/handoff/SKILL.md +132 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/ship/SKILL.md +149 -133
- package/scaffolds/migrate-safety/scripts/migrate-with-backup.sh +0 -0
- package/scaffolds/recall-hook/scripts/ensure-recall.sh +0 -0
|
@@ -246,6 +246,7 @@ function emptyParsedFile(absPath) {
|
|
|
246
246
|
return {
|
|
247
247
|
name: absPath.split("/").pop() ?? absPath,
|
|
248
248
|
exports: [],
|
|
249
|
+
defines: [],
|
|
249
250
|
imports: [],
|
|
250
251
|
reExports: [],
|
|
251
252
|
jsxElements: /* @__PURE__ */ new Set(),
|
|
@@ -358,6 +359,34 @@ function parseFileTS(absPath) {
|
|
|
358
359
|
reExports.push({ name: "*", from: caps["reexport.wildcard.source"], isWildcard: true });
|
|
359
360
|
}
|
|
360
361
|
}
|
|
362
|
+
const definesSet = /* @__PURE__ */ new Set();
|
|
363
|
+
function recordCallable(decl) {
|
|
364
|
+
if (decl.type === "function_declaration" || decl.type === "generator_function_declaration") {
|
|
365
|
+
const id = childOfType(decl, "identifier");
|
|
366
|
+
if (id) definesSet.add(id.text);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (decl.type === "class_declaration") {
|
|
370
|
+
const id = childOfType(decl, "type_identifier") ?? childOfType(decl, "identifier");
|
|
371
|
+
if (id) definesSet.add(id.text);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
if (decl.type === "lexical_declaration" || decl.type === "variable_declaration") {
|
|
375
|
+
for (const d of childrenOfType(decl, "variable_declarator")) {
|
|
376
|
+
const id = childOfType(d, "identifier");
|
|
377
|
+
if (!id) continue;
|
|
378
|
+
const isCallable = !!childOfType(d, "arrow_function") || !!childOfType(d, "function_expression") || !!childOfType(d, "function") || !!childOfType(d, "generator_function");
|
|
379
|
+
if (isCallable) definesSet.add(id.text);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
for (const child of root.children) {
|
|
384
|
+
if (child.type === "export_statement") {
|
|
385
|
+
for (const gc of child.children) recordCallable(gc);
|
|
386
|
+
} else {
|
|
387
|
+
recordCallable(child);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
361
390
|
const jsxElements = /* @__PURE__ */ new Set();
|
|
362
391
|
const jsxQuery = getQuery("jsx-elements");
|
|
363
392
|
const jsxCaptures = jsxQuery.captures(root);
|
|
@@ -446,7 +475,7 @@ function parseFileTS(absPath) {
|
|
|
446
475
|
}
|
|
447
476
|
}
|
|
448
477
|
const name = defaultName ?? firstValueExport ?? firstTypeExport ?? "";
|
|
449
|
-
return { name, exports: exportsOrdered, imports, reExports, jsxElements, navigations, fetchCalls };
|
|
478
|
+
return { name, exports: exportsOrdered, defines: [...definesSet], imports, reExports, jsxElements, navigations, fetchCalls };
|
|
450
479
|
}
|
|
451
480
|
function extractDbCallsTS(absPath) {
|
|
452
481
|
const tree = parseSource(absPath);
|
|
@@ -2884,6 +2913,11 @@ function generate(rootDir) {
|
|
|
2884
2913
|
const parsed = parsedByPath.get(absPath);
|
|
2885
2914
|
const name = parsed.name || nameFromFilename(absPath);
|
|
2886
2915
|
const layer = CLASSIFICATION_TO_LAYER[type] ?? "ui";
|
|
2916
|
+
const importedNames = [...new Set(
|
|
2917
|
+
parsed.imports.flatMap(
|
|
2918
|
+
(imp) => imp.isTypeOnly ? [] : imp.names.filter((n) => !imp.typeNames.has(n))
|
|
2919
|
+
)
|
|
2920
|
+
)];
|
|
2887
2921
|
nodeIdSet.add(id);
|
|
2888
2922
|
if (layer === "api") {
|
|
2889
2923
|
const dbCalls = extractDbCallsTS(absPath);
|
|
@@ -2922,6 +2956,8 @@ function generate(rootDir) {
|
|
|
2922
2956
|
responses: deep.responses,
|
|
2923
2957
|
params: deep.params,
|
|
2924
2958
|
...deep.effects ? { effects: deep.effects } : {},
|
|
2959
|
+
...parsed.defines.length > 0 ? { defines: parsed.defines } : {},
|
|
2960
|
+
...importedNames.length > 0 ? { imported_names: importedNames } : {},
|
|
2925
2961
|
...deep.notes ? { notes: deep.notes } : {},
|
|
2926
2962
|
_dbCalls: dbCalls
|
|
2927
2963
|
// temp: used for cross-ref building below
|
|
@@ -2938,6 +2974,8 @@ function generate(rootDir) {
|
|
|
2938
2974
|
layer: "ui",
|
|
2939
2975
|
route,
|
|
2940
2976
|
exports: parsed.exports,
|
|
2977
|
+
...parsed.defines.length > 0 ? { defines: parsed.defines } : {},
|
|
2978
|
+
...importedNames.length > 0 ? { imported_names: importedNames } : {},
|
|
2941
2979
|
elements: deep.elements,
|
|
2942
2980
|
stateVars: deep.stateVars,
|
|
2943
2981
|
conditions: deep.conditions,
|
|
@@ -5898,6 +5936,132 @@ var middlewareGatesParser = {
|
|
|
5898
5936
|
}
|
|
5899
5937
|
};
|
|
5900
5938
|
|
|
5939
|
+
// src/server/graph/parsers/crosslayer/call-resolver.ts
|
|
5940
|
+
var BARE_IDENT = /^[A-Za-z_$][\w$]*$/;
|
|
5941
|
+
var callResolverParser = {
|
|
5942
|
+
id: "call-resolver",
|
|
5943
|
+
layer: "crosslayer",
|
|
5944
|
+
concern: "call-graph",
|
|
5945
|
+
detect(_rootDir) {
|
|
5946
|
+
return true;
|
|
5947
|
+
},
|
|
5948
|
+
generate(_rootDir, layerOutputs) {
|
|
5949
|
+
const definers = /* @__PURE__ */ new Map();
|
|
5950
|
+
const addDef = (sym, entry) => {
|
|
5951
|
+
if (!BARE_IDENT.test(sym)) return;
|
|
5952
|
+
const list = definers.get(sym);
|
|
5953
|
+
if (!list) {
|
|
5954
|
+
definers.set(sym, [entry]);
|
|
5955
|
+
} else if (!list.some((d) => d.nodeId === entry.nodeId)) {
|
|
5956
|
+
list.push(entry);
|
|
5957
|
+
}
|
|
5958
|
+
};
|
|
5959
|
+
const nodeLayer = /* @__PURE__ */ new Map();
|
|
5960
|
+
for (const [layer, output] of layerOutputs) {
|
|
5961
|
+
if (layer === "db" || layer === "static") continue;
|
|
5962
|
+
for (const node of output.nodes) {
|
|
5963
|
+
nodeLayer.set(node.id, layer);
|
|
5964
|
+
const entry = { nodeId: node.id, layer };
|
|
5965
|
+
for (const s of node.exports ?? []) addDef(s, entry);
|
|
5966
|
+
for (const s of node.defines ?? []) addDef(s, entry);
|
|
5967
|
+
}
|
|
5968
|
+
}
|
|
5969
|
+
const importTargets = /* @__PURE__ */ new Map();
|
|
5970
|
+
for (const [, output] of layerOutputs) {
|
|
5971
|
+
for (const e of output.edges) {
|
|
5972
|
+
if (e.type !== "imports" && e.type !== "imports_type" && e.type !== "renders") continue;
|
|
5973
|
+
let set = importTargets.get(e.source);
|
|
5974
|
+
if (!set) {
|
|
5975
|
+
set = /* @__PURE__ */ new Set();
|
|
5976
|
+
importTargets.set(e.source, set);
|
|
5977
|
+
}
|
|
5978
|
+
set.add(e.target);
|
|
5979
|
+
}
|
|
5980
|
+
}
|
|
5981
|
+
const crossRefs = [];
|
|
5982
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5983
|
+
let resolvedSelf = 0;
|
|
5984
|
+
let resolvedImport = 0;
|
|
5985
|
+
let ambiguous = 0;
|
|
5986
|
+
let dropped = 0;
|
|
5987
|
+
for (const [, output] of layerOutputs) {
|
|
5988
|
+
for (const node of output.nodes) {
|
|
5989
|
+
const calls = node.effects?.calls;
|
|
5990
|
+
if (!calls || calls.length === 0) continue;
|
|
5991
|
+
const selfSyms = /* @__PURE__ */ new Set([
|
|
5992
|
+
...node.exports ?? [],
|
|
5993
|
+
...node.defines ?? []
|
|
5994
|
+
]);
|
|
5995
|
+
const importedSyms = new Set(node.imported_names ?? []);
|
|
5996
|
+
const myImports = importTargets.get(node.id);
|
|
5997
|
+
const localSeen = /* @__PURE__ */ new Set();
|
|
5998
|
+
for (const callee of calls) {
|
|
5999
|
+
if (!BARE_IDENT.test(callee)) continue;
|
|
6000
|
+
if (localSeen.has(callee)) continue;
|
|
6001
|
+
localSeen.add(callee);
|
|
6002
|
+
const key = `${node.id}\u2192${callee}`;
|
|
6003
|
+
if (selfSyms.has(callee)) {
|
|
6004
|
+
if (seen.has(key)) continue;
|
|
6005
|
+
seen.add(key);
|
|
6006
|
+
crossRefs.push({
|
|
6007
|
+
source: node.id,
|
|
6008
|
+
target: callee,
|
|
6009
|
+
type: "calls",
|
|
6010
|
+
layer: nodeLayer.get(node.id) ?? "ui",
|
|
6011
|
+
defined_in: node.id
|
|
6012
|
+
});
|
|
6013
|
+
resolvedSelf++;
|
|
6014
|
+
continue;
|
|
6015
|
+
}
|
|
6016
|
+
if (!importedSyms.has(callee)) {
|
|
6017
|
+
dropped++;
|
|
6018
|
+
continue;
|
|
6019
|
+
}
|
|
6020
|
+
const defs = (definers.get(callee) ?? []).filter((d) => d.nodeId !== node.id);
|
|
6021
|
+
if (defs.length === 0) {
|
|
6022
|
+
dropped++;
|
|
6023
|
+
continue;
|
|
6024
|
+
}
|
|
6025
|
+
const fromImported = myImports ? defs.filter((d) => myImports.has(d.nodeId)) : [];
|
|
6026
|
+
const chosen = fromImported.length > 0 ? fromImported : defs;
|
|
6027
|
+
const owner = chosen[0];
|
|
6028
|
+
const isAmbiguous = chosen.length > 1;
|
|
6029
|
+
if (isAmbiguous) ambiguous++;
|
|
6030
|
+
if (seen.has(key)) continue;
|
|
6031
|
+
seen.add(key);
|
|
6032
|
+
const ref = {
|
|
6033
|
+
source: node.id,
|
|
6034
|
+
target: callee,
|
|
6035
|
+
type: "calls",
|
|
6036
|
+
layer: owner.layer,
|
|
6037
|
+
defined_in: owner.nodeId
|
|
6038
|
+
};
|
|
6039
|
+
if (isAmbiguous) ref.ambiguous = true;
|
|
6040
|
+
crossRefs.push(ref);
|
|
6041
|
+
resolvedImport++;
|
|
6042
|
+
}
|
|
6043
|
+
}
|
|
6044
|
+
}
|
|
6045
|
+
crossRefs.sort(
|
|
6046
|
+
(a, b) => a.source.localeCompare(b.source) || a.target.localeCompare(b.target)
|
|
6047
|
+
);
|
|
6048
|
+
return {
|
|
6049
|
+
cross_refs: crossRefs,
|
|
6050
|
+
flagged_edges: [],
|
|
6051
|
+
warnings: [],
|
|
6052
|
+
patterns: {
|
|
6053
|
+
call_resolution: {
|
|
6054
|
+
resolved_self: resolvedSelf,
|
|
6055
|
+
resolved_import: resolvedImport,
|
|
6056
|
+
ambiguous,
|
|
6057
|
+
dropped,
|
|
6058
|
+
symbols_defined: definers.size
|
|
6059
|
+
}
|
|
6060
|
+
}
|
|
6061
|
+
};
|
|
6062
|
+
}
|
|
6063
|
+
};
|
|
6064
|
+
|
|
5901
6065
|
// src/server/graph/core/parser-registry.ts
|
|
5902
6066
|
function isMultiLayerParser(p) {
|
|
5903
6067
|
return "layers" in p && Array.isArray(p.layers);
|
|
@@ -5964,7 +6128,8 @@ function registerBuiltins2(registry, disabled) {
|
|
|
5964
6128
|
apiAnnotationsParser,
|
|
5965
6129
|
urlLiteralScannerParser,
|
|
5966
6130
|
staticRefScannerParser,
|
|
5967
|
-
middlewareGatesParser
|
|
6131
|
+
middlewareGatesParser,
|
|
6132
|
+
callResolverParser
|
|
5968
6133
|
];
|
|
5969
6134
|
for (const parser of builtins) {
|
|
5970
6135
|
if (disabled.has(parser.id)) continue;
|