@ossiq/cli-darwin-x64 0.1.13 → 0.1.14

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 (53) hide show
  1. package/bin/ossiq/_internal/base_library.zip +0 -0
  2. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/METADATA +554 -0
  3. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/RECORD +40 -0
  4. package/bin/ossiq/_internal/{semantic_version-2.10.0.dist-info → keyring-25.7.0.dist-info}/WHEEL +1 -2
  5. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/entry_points.txt +13 -0
  6. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/licenses/LICENSE +18 -0
  7. package/bin/ossiq/_internal/keyring-25.7.0.dist-info/top_level.txt +1 -0
  8. package/bin/ossiq/_internal/lark/grammars/common.lark +59 -0
  9. package/bin/ossiq/_internal/lark/grammars/lark.lark +62 -0
  10. package/bin/ossiq/_internal/lark/grammars/python.lark +302 -0
  11. package/bin/ossiq/_internal/lark/grammars/unicode.lark +7 -0
  12. package/bin/ossiq/_internal/ossiq/data/SKILL.md +42 -16
  13. package/bin/ossiq/_internal/ossiq/domain/README.md +30 -4
  14. package/bin/ossiq/_internal/ossiq/solver/README.md +10 -3
  15. package/bin/ossiq/_internal/ossiq/strategy/README.md +20 -2
  16. package/bin/ossiq/_internal/ossiq/ui/html_templates/spa_app.html +1828 -1518
  17. package/bin/ossiq/_internal/ossiq/ui/renderers/export/README.md +103 -40
  18. package/bin/ossiq/_internal/ossiq/ui/renderers/export/schemas/export_schema_v1.6.json +1805 -0
  19. package/bin/ossiq/_internal/ossiq/ui/renderers/export/schemas/export_schema_v1.6_standard.json +1328 -0
  20. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/METADATA +207 -0
  21. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/RECORD +13 -0
  22. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/REQUESTED +0 -0
  23. package/bin/ossiq/_internal/ossiq-0.1.14.dist-info/uv_cache.json +1 -0
  24. package/bin/ossiq/_internal/pycard.cpython-313-darwin.so +0 -0
  25. package/bin/ossiq/_internal/pyformula.cpython-313-darwin.so +0 -0
  26. package/bin/ossiq/_internal/pysolvers.cpython-313-darwin.so +0 -0
  27. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/INSTALLER +1 -0
  28. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/METADATA +133 -0
  29. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/RECORD +21 -0
  30. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/REQUESTED +0 -0
  31. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/WHEEL +5 -0
  32. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/licenses/LICENSE +73 -0
  33. package/bin/ossiq/_internal/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/top_level.txt +1 -0
  34. package/bin/ossiq/ossiq +0 -0
  35. package/package.json +1 -1
  36. package/bin/ossiq/_internal/ossiq-0.1.13.dist-info/METADATA +0 -385
  37. package/bin/ossiq/_internal/ossiq-0.1.13.dist-info/RECORD +0 -13
  38. package/bin/ossiq/_internal/ossiq-0.1.13.dist-info/uv_cache.json +0 -1
  39. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/LICENSE +0 -22
  40. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/METADATA +0 -324
  41. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/RECORD +0 -10
  42. package/bin/ossiq/_internal/semantic_version-2.10.0.dist-info/top_level.txt +0 -1
  43. package/bin/ossiq/_internal/wcwidth/textwrap.py,cover +0 -664
  44. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → keyring-25.7.0.dist-info}/INSTALLER +0 -0
  45. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → keyring-25.7.0.dist-info}/REQUESTED +0 -0
  46. /package/bin/ossiq/_internal/{semantic_version-2.10.0.dist-info/REQUESTED → lark/py.typed} +0 -0
  47. /package/bin/ossiq/_internal/{semantic_version-2.10.0.dist-info → ossiq-0.1.14.dist-info}/INSTALLER +0 -0
  48. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → ossiq-0.1.14.dist-info}/WHEEL +0 -0
  49. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → ossiq-0.1.14.dist-info}/direct_url.json +0 -0
  50. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → ossiq-0.1.14.dist-info}/entry_points.txt +0 -0
  51. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → ossiq-0.1.14.dist-info}/licenses/AUTHORS +0 -0
  52. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → ossiq-0.1.14.dist-info}/licenses/LICENSE +0 -0
  53. /package/bin/ossiq/_internal/{ossiq-0.1.13.dist-info → ossiq-0.1.14.dist-info}/uv_build.json +0 -0
