@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
|
@@ -1516,6 +1516,7 @@ function emptyParsedFile(absPath) {
|
|
|
1516
1516
|
return {
|
|
1517
1517
|
name: absPath.split("/").pop() ?? absPath,
|
|
1518
1518
|
exports: [],
|
|
1519
|
+
defines: [],
|
|
1519
1520
|
imports: [],
|
|
1520
1521
|
reExports: [],
|
|
1521
1522
|
jsxElements: /* @__PURE__ */ new Set(),
|
|
@@ -1628,6 +1629,34 @@ function parseFileTS(absPath) {
|
|
|
1628
1629
|
reExports.push({ name: "*", from: caps["reexport.wildcard.source"], isWildcard: true });
|
|
1629
1630
|
}
|
|
1630
1631
|
}
|
|
1632
|
+
const definesSet = /* @__PURE__ */ new Set();
|
|
1633
|
+
function recordCallable(decl) {
|
|
1634
|
+
if (decl.type === "function_declaration" || decl.type === "generator_function_declaration") {
|
|
1635
|
+
const id = childOfType(decl, "identifier");
|
|
1636
|
+
if (id) definesSet.add(id.text);
|
|
1637
|
+
return;
|
|
1638
|
+
}
|
|
1639
|
+
if (decl.type === "class_declaration") {
|
|
1640
|
+
const id = childOfType(decl, "type_identifier") ?? childOfType(decl, "identifier");
|
|
1641
|
+
if (id) definesSet.add(id.text);
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
if (decl.type === "lexical_declaration" || decl.type === "variable_declaration") {
|
|
1645
|
+
for (const d of childrenOfType(decl, "variable_declarator")) {
|
|
1646
|
+
const id = childOfType(d, "identifier");
|
|
1647
|
+
if (!id) continue;
|
|
1648
|
+
const isCallable = !!childOfType(d, "arrow_function") || !!childOfType(d, "function_expression") || !!childOfType(d, "function") || !!childOfType(d, "generator_function");
|
|
1649
|
+
if (isCallable) definesSet.add(id.text);
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
for (const child of root.children) {
|
|
1654
|
+
if (child.type === "export_statement") {
|
|
1655
|
+
for (const gc of child.children) recordCallable(gc);
|
|
1656
|
+
} else {
|
|
1657
|
+
recordCallable(child);
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1631
1660
|
const jsxElements = /* @__PURE__ */ new Set();
|
|
1632
1661
|
const jsxQuery = getQuery("jsx-elements");
|
|
1633
1662
|
const jsxCaptures = jsxQuery.captures(root);
|
|
@@ -1716,7 +1745,7 @@ function parseFileTS(absPath) {
|
|
|
1716
1745
|
}
|
|
1717
1746
|
}
|
|
1718
1747
|
const name = defaultName ?? firstValueExport ?? firstTypeExport ?? "";
|
|
1719
|
-
return { name, exports: exportsOrdered, imports, reExports, jsxElements, navigations, fetchCalls };
|
|
1748
|
+
return { name, exports: exportsOrdered, defines: [...definesSet], imports, reExports, jsxElements, navigations, fetchCalls };
|
|
1720
1749
|
}
|
|
1721
1750
|
function extractDbCallsTS(absPath) {
|
|
1722
1751
|
const tree = parseSource(absPath);
|
|
@@ -2933,6 +2962,11 @@ function generate(rootDir) {
|
|
|
2933
2962
|
const parsed = parsedByPath.get(absPath);
|
|
2934
2963
|
const name = parsed.name || nameFromFilename(absPath);
|
|
2935
2964
|
const layer = CLASSIFICATION_TO_LAYER[type] ?? "ui";
|
|
2965
|
+
const importedNames = [...new Set(
|
|
2966
|
+
parsed.imports.flatMap(
|
|
2967
|
+
(imp) => imp.isTypeOnly ? [] : imp.names.filter((n) => !imp.typeNames.has(n))
|
|
2968
|
+
)
|
|
2969
|
+
)];
|
|
2936
2970
|
nodeIdSet.add(id);
|
|
2937
2971
|
if (layer === "api") {
|
|
2938
2972
|
const dbCalls = extractDbCallsTS(absPath);
|
|
@@ -2971,6 +3005,8 @@ function generate(rootDir) {
|
|
|
2971
3005
|
responses: deep.responses,
|
|
2972
3006
|
params: deep.params,
|
|
2973
3007
|
...deep.effects ? { effects: deep.effects } : {},
|
|
3008
|
+
...parsed.defines.length > 0 ? { defines: parsed.defines } : {},
|
|
3009
|
+
...importedNames.length > 0 ? { imported_names: importedNames } : {},
|
|
2974
3010
|
...deep.notes ? { notes: deep.notes } : {},
|
|
2975
3011
|
_dbCalls: dbCalls
|
|
2976
3012
|
// temp: used for cross-ref building below
|
|
@@ -2987,6 +3023,8 @@ function generate(rootDir) {
|
|
|
2987
3023
|
layer: "ui",
|
|
2988
3024
|
route,
|
|
2989
3025
|
exports: parsed.exports,
|
|
3026
|
+
...parsed.defines.length > 0 ? { defines: parsed.defines } : {},
|
|
3027
|
+
...importedNames.length > 0 ? { imported_names: importedNames } : {},
|
|
2990
3028
|
elements: deep.elements,
|
|
2991
3029
|
stateVars: deep.stateVars,
|
|
2992
3030
|
conditions: deep.conditions,
|
|
@@ -6041,6 +6079,138 @@ var init_middleware_gates = __esm({
|
|
|
6041
6079
|
}
|
|
6042
6080
|
});
|
|
6043
6081
|
|
|
6082
|
+
// src/server/graph/parsers/crosslayer/call-resolver.ts
|
|
6083
|
+
var BARE_IDENT, callResolverParser;
|
|
6084
|
+
var init_call_resolver = __esm({
|
|
6085
|
+
"src/server/graph/parsers/crosslayer/call-resolver.ts"() {
|
|
6086
|
+
"use strict";
|
|
6087
|
+
BARE_IDENT = /^[A-Za-z_$][\w$]*$/;
|
|
6088
|
+
callResolverParser = {
|
|
6089
|
+
id: "call-resolver",
|
|
6090
|
+
layer: "crosslayer",
|
|
6091
|
+
concern: "call-graph",
|
|
6092
|
+
detect(_rootDir) {
|
|
6093
|
+
return true;
|
|
6094
|
+
},
|
|
6095
|
+
generate(_rootDir, layerOutputs) {
|
|
6096
|
+
const definers = /* @__PURE__ */ new Map();
|
|
6097
|
+
const addDef = (sym, entry) => {
|
|
6098
|
+
if (!BARE_IDENT.test(sym)) return;
|
|
6099
|
+
const list = definers.get(sym);
|
|
6100
|
+
if (!list) {
|
|
6101
|
+
definers.set(sym, [entry]);
|
|
6102
|
+
} else if (!list.some((d) => d.nodeId === entry.nodeId)) {
|
|
6103
|
+
list.push(entry);
|
|
6104
|
+
}
|
|
6105
|
+
};
|
|
6106
|
+
const nodeLayer = /* @__PURE__ */ new Map();
|
|
6107
|
+
for (const [layer, output] of layerOutputs) {
|
|
6108
|
+
if (layer === "db" || layer === "static") continue;
|
|
6109
|
+
for (const node of output.nodes) {
|
|
6110
|
+
nodeLayer.set(node.id, layer);
|
|
6111
|
+
const entry = { nodeId: node.id, layer };
|
|
6112
|
+
for (const s of node.exports ?? []) addDef(s, entry);
|
|
6113
|
+
for (const s of node.defines ?? []) addDef(s, entry);
|
|
6114
|
+
}
|
|
6115
|
+
}
|
|
6116
|
+
const importTargets = /* @__PURE__ */ new Map();
|
|
6117
|
+
for (const [, output] of layerOutputs) {
|
|
6118
|
+
for (const e of output.edges) {
|
|
6119
|
+
if (e.type !== "imports" && e.type !== "imports_type" && e.type !== "renders") continue;
|
|
6120
|
+
let set = importTargets.get(e.source);
|
|
6121
|
+
if (!set) {
|
|
6122
|
+
set = /* @__PURE__ */ new Set();
|
|
6123
|
+
importTargets.set(e.source, set);
|
|
6124
|
+
}
|
|
6125
|
+
set.add(e.target);
|
|
6126
|
+
}
|
|
6127
|
+
}
|
|
6128
|
+
const crossRefs = [];
|
|
6129
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6130
|
+
let resolvedSelf = 0;
|
|
6131
|
+
let resolvedImport = 0;
|
|
6132
|
+
let ambiguous = 0;
|
|
6133
|
+
let dropped = 0;
|
|
6134
|
+
for (const [, output] of layerOutputs) {
|
|
6135
|
+
for (const node of output.nodes) {
|
|
6136
|
+
const calls = node.effects?.calls;
|
|
6137
|
+
if (!calls || calls.length === 0) continue;
|
|
6138
|
+
const selfSyms = /* @__PURE__ */ new Set([
|
|
6139
|
+
...node.exports ?? [],
|
|
6140
|
+
...node.defines ?? []
|
|
6141
|
+
]);
|
|
6142
|
+
const importedSyms = new Set(node.imported_names ?? []);
|
|
6143
|
+
const myImports = importTargets.get(node.id);
|
|
6144
|
+
const localSeen = /* @__PURE__ */ new Set();
|
|
6145
|
+
for (const callee of calls) {
|
|
6146
|
+
if (!BARE_IDENT.test(callee)) continue;
|
|
6147
|
+
if (localSeen.has(callee)) continue;
|
|
6148
|
+
localSeen.add(callee);
|
|
6149
|
+
const key = `${node.id}\u2192${callee}`;
|
|
6150
|
+
if (selfSyms.has(callee)) {
|
|
6151
|
+
if (seen.has(key)) continue;
|
|
6152
|
+
seen.add(key);
|
|
6153
|
+
crossRefs.push({
|
|
6154
|
+
source: node.id,
|
|
6155
|
+
target: callee,
|
|
6156
|
+
type: "calls",
|
|
6157
|
+
layer: nodeLayer.get(node.id) ?? "ui",
|
|
6158
|
+
defined_in: node.id
|
|
6159
|
+
});
|
|
6160
|
+
resolvedSelf++;
|
|
6161
|
+
continue;
|
|
6162
|
+
}
|
|
6163
|
+
if (!importedSyms.has(callee)) {
|
|
6164
|
+
dropped++;
|
|
6165
|
+
continue;
|
|
6166
|
+
}
|
|
6167
|
+
const defs = (definers.get(callee) ?? []).filter((d) => d.nodeId !== node.id);
|
|
6168
|
+
if (defs.length === 0) {
|
|
6169
|
+
dropped++;
|
|
6170
|
+
continue;
|
|
6171
|
+
}
|
|
6172
|
+
const fromImported = myImports ? defs.filter((d) => myImports.has(d.nodeId)) : [];
|
|
6173
|
+
const chosen = fromImported.length > 0 ? fromImported : defs;
|
|
6174
|
+
const owner = chosen[0];
|
|
6175
|
+
const isAmbiguous = chosen.length > 1;
|
|
6176
|
+
if (isAmbiguous) ambiguous++;
|
|
6177
|
+
if (seen.has(key)) continue;
|
|
6178
|
+
seen.add(key);
|
|
6179
|
+
const ref = {
|
|
6180
|
+
source: node.id,
|
|
6181
|
+
target: callee,
|
|
6182
|
+
type: "calls",
|
|
6183
|
+
layer: owner.layer,
|
|
6184
|
+
defined_in: owner.nodeId
|
|
6185
|
+
};
|
|
6186
|
+
if (isAmbiguous) ref.ambiguous = true;
|
|
6187
|
+
crossRefs.push(ref);
|
|
6188
|
+
resolvedImport++;
|
|
6189
|
+
}
|
|
6190
|
+
}
|
|
6191
|
+
}
|
|
6192
|
+
crossRefs.sort(
|
|
6193
|
+
(a, b) => a.source.localeCompare(b.source) || a.target.localeCompare(b.target)
|
|
6194
|
+
);
|
|
6195
|
+
return {
|
|
6196
|
+
cross_refs: crossRefs,
|
|
6197
|
+
flagged_edges: [],
|
|
6198
|
+
warnings: [],
|
|
6199
|
+
patterns: {
|
|
6200
|
+
call_resolution: {
|
|
6201
|
+
resolved_self: resolvedSelf,
|
|
6202
|
+
resolved_import: resolvedImport,
|
|
6203
|
+
ambiguous,
|
|
6204
|
+
dropped,
|
|
6205
|
+
symbols_defined: definers.size
|
|
6206
|
+
}
|
|
6207
|
+
}
|
|
6208
|
+
};
|
|
6209
|
+
}
|
|
6210
|
+
};
|
|
6211
|
+
}
|
|
6212
|
+
});
|
|
6213
|
+
|
|
6044
6214
|
// src/server/graph/core/parser-registry.ts
|
|
6045
6215
|
function isMultiLayerParser(p) {
|
|
6046
6216
|
return "layers" in p && Array.isArray(p.layers);
|
|
@@ -6055,7 +6225,8 @@ function registerBuiltins2(registry, disabled) {
|
|
|
6055
6225
|
apiAnnotationsParser,
|
|
6056
6226
|
urlLiteralScannerParser,
|
|
6057
6227
|
staticRefScannerParser,
|
|
6058
|
-
middlewareGatesParser
|
|
6228
|
+
middlewareGatesParser,
|
|
6229
|
+
callResolverParser
|
|
6059
6230
|
];
|
|
6060
6231
|
for (const parser of builtins) {
|
|
6061
6232
|
if (disabled.has(parser.id)) continue;
|
|
@@ -6106,6 +6277,7 @@ var init_parser_registry = __esm({
|
|
|
6106
6277
|
init_static_values();
|
|
6107
6278
|
init_static_ref_scanner();
|
|
6108
6279
|
init_middleware_gates();
|
|
6280
|
+
init_call_resolver();
|
|
6109
6281
|
ParserRegistry = class {
|
|
6110
6282
|
constructor() {
|
|
6111
6283
|
this.singleLayerParsers = /* @__PURE__ */ new Map();
|
|
@@ -7607,14 +7779,14 @@ Regenerated ${okCount}/${projects.length} project graph(s)${failCount ? ` (${fai
|
|
|
7607
7779
|
}
|
|
7608
7780
|
const graph = readGraph(rootDir, layer);
|
|
7609
7781
|
if (!graph) {
|
|
7610
|
-
console.error(`No ${layer} graph found. Run:
|
|
7782
|
+
console.error(`No ${layer} graph found. Run: launch-sequencer graph:generate${projectArg ? ` --project ${projectArg}` : ""}`);
|
|
7611
7783
|
process.exit(1);
|
|
7612
7784
|
}
|
|
7613
7785
|
console.log(JSON.stringify(graph, null, 2));
|
|
7614
7786
|
} else {
|
|
7615
7787
|
const graphs = readAllGraphs(rootDir);
|
|
7616
7788
|
if (Object.keys(graphs).length === 0) {
|
|
7617
|
-
console.error(`No graphs found. Run:
|
|
7789
|
+
console.error(`No graphs found. Run: launch-sequencer graph:generate${projectArg ? ` --project ${projectArg}` : ""}`);
|
|
7618
7790
|
process.exit(1);
|
|
7619
7791
|
}
|
|
7620
7792
|
console.log(JSON.stringify(graphs, null, 2));
|
|
@@ -9363,6 +9535,10 @@ function handleWhoUses(args) {
|
|
|
9363
9535
|
};
|
|
9364
9536
|
const via = cr.via;
|
|
9365
9537
|
if (Array.isArray(via)) entry.via = via;
|
|
9538
|
+
const definedIn = cr.defined_in;
|
|
9539
|
+
if (typeof definedIn === "string") entry.defined_in = definedIn;
|
|
9540
|
+
const ambiguous = cr.ambiguous;
|
|
9541
|
+
if (ambiguous) entry.ambiguous = true;
|
|
9366
9542
|
hits.push(entry);
|
|
9367
9543
|
}
|
|
9368
9544
|
}
|