@quolu/lattice 0.38.0 → 0.39.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/README.ja.md +22 -16
- package/README.md +11 -7
- package/bin/lattice-mcp.mjs +0 -0
- package/bin/lattice.mjs +1 -1
- package/docs/schemas/lattice.phase_todo_revision.v3.schema.json +49 -1
- package/docs/schemas/lattice.plan_create_input.v4.schema.json +85 -0
- package/docs/schemas/lattice.todo_extraction.v3.schema.json +146 -0
- package/docs/schemas/lattice.todo_revision.v2.schema.json +41 -1
- package/package.json +3 -1
- package/sensor/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/sensor/dist/extraction/tree-sitter.js +68 -16
- package/sensor/dist/extraction/tree-sitter.js.map +1 -1
- package/src/cli-help.mjs +7 -7
- package/src/project-cli.mjs +32 -15
- package/src/seam-cost.mjs +3 -3
- package/src/todo-cli.mjs +360 -218
- package/src/todo-contracts.mjs +46 -8
- package/src/todo-dashboard-registry.mjs +17 -3
- package/src/todo-gantt-html-independence.mjs +14 -3
- package/src/todo-gantt-html-shared.mjs +5 -2
- package/src/todo-gantt-layout.mjs +1 -1
- package/src/todo-gantt-scope.mjs +1 -1
- package/src/todo-migration.mjs +46 -9
- package/src/todo-revision.mjs +10 -8
- package/src/todo-status.mjs +3 -3
- package/src/todo-store.mjs +74 -31
|
@@ -809,9 +809,12 @@ class TreeSitterExtractor {
|
|
|
809
809
|
const left = (0, tree_sitter_helpers_1.getChildByField)(n, 'left') ?? (0, tree_sitter_helpers_1.getChildByField)(n, 'pattern') ?? n.namedChild(0);
|
|
810
810
|
if (left?.type === 'identifier')
|
|
811
811
|
bump(left);
|
|
812
|
-
|
|
812
|
+
// Attribute/subscript assignment mutates an existing binding's
|
|
813
|
+
// value; only destructuring patterns introduce/rebind names.
|
|
814
|
+
else if (left && ['expression_list', 'pattern_list', 'tuple', 'list', 'list_pattern'].includes(left.type)) {
|
|
813
815
|
for (const c of left.namedChildren)
|
|
814
816
|
bump(c);
|
|
817
|
+
}
|
|
815
818
|
break;
|
|
816
819
|
}
|
|
817
820
|
case 'init_declarator': // C `T X = …` (file-scope const AND the local that shadows it)
|
|
@@ -863,30 +866,79 @@ class TreeSitterExtractor {
|
|
|
863
866
|
if (targets.size === 0)
|
|
864
867
|
return;
|
|
865
868
|
}
|
|
866
|
-
// Write detection is wired for
|
|
867
|
-
//
|
|
868
|
-
//
|
|
869
|
-
|
|
870
|
-
|
|
869
|
+
// Write detection is wired for every language that also has a native-kernel
|
|
870
|
+
// value-ref mirror. Languages outside this set keep an absent flag — callers
|
|
871
|
+
// must not interpret absence as read-only.
|
|
872
|
+
const writeAware = [
|
|
873
|
+
'typescript', 'javascript', 'tsx', 'jsx', 'arkts', 'go', 'python', 'java',
|
|
874
|
+
].includes(this.language);
|
|
871
875
|
const isWriteReference = (n) => {
|
|
872
|
-
// Climb the
|
|
876
|
+
// Climb the binding-root path: `cache.x.y = 1` / `cache[k] = 1` mutate
|
|
873
877
|
// the binding's value even though the identifier itself is not re-bound.
|
|
874
878
|
let node = n;
|
|
875
879
|
let parent = node.parent;
|
|
876
|
-
while (parent
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
880
|
+
while (parent) {
|
|
881
|
+
const rootField = (() => {
|
|
882
|
+
if (parent.type === 'member_expression' || parent.type === 'subscript_expression')
|
|
883
|
+
return 'object';
|
|
884
|
+
if (this.language === 'go'
|
|
885
|
+
&& ['selector_expression', 'index_expression', 'slice_expression'].includes(parent.type))
|
|
886
|
+
return 'operand';
|
|
887
|
+
if (this.language === 'python' && parent.type === 'attribute')
|
|
888
|
+
return 'object';
|
|
889
|
+
if (this.language === 'python' && parent.type === 'subscript')
|
|
890
|
+
return 'value';
|
|
891
|
+
if (this.language === 'java' && parent.type === 'field_access')
|
|
892
|
+
return 'object';
|
|
893
|
+
if (this.language === 'java' && parent.type === 'array_access')
|
|
894
|
+
return 'array';
|
|
895
|
+
return null;
|
|
896
|
+
})();
|
|
897
|
+
if (rootField !== null) {
|
|
898
|
+
const root = (0, tree_sitter_helpers_1.getChildByField)(parent, rootField);
|
|
899
|
+
if (!root || root.startIndex !== node.startIndex || root.endIndex !== node.endIndex)
|
|
900
|
+
break;
|
|
901
|
+
node = parent;
|
|
902
|
+
parent = node.parent;
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
// Go's assignment LHS is wrapped in an expression_list.
|
|
906
|
+
if (this.language === 'go' && parent.type === 'expression_list') {
|
|
907
|
+
node = parent;
|
|
908
|
+
parent = node.parent;
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
break;
|
|
882
912
|
}
|
|
883
913
|
if (!parent)
|
|
884
914
|
return false;
|
|
885
|
-
|
|
886
|
-
const left = (0, tree_sitter_helpers_1.getChildByField)(
|
|
915
|
+
const isLeft = (owner, fields) => fields.some((field) => {
|
|
916
|
+
const left = (0, tree_sitter_helpers_1.getChildByField)(owner, field);
|
|
887
917
|
return left !== null && left.startIndex === node.startIndex && left.endIndex === node.endIndex;
|
|
918
|
+
});
|
|
919
|
+
if (['typescript', 'javascript', 'tsx', 'jsx', 'arkts'].includes(this.language)) {
|
|
920
|
+
if (parent.type === 'assignment_expression' || parent.type === 'augmented_assignment_expression') {
|
|
921
|
+
return isLeft(parent, ['left']);
|
|
922
|
+
}
|
|
923
|
+
return parent.type === 'update_expression';
|
|
888
924
|
}
|
|
889
|
-
|
|
925
|
+
if (this.language === 'go') {
|
|
926
|
+
if (parent.type === 'assignment_statement')
|
|
927
|
+
return isLeft(parent, ['left']);
|
|
928
|
+
return parent.type === 'inc_statement' || parent.type === 'dec_statement';
|
|
929
|
+
}
|
|
930
|
+
if (this.language === 'python') {
|
|
931
|
+
if (parent.type === 'assignment' || parent.type === 'augmented_assignment') {
|
|
932
|
+
return isLeft(parent, ['left']);
|
|
933
|
+
}
|
|
934
|
+
return parent.type === 'named_expression' && isLeft(parent, ['name', 'left']);
|
|
935
|
+
}
|
|
936
|
+
if (this.language === 'java') {
|
|
937
|
+
if (parent.type === 'assignment_expression')
|
|
938
|
+
return isLeft(parent, ['left']);
|
|
939
|
+
return parent.type === 'update_expression';
|
|
940
|
+
}
|
|
941
|
+
return false;
|
|
890
942
|
};
|
|
891
943
|
for (const scope of scopes) {
|
|
892
944
|
const seen = new Map();
|