@@ -0,0 +1,59 @@
1
+ // Basic terminals for common use
2
+
3
+
4
+ //
5
+ // Numbers
6
+ //
7
+
8
+ DIGIT: "0".."9"
9
+ HEXDIGIT: "a".."f"|"A".."F"|DIGIT
10
+
11
+ INT: DIGIT+
12
+ SIGNED_INT: ["+"|"-"] INT
13
+ DECIMAL: INT "." INT? | "." INT
14
+
15
+ // float = /-?\d+(\.\d+)?([eE][+-]?\d+)?/
16
+ _EXP: ("e"|"E") SIGNED_INT
17
+ FLOAT: INT _EXP | DECIMAL _EXP?
18
+ SIGNED_FLOAT: ["+"|"-"] FLOAT
19
+
20
+ NUMBER: FLOAT | INT
21
+ SIGNED_NUMBER: ["+"|"-"] NUMBER
22
+
23
+ //
24
+ // Strings
25
+ //
26
+ _STRING_INNER: /.*?/
27
+ _STRING_ESC_INNER: _STRING_INNER /(?<!\\)(\\\\)*?/
28
+
29
+ ESCAPED_STRING : "\"" _STRING_ESC_INNER "\""
30
+
31
+
32
+ //
33
+ // Names (Variables)
34
+ //
35
+ LCASE_LETTER: "a".."z"
36
+ UCASE_LETTER: "A".."Z"
37
+
38
+ LETTER: UCASE_LETTER | LCASE_LETTER
39
+ WORD: LETTER+
40
+
41
+ CNAME: ("_"|LETTER) ("_"|LETTER|DIGIT)*
42
+
43
+
44
+ //
45
+ // Whitespace
46
+ //
47
+ WS_INLINE: (" "|/\t/)+
48
+ WS: /[ \t\f\r\n]/+
49
+
50
+ CR : /\r/
51
+ LF : /\n/
52
+ NEWLINE: (CR? LF)+
53
+
54
+
55
+ // Comments
56
+ SH_COMMENT: /#[^\n]*/
57
+ CPP_COMMENT: /\/\/[^\n]*/
58
+ C_COMMENT: "/*" /(.|\n)*?/ "*/"
59
+ SQL_COMMENT: /--[^\n]*/
@@ -0,0 +1,62 @@
1
+ # Lark grammar of Lark's syntax
2
+ # Note: Lark is not bootstrapped, its parser is implemented in load_grammar.py
3
+
4
+ start: (_item? _NL)* _item?
5
+
6
+ _item: rule
7
+ | token
8
+ | statement
9
+
10
+ rule: RULE rule_params priority? ":" expansions
11
+ token: TOKEN token_params priority? ":" expansions
12
+
13
+ rule_params: ["{" RULE ("," RULE)* "}"]
14
+ token_params: ["{" TOKEN ("," TOKEN)* "}"]
15
+
16
+ priority: "." NUMBER
17
+
18
+ statement: "%ignore" expansions -> ignore
19
+ | "%import" import_path ["->" name] -> import
20
+ | "%import" import_path name_list -> multi_import
21
+ | "%override" rule -> override_rule
22
+ | "%declare" name+ -> declare
23
+
24
+ !import_path: "."? name ("." name)*
25
+ name_list: "(" name ("," name)* ")"
26
+
27
+ ?expansions: alias (_VBAR alias)*
28
+
29
+ ?alias: expansion ["->" RULE]
30
+
31
+ ?expansion: expr*
32
+
33
+ ?expr: atom [OP | "~" NUMBER [".." NUMBER]]
34
+
35
+ ?atom: "(" expansions ")"
36
+ | "[" expansions "]" -> maybe
37
+ | value
38
+
39
+ ?value: STRING ".." STRING -> literal_range
40
+ | name
41
+ | (REGEXP | STRING) -> literal
42
+ | name "{" value ("," value)* "}" -> template_usage
43
+
44
+ name: RULE
45
+ | TOKEN
46
+
47
+ _VBAR: _NL? "|"
48
+ OP: /[+*]|[?](?![a-z])/
49
+ RULE: /!?[_?]?[a-z][_a-z0-9]*/
50
+ TOKEN: /_?[A-Z][_A-Z0-9]*/
51
+ STRING: _STRING "i"?
52
+ REGEXP: /\/(?!\/)(\\\/|\\\\|[^\/])*?\/[imslux]*/
53
+ _NL: /(\r?\n)+\s*/
54
+
55
+ %import common.ESCAPED_STRING -> _STRING
56
+ %import common.SIGNED_INT -> NUMBER
57
+ %import common.WS_INLINE
58
+
59
+ COMMENT: /\s*/ "//" /[^\n]/* | /\s*/ "#" /[^\n]/*
60
+
61
+ %ignore WS_INLINE
62
+ %ignore COMMENT
@@ -0,0 +1,302 @@
1
+ // Python 3 grammar for Lark
2
+
3
+ // This grammar should parse all python 3.x code successfully.
4
+
5
+ // Adapted from: https://docs.python.org/3/reference/grammar.html
6
+
7
+ // Start symbols for the grammar:
8
+ // single_input is a single interactive statement;
9
+ // file_input is a module or sequence of commands read from an input file;
10
+ // eval_input is the input for the eval() functions.
11
+ // NB: compound_stmt in single_input is followed by extra NEWLINE!
12
+ //
13
+
14
+ single_input: _NEWLINE | simple_stmt | compound_stmt _NEWLINE
15
+ file_input: (_NEWLINE | stmt)*
16
+ eval_input: testlist _NEWLINE*
17
+
18
+ decorator: "@" dotted_name [ "(" [arguments] ")" ] _NEWLINE
19
+ decorators: decorator+
20
+ decorated: decorators (classdef | funcdef | async_funcdef)
21
+
22
+ async_funcdef: "async" funcdef
23
+ funcdef: "def" name "(" [parameters] ")" ["->" test] ":" suite
24
+
25
+ parameters: paramvalue ("," paramvalue)* ["," SLASH ("," paramvalue)*] ["," [starparams | kwparams]]
26
+ | starparams
27
+ | kwparams
28
+
29
+ SLASH: "/" // Otherwise the it will completely disappear and it will be undisguisable in the result
30
+ starparams: (starparam | starguard) poststarparams
31
+ starparam: "*" typedparam
32
+ starguard: "*"
33
+ poststarparams: ("," paramvalue)* ["," kwparams]
34
+ kwparams: "**" typedparam ","?
35
+
36
+ ?paramvalue: typedparam ("=" test)?
37
+ ?typedparam: name (":" test)?
38
+
39
+
40
+ lambdef: "lambda" [lambda_params] ":" test
41
+ lambdef_nocond: "lambda" [lambda_params] ":" test_nocond
42
+ lambda_params: lambda_paramvalue ("," lambda_paramvalue)* ["," [lambda_starparams | lambda_kwparams]]
43
+ | lambda_starparams
44
+ | lambda_kwparams
45
+ ?lambda_paramvalue: name ("=" test)?
46
+ lambda_starparams: "*" [name] ("," lambda_paramvalue)* ["," [lambda_kwparams]]
47
+ lambda_kwparams: "**" name ","?
48
+
49
+
50
+ ?stmt: simple_stmt | compound_stmt
51
+ ?simple_stmt: small_stmt (";" small_stmt)* [";"] _NEWLINE
52
+ ?small_stmt: (expr_stmt | assign_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
53
+ expr_stmt: testlist_star_expr
54
+ assign_stmt: annassign | augassign | assign
55
+
56
+ annassign: testlist_star_expr ":" test ["=" test]
57
+ assign: testlist_star_expr ("=" (yield_expr|testlist_star_expr))+
58
+ augassign: testlist_star_expr augassign_op (yield_expr|testlist)
59
+ !augassign_op: "+=" | "-=" | "*=" | "@=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "**=" | "//="
60
+ ?testlist_star_expr: test_or_star_expr
61
+ | test_or_star_expr ("," test_or_star_expr)+ ","? -> tuple
62
+ | test_or_star_expr "," -> tuple
63
+
64
+ // For normal and annotated assignments, additional restrictions enforced by the interpreter
65
+ del_stmt: "del" exprlist
66
+ pass_stmt: "pass"
67
+ ?flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
68
+ break_stmt: "break"
69
+ continue_stmt: "continue"
70
+ return_stmt: "return" [testlist]
71
+ yield_stmt: yield_expr
72
+ raise_stmt: "raise" [test ["from" test]]
73
+ import_stmt: import_name | import_from
74
+ import_name: "import" dotted_as_names
75
+ // note below: the ("." | "...") is necessary because "..." is tokenized as ELLIPSIS
76
+ import_from: "from" (dots? dotted_name | dots) "import" ("*" | "(" import_as_names ")" | import_as_names)
77
+ !dots: "."+
78
+ import_as_name: name ["as" name]
79
+ dotted_as_name: dotted_name ["as" name]
80
+ import_as_names: import_as_name ("," import_as_name)* [","]
81
+ dotted_as_names: dotted_as_name ("," dotted_as_name)*
82
+ dotted_name: name ("." name)*
83
+ global_stmt: "global" name ("," name)*
84
+ nonlocal_stmt: "nonlocal" name ("," name)*
85
+ assert_stmt: "assert" test ["," test]
86
+
87
+ ?compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | match_stmt
88
+ | with_stmt | funcdef | classdef | decorated | async_stmt
89
+ async_stmt: "async" (funcdef | with_stmt | for_stmt)
90
+ if_stmt: "if" test ":" suite elifs ["else" ":" suite]
91
+ elifs: elif_*
92
+ elif_: "elif" test ":" suite
93
+ while_stmt: "while" test ":" suite ["else" ":" suite]
94
+ for_stmt: "for" exprlist "in" testlist ":" suite ["else" ":" suite]
95
+ try_stmt: "try" ":" suite except_clauses ["else" ":" suite] [finally]
96
+ | "try" ":" suite finally -> try_finally
97
+ finally: "finally" ":" suite
98
+ except_clauses: except_clause+
99
+ except_clause: "except" [test ["as" name]] ":" suite
100
+ // NB compile.c makes sure that the default except clause is last
101
+
102
+
103
+ with_stmt: "with" with_items ":" suite
104
+ with_items: with_item ("," with_item)*
105
+ with_item: test ["as" name]
106
+
107
+ match_stmt: "match" test ":" _NEWLINE _INDENT case+ _DEDENT
108
+
109
+ case: "case" pattern ["if" test] ":" suite
110
+
111
+ ?pattern: sequence_item_pattern "," _sequence_pattern -> sequence_pattern
112
+ | as_pattern
113
+ ?as_pattern: or_pattern ("as" NAME)?
114
+ ?or_pattern: closed_pattern ("|" closed_pattern)*
115
+ ?closed_pattern: literal_pattern
116
+ | NAME -> capture_pattern
117
+ | "_" -> any_pattern
118
+ | attr_pattern
119
+ | "(" as_pattern ")"
120
+ | "[" _sequence_pattern "]" -> sequence_pattern
121
+ | "(" (sequence_item_pattern "," _sequence_pattern)? ")" -> sequence_pattern
122
+ | "{" (mapping_item_pattern ("," mapping_item_pattern)* ","?)?"}" -> mapping_pattern
123
+ | "{" (mapping_item_pattern ("," mapping_item_pattern)* ",")? "**" NAME ","? "}" -> mapping_star_pattern
124
+ | class_pattern
125
+
126
+ literal_pattern: inner_literal_pattern
127
+
128
+ ?inner_literal_pattern: "None" -> const_none
129
+ | "True" -> const_true
130
+ | "False" -> const_false
131
+ | STRING -> string
132
+ | number
133
+
134
+ attr_pattern: NAME ("." NAME)+ -> value
135
+
136
+ name_or_attr_pattern: NAME ("." NAME)* -> value
137
+
138
+ mapping_item_pattern: (literal_pattern|attr_pattern) ":" as_pattern
139
+
140
+ _sequence_pattern: (sequence_item_pattern ("," sequence_item_pattern)* ","?)?
141
+ ?sequence_item_pattern: as_pattern
142
+ | "*" NAME -> star_pattern
143
+
144
+ class_pattern: name_or_attr_pattern "(" [arguments_pattern ","?] ")"
145
+ arguments_pattern: pos_arg_pattern ["," keyws_arg_pattern]
146
+ | keyws_arg_pattern -> no_pos_arguments
147
+
148
+ pos_arg_pattern: as_pattern ("," as_pattern)*
149
+ keyws_arg_pattern: keyw_arg_pattern ("," keyw_arg_pattern)*
150
+ keyw_arg_pattern: NAME "=" as_pattern
151
+
152
+
153
+
154
+ suite: simple_stmt | _NEWLINE _INDENT stmt+ _DEDENT
155
+
156
+ ?test: or_test ("if" or_test "else" test)?
157
+ | lambdef
158
+ | assign_expr
159
+
160
+ assign_expr: name ":=" test
161
+
162
+ ?test_nocond: or_test | lambdef_nocond
163
+
164
+ ?or_test: and_test ("or" and_test)*
165
+ ?and_test: not_test_ ("and" not_test_)*
166
+ ?not_test_: "not" not_test_ -> not_test
167
+ | comparison
168
+ ?comparison: expr (comp_op expr)*
169
+ star_expr: "*" expr
170
+
171
+ ?expr: or_expr
172
+ ?or_expr: xor_expr ("|" xor_expr)*
173
+ ?xor_expr: and_expr ("^" and_expr)*
174
+ ?and_expr: shift_expr ("&" shift_expr)*
175
+ ?shift_expr: arith_expr (_shift_op arith_expr)*
176
+ ?arith_expr: term (_add_op term)*
177
+ ?term: factor (_mul_op factor)*
178
+ ?factor: _unary_op factor | power
179
+
180
+ !_unary_op: "+"|"-"|"~"
181
+ !_add_op: "+"|"-"
182
+ !_shift_op: "<<"|">>"
183
+ !_mul_op: "*"|"@"|"/"|"%"|"//"
184
+ // <> isn't actually a valid comparison operator in Python. It's here for the
185
+ // sake of a __future__ import described in PEP 401 (which really works :-)
186
+ !comp_op: "<"|">"|"=="|">="|"<="|"<>"|"!="|"in"|"not" "in"|"is"|"is" "not"
187
+
188
+ ?power: await_expr ("**" factor)?
189
+ ?await_expr: AWAIT? atom_expr
190
+ AWAIT: "await"
191
+
192
+ ?atom_expr: atom_expr "(" [arguments] ")" -> funccall
193
+ | atom_expr "[" subscriptlist "]" -> getitem
194
+ | atom_expr "." name -> getattr
195
+ | atom
196
+
197
+ ?atom: "(" yield_expr ")"
198
+ | "(" _tuple_inner? ")" -> tuple
199
+ | "(" comprehension{test_or_star_expr} ")" -> tuple_comprehension
200
+ | "[" _exprlist? "]" -> list
201
+ | "[" comprehension{test_or_star_expr} "]" -> list_comprehension
202
+ | "{" _dict_exprlist? "}" -> dict
203
+ | "{" comprehension{key_value} "}" -> dict_comprehension
204
+ | "{" _exprlist "}" -> set
205
+ | "{" comprehension{test} "}" -> set_comprehension
206
+ | name -> var
207
+ | number
208
+ | string_concat
209
+ | "(" test ")"
210
+ | "..." -> ellipsis
211
+ | "None" -> const_none
212
+ | "True" -> const_true
213
+ | "False" -> const_false
214
+
215
+
216
+ ?string_concat: string+
217
+
218
+ _tuple_inner: test_or_star_expr (("," test_or_star_expr)+ [","] | ",")
219
+
220
+ ?test_or_star_expr: test
221
+ | star_expr
222
+
223
+ ?subscriptlist: subscript
224
+ | subscript (("," subscript)+ [","] | ",") -> subscript_tuple
225
+ ?subscript: test | ([test] ":" [test] [sliceop]) -> slice
226
+ sliceop: ":" [test]
227
+ ?exprlist: (expr|star_expr)
228
+ | (expr|star_expr) (("," (expr|star_expr))+ [","]|",")
229
+ ?testlist: test | testlist_tuple
230
+ testlist_tuple: test (("," test)+ [","] | ",")
231
+ _dict_exprlist: (key_value | "**" expr) ("," (key_value | "**" expr))* [","]
232
+
233
+ key_value: test ":" test
234
+
235
+ _exprlist: test_or_star_expr ("," test_or_star_expr)* [","]
236
+
237
+ classdef: "class" name ["(" [arguments] ")"] ":" suite
238
+
239
+
240
+
241
+ arguments: argvalue ("," argvalue)* ("," [ starargs | kwargs])?
242
+ | starargs
243
+ | kwargs
244
+ | comprehension{test}
245
+
246
+ starargs: stararg ("," stararg)* ("," argvalue)* ["," kwargs]
247
+ stararg: "*" test
248
+ kwargs: "**" test ("," argvalue)*
249
+
250
+ ?argvalue: test ("=" test)?
251
+
252
+
253
+ comprehension{comp_result}: comp_result comp_fors [comp_if]
254
+ comp_fors: comp_for+
255
+ comp_for: [ASYNC] "for" exprlist "in" or_test
256
+ ASYNC: "async"
257
+ ?comp_if: "if" test_nocond
258
+
259
+ // not used in grammar, but may appear in "node" passed from Parser to Compiler
260
+ encoding_decl: name
261
+
262
+ yield_expr: "yield" [testlist]
263
+ | "yield" "from" test -> yield_from
264
+
265
+ number: DEC_NUMBER | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER | IMAG_NUMBER
266
+ string: STRING | LONG_STRING
267
+
268
+ // Other terminals
269
+
270
+ _NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+
271
+
272
+ %ignore /[\t \f]+/ // WS
273
+ %ignore /\\[\t \f]*\r?\n/ // LINE_CONT
274
+ %ignore COMMENT
275
+ %declare _INDENT _DEDENT
276
+
277
+
278
+ // Python terminals
279
+
280
+ !name: NAME | "match" | "case"
281
+ NAME: /[^\W\d]\w*/
282
+ COMMENT: /#[^\n]*/
283
+
284
+ STRING: /([ubf]?r?|r[ubf])("(?!"").*?(?<!\\)(\\\\)*?"|'(?!'').*?(?<!\\)(\\\\)*?')/i
285
+ LONG_STRING: /([ubf]?r?|r[ubf])(""".*?(?<!\\)(\\\\)*?"""|'''.*?(?<!\\)(\\\\)*?''')/is
286
+
287
+ _SPECIAL_DEC: "0".."9" ("_"? "0".."9" )*
288
+ DEC_NUMBER: "1".."9" ("_"? "0".."9" )*
289
+ | "0" ("_"? "0" )* /(?![1-9])/
290
+ HEX_NUMBER.2: "0" ("x" | "X") ("_"? ("0".."9" | "a".."f" | "A".."F"))+
291
+ OCT_NUMBER.2: "0" ("o" | "O") ("_"? "0".."7" )+
292
+ BIN_NUMBER.2: "0" ("b" | "B") ("_"? "0".."1" )+
293
+
294
+ _EXP: ("e"|"E") ["+" | "-"] _SPECIAL_DEC
295
+ DECIMAL: "." _SPECIAL_DEC | _SPECIAL_DEC "." _SPECIAL_DEC?
296
+ FLOAT_NUMBER.2: _SPECIAL_DEC _EXP | DECIMAL _EXP?
297
+ IMAG_NUMBER.2: (_SPECIAL_DEC | FLOAT_NUMBER) ("J" | "j")
298
+
299
+
300
+ // Comma-separated list (with an optional trailing comma)
301
+ cs_list{item}: item ("," item)* ","?
302
+ _cs_list{item}: item ("," item)* ","?
@@ -0,0 +1,7 @@
1
+ // TODO: LETTER, WORD, etc.
2
+
3
+ //
4
+ // Whitespace
5
+ //
6
+ WS_INLINE: /[ \t\xa0]/+
7
+ WS: /[ \t\xa0\f\r\n]/+
@@ -13,9 +13,15 @@ description: >-
13
13
  OSS IQ is a **local CLI tool** — it runs entirely on your machine and does not
14
14
  send any project data to external services. All analysis is performed locally.
15
15
 
16
- Run via `uvx ossiq` (no install needed, works from any directory) or bare `ossiq` if already installed.
16
+ Run OSS IQ as `{{ossiq}}`, exactly as the commands below spell it; it works from any directory.
17
17
 
18
- **GitHub rate limits:** Without a token, GitHub's API allows 60 req/hr. If you hit rate limits, the user should run `ossiq install skills <tool> --github-token <token>` once to store the token in `~/.ossiq/config` (classic PAT, no scopes needed for public repos raises the limit to 5 000 req/hr). Do not ask the user to pass it manually on every command.
18
+ **GitHub rate limits:** Without a login, GitHub's API allows 60 req/hr; logged in it allows 5 000. If you hit rate limits, or OSS IQ prints a GitHub login code, log in with a one-time code. Never ask the user for a token or put one on a command line.
19
+
20
+ 1. Run `{{ossiq}} auth login --no-wait`. It prints a URL and a code and exits with status 75, which means "waiting for approval", not failure.
21
+ 2. Show the URL and code to the user exactly as printed, and wait until they say they approved it on GitHub.
22
+ 3. Run `{{ossiq}} auth login --resume`. Exit 0 means logged in; 75 again means it is not approved yet. A code expires after about 15 minutes: go back to step 1 for a new one.
23
+
24
+ Through the MCP server, a tool result with `auth_status: PENDING_USER_ACTION` carries the same URL and code. Relay them, wait for the user, then call the same tool again. The login is kept in the system keyring (`{{ossiq}} auth status` shows it, `{{ossiq}} auth logout` removes it). Without a keyring, or in CI, set `OSSIQ_GITHUB_TOKEN` in the environment instead.
19
25
 
20
26
  OSS IQ scores dependency health: drift, CVEs, maintainer/bus-factor risk,
21
27
  typosquat signals, and a solver-recommended version. Run it **before** you
@@ -23,9 +29,9 @@ change a project's dependencies and do what the `next_action` says.
23
29
 
24
30
  Either call the CLI (below) or, if an MCP server named `ossiq` is connected, call
25
31
  the equivalent tools `ossiq_evaluate_dependency` / `ossiq_evaluate_updates`. Prefer these (or
26
- `--format agent`). If you need a file to hand over instead, `ossiq export` writes the standard
32
+ `--format agent`). If you need a file to hand over instead, `{{ossiq}} export` writes the standard
27
33
  profile - every direct dependency, the transitives that need attention, decision fields only.
28
- `ossiq export --full` adds every transitive, the dependency tree and raw upstream signals; it is for
34
+ `{{ossiq}} export --full` adds every transitive, the dependency tree and raw upstream signals; it is for
29
35
  dashboards and archives and several times larger, so don't feed it to an agent.
30
36
 
31
37
  ## Tell OSS IQ which runtime the project runs on
@@ -51,7 +57,7 @@ The runtime you state is still held to the project's declared floor (`engines.no
51
57
  Before introducing a package, run:
52
58
 
53
59
  ```bash
54
- uvx ossiq info <package> <project_path> --format agent
60
+ {{ossiq}} info <package> <project_path> --format agent
55
61
  ```
56
62
 
57
63
  Example output:
@@ -76,18 +82,22 @@ installed in the project (not a prospective add) — see the version ladder belo
76
82
 
77
83
  `next_action` for an add is `install`, `install with caution`, or `do not install`.
78
84
 
85
+ `do not install` includes a package its registry deprecated, archived or quarantined, and a
86
+ deprecated release requested by `version`. `reasons` quotes the registry's own note, which
87
+ usually names the replacement: look for that alternative instead of forcing the install.
88
+
79
89
  ## When updating existing dependencies
80
90
 
81
91
  Before bumping versions, run:
82
92
 
83
93
  ```bash
84
- uvx ossiq status <project_path> --format agent
94
+ {{ossiq}} status <project_path> --format agent
85
95
  ```
86
96
 
87
97
  By default this targets the `standard` tier of the update pyramid (plain drift, inside each
88
98
  package's declared range). Pass `--update-strategy security` for the smallest diff that clears
89
99
  known CVEs, or `latest`/`cutting-edge` to also widen constraints / admit prereleases — see
90
- `ossiq status --help`. The MCP tool `ossiq_evaluate_updates` takes the same `update_strategy`
100
+ `{{ossiq}} status --help`. The MCP tool `ossiq_evaluate_updates` takes the same `update_strategy`
91
101
  argument.
92
102
 
93
103
  Example output:
@@ -130,17 +140,21 @@ Example output:
130
140
  ```
131
141
 
132
142
  The top-level `next_action` is the most urgent one across the `updates` list, or
133
- `no action needed` when the list is empty. Each entry's `next_action` is one of:
143
+ `no action needed` when no entry has an action due. Each entry's `next_action` is one of:
134
144
 
135
145
  - **Check for the Fix** — a known CVE that `to` does not clear (or there is no `to`); check for a
136
146
  patched release.
137
- - **Find alternative** — the package is gone or its upstream is abandoned/deprecated; migrate off it.
147
+ - **Find alternative** — the package is gone, its registry deprecated, archived or quarantined it,
148
+ or its upstream is abandoned/deprecated; migrate off it. A newer release of such a package does
149
+ not help.
138
150
  - **Consider alternative** — the upstream is winding down; plan a migration.
139
151
  - **Check Release Notes** — a major version behind; review breaking changes before the bump.
140
- - **Update Immediately** — a minor/patch behind, or a recommended version exists; bump it.
152
+ - **Update Immediately** — a minor/patch behind, or a recommended version exists; bump it. An
153
+ entry that also carries `requires_constraint_widening: true` reads this way when `apply` writes
154
+ the wider range itself, after a confirmation.
141
155
  - **Constrained. Check newer version** — a minor/patch behind, but the declared range
142
- (e.g. `~7.3.0`) admits no newer version, or the CVE fix in `to` needs it widened; widening the
143
- range is the real next step.
156
+ (e.g. `~7.3.0`) admits no newer version, or the CVE fix in `to` needs it widened and `apply`
157
+ would not widen it on its own; widening the range is the real next step.
144
158
  - **Withheld by strategy** — a minor/patch behind, and the range admits a bump, but the run's
145
159
  `--update-strategy` tier admitted no motive to take it. Nothing is wrong with the package;
146
160
  `strategy_withheld_reason` names the lowest tier that would move it.
@@ -165,6 +179,15 @@ than its registry name — npm aliases (`"uuid-v7": "npm:uuid@^7.0.0"`) are the
165
179
  Two aliases of one package produce two entries sharing `"package"`, so `dependency_name` is what
166
180
  tells you which declaration an entry answers for and which line to edit.
167
181
 
182
+ `unresolved_peers` appears (npm only) when the package declares a peer that nothing within its
183
+ reach can satisfy, so the package may fail to load. It appears whatever the entry's `next_action`
184
+ says, `no action needed` included. Each item gives the peer's `package` and `spec`, whether it is
185
+ `optional`, and `installed_elsewhere`: the versions installed out of reach, empty when the peer is
186
+ installed nowhere. When a copy that satisfies `spec` is installed elsewhere, the top-level
187
+ `peer_repairs` lists what `{{ossiq}} apply` adds to the manifest to fix it. Don't read
188
+ `no action needed` as clean for such a package: run `{{ossiq}} plan` to review the repair, then
189
+ `{{ossiq}} apply`.
190
+
168
191
  ### Module-system and API breaks
169
192
 
170
193
  A recommended version is not always drop-in. Semver alone can't see an npm package going
@@ -212,8 +235,11 @@ choice (avoids known-CVE and too-fresh versions) — **unless the entry also car
212
235
  `"requires_constraint_widening": true`**. That flag means `to` is only reachable by
213
236
  widening the manifest's declared range first (`==1.10.13` admits nothing past
214
237
  1.10.13, so `1.10.26` needs a wider specifier, not just a straight rewrite of the
215
- pin). `ossiq update`/`ossiq apply` will not write such an entry on their own —
216
- widen the constraint by hand, then re-run the command.
238
+ pin). `latest` and `cutting-edge` write such picks after a confirmation prompt. At the other
239
+ tiers `{{ossiq}} update`/`{{ossiq}} apply` will not write one on their own — widen the
240
+ constraint by hand, then re-run the command — unless the entry also carries
241
+ `"widening_authorized": true`. That means a CVE or end-of-life motive carried the pick past
242
+ the tier, so they write it after the same prompt.
217
243
 
218
244
  ### Engine/runtime compatibility
219
245
 
@@ -247,11 +273,11 @@ version it was checked against instead of leaving it a silent runtime failure.
247
273
  ## Before applying an update to a specific version
248
274
 
249
275
  `to` above is OSS IQ's own recommendation. If you (or the user) want to go to a *different*
250
- version — one `ossiq status`/`ossiq_evaluate_updates` didn't propose — check it first instead of
276
+ version — one `{{ossiq}} status`/`ossiq_evaluate_updates` didn't propose — check it first instead of
251
277
  discovering a break via test failure:
252
278
 
253
279
  ```bash
254
- uvx ossiq update-context <package> <project_path> --to <version>
280
+ {{ossiq}} update-context <package> <project_path> --to <version>
255
281
  ```
256
282
 
257
283
  or, over MCP, `ossiq_update_context` with `{"package": ..., "target_version": ..., "runtime": ...}`. `target_version`
@@ -12,7 +12,9 @@ This document lists the external specifications that define or inform the domain
12
12
 
13
13
  | Field | Registry | Meaning |
14
14
  |-------|----------|---------|
15
- | `is_deprecated: bool` | npm | The package's latest version carries a `deprecated` field — the whole package is considered deprecated. Set via `npm deprecate <pkg>`. |
15
+ | `registry_status: RegistryStatus \| None` | npm / PyPI | The registry's verdict on the whole package, in PEP 792's vocabulary: `active`, `deprecated`, `archived`, `quarantined`. npm: `deprecated` when `versions[latest].deprecated` is set (via `npm deprecate <pkg>`), else `active`. PyPI: the Simple API's project status. `None` when the registry gave none, which is not `active`. |
16
+ | `is_deprecated: bool` | npm / PyPI | Read-only, derived from `registry_status`: true for `deprecated` and `archived`. `quarantined` is an administrator's safety verdict, not a maintainer's decision, so it does not count. |
17
+ | `deprecation_message: str \| None` | npm / PyPI | npm's `deprecated` note on the latest version, or PyPI's PEP 792 reason. |
16
18
  | `is_unpublished: bool` | npm | `time.unpublished` is present in the packument — the entire package was removed from the registry. |
17
19
  | `canonical_name: str \| None` | npm | When a package is installed under an npm alias (e.g. `"chalk-legacy": "npm:chalk@4"`), `name` is the alias and `canonical_name` is the real registry name used for lookups. `None` when `name` already is the canonical registry name. |
18
20
 
@@ -20,7 +22,8 @@ This document lists the external specifications that define or inform the domain
20
22
 
21
23
  | Field | Registry | Meaning |
22
24
  |-------|----------|---------|
23
- | `is_deprecated: bool` | npm | This specific version's manifest has a truthy `deprecated` field. |
25
+ | `is_deprecated: bool` | npm | This specific version's manifest has a truthy `deprecated` field. PyPI has no per-release deprecation; a yanked release is its equivalent. |
26
+ | `deprecation_message: str \| None` | npm | The `deprecated` note on this version. |
24
27
  | `is_yanked: bool` | PyPI | The version exists on PyPI but is marked yanked — excluded from normal resolution. |
25
28
  | `is_unpublished: bool` | npm | The version was individually deleted after release (present in `time` but absent from `versions`), or the entire package was unpublished (all versions inherit this flag). |
26
29
  | `is_prerelease: bool` | npm / PyPI | Version string contains a pre-release segment (e.g. `alpha`, `beta`, `rc`, `dev`). Set by registry adapters during version list construction. |
@@ -34,9 +37,11 @@ This document lists the external specifications that define or inform the domain
34
37
  | `is_installed_prerelease` | `version.is_prerelease` | Installed version is a pre-release. |
35
38
  | `is_installed_yanked` | `version.is_yanked or version.is_unpublished` | Installed version was pulled from the registry (covers both PyPI yanked and npm unpublished). |
36
39
  | `is_installed_deprecated` | `version.is_deprecated or package.is_deprecated` | Installed version or its parent package is deprecated. |
40
+ | `registry_status` | `package.registry_status` | The registry's verdict on the whole package. Unlike `is_installed_deprecated`, a deprecated release of an otherwise live package does not show here. |
41
+ | `deprecation_message` | `package.deprecation_message`, else the installed version's | The note behind the deprecation. |
37
42
  | `is_installed_package_unpublished` | `package.is_unpublished` | The entire package has been removed from the registry. |
38
43
 
39
- Display priority in all renderers: **UNPUBLISHED** > **YANKED** > **DEPRECATED** > pre-release.
44
+ Display priority in all renderers: **UNPUBLISHED** > **YANKED** > **QUARANTINED** > **ARCHIVED** > **DEPRECATED** > pre-release.
40
45
 
41
46
  ---
42
47
 
@@ -126,6 +131,9 @@ Priority ordering for display: **OVERRIDE** > **ADDITIVE** > **PINNED** > **NARR
126
131
  | `type` | `ConstraintType` | Classification of the constraint (see above). |
127
132
  | `source_file` | `str \| None` | The file that declared it (e.g. `"package.json"`, `"pyproject.toml"`). |
128
133
  | `scope_path` | `list[str] \| None` | For npm nested overrides, the path through the dependency tree; `None` for flat constraints. |
134
+ | `is_ossiq_authored` | `bool` | An `OVERRIDE` whose value is still what OSS IQ last wrote (`ossiq:metadata`); `False` for the user's own. |
135
+ | `override_key` | `str \| None` | npm only: the range a version-keyed rule (`foo@^1`) applies to; `None` when it applies to every version. |
136
+ | `override_value` | `str \| None` | npm only: what the matching rule forces — a version, a range or a `$name` reference. |
129
137
 
130
138
  ### `PeerRequirement` — peer constraint tracking
131
139
 
@@ -138,6 +146,16 @@ Priority ordering for display: **OVERRIDE** > **ADDITIVE** > **PINNED** > **NARR
138
146
 
139
147
  Violations (installed version not satisfying `spec`) are surfaced in `ScanRecord.peer_violations`.
140
148
 
149
+ ### `IncomingEdge` and `InstalledCopy` — who asked for which copy
150
+
151
+ npm installs the same name at several versions (nested `node_modules`), so a package is not one node with a pile of constraints but several copies, each with its own requirers.
152
+
153
+ `IncomingEdge` (in `project.py`) is one parent's requirement on an installed package: `requirer_name`, `requirer_version`, `spec` and `is_peer`. `Dependency.parent_edges` holds them next to `parent_constraints`, which remains the flat spec list the solver reads.
154
+
155
+ `InstalledCopy` (in `project.py`) is one physical copy: its `version`, the `edges` that resolve to it, and its own `constraint_info`. `ScanRecord.installed_copies` lists every copy newest first; `installed_version` is the first. Under pip and uv there is always exactly one.
156
+
157
+ The npm lockfile graph attaches each edge to the copy Node would resolve for that parent — the parent's own `node_modules`, then each ancestor's, up to the top level — which is how `package-lock.json` v2/v3 lays the tree out.
158
+
141
159
  ---
142
160
 
143
161
  ## Dependency Categories
@@ -285,6 +303,14 @@ Key response fields used:
285
303
 
286
304
  `yanked` maps to `PackageVersion.is_yanked`. A yanked version still exists on PyPI but is excluded from normal resolution; pip will refuse to install it unless the version is pinned exactly.
287
305
 
306
+ ### PyPI Simple API (PEP 792 project status)
307
+ **Spec**: https://packaging.python.org/en/latest/specifications/project-status-markers/
308
+ **Applies to**: `Package.registry_status`, `Package.deprecation_message`
309
+
310
+ The JSON API above carries no project status. The Simple API does, in the head of each project page: `<meta name="pypi:project-status" content="archived">` and an optional `pypi:project-status-reason`. The statuses are `active`, `deprecated`, `archived` and `quarantined`; an index may omit the tag for an active project, so an absent tag reads as `active`.
311
+
312
+ Endpoint: `https://pypi.org/simple/{name}/` with `Accept: application/vnd.pypi.simple.v1+html`. A page lists every file of the project (numpy's is 2 MB), so the request asks for the first 2 KB with a `Range` header and `Accept-Encoding: identity`; PyPI answers `206`. A failed request leaves `registry_status` as `None`.
313
+
288
314
  ### npm Registry API
289
315
  **Spec**: https://github.com/npm/registry/blob/master/docs/REGISTRY.md
290
316
  **Applies to**: `Package`, `PackageVersion`, `ProjectPackagesRegistry.NPM`
@@ -295,7 +321,7 @@ Key response fields used:
295
321
  - `name`, `description`, `author`, `homepage`, `repository.url`
296
322
  - `versions.{ver}.dependencies`, `versions.{ver}.devDependencies`, `versions.{ver}.peerDependencies`
297
323
  - `versions.{ver}.deprecated` — non-empty string means this version is deprecated → `PackageVersion.is_deprecated`
298
- - `dist-tags.latest` — current latest version; if `versions[latest].deprecated` is set → `Package.is_deprecated`
324
+ - `dist-tags.latest` — current latest version; if `versions[latest].deprecated` is set → `Package.registry_status = DEPRECATED` (else `ACTIVE`), with the note in `Package.deprecation_message`
299
325
  - `time.{ver}` — publish timestamp per version
300
326
  - `time.unpublished` — present when the entire package was unpublished → `Package.is_unpublished`; every version also gets `PackageVersion.is_unpublished=True`
301
327
  - `dist.integrity`, `dist.tarball` — download and verification