@taskless/cli 0.10.0 → 0.10.1

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 (2) hide show
  1. package/dist/index.js +232 -167
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -888,7 +888,7 @@ function ps() {
888
888
  const e = em();
889
889
  return e?.apiUrl ? e.apiUrl : Qp;
890
890
  }
891
- const jt = "0.10.0", ms = "x-taskless-cli-version", Jo = "taskless-cli";
891
+ const jt = "0.10.1", ms = "x-taskless-cli-version", Jo = "taskless-cli";
892
892
  class tm {
893
893
  async requestDeviceCode(t) {
894
894
  const n = ps(), s = { client_id: Jo };
@@ -15759,7 +15759,7 @@ description: |
15759
15759
  \`taskless help route\`; it does NOT suppress the skill.
15760
15760
  metadata:
15761
15761
  author: taskless
15762
- version: 0.10.0
15762
+ version: 0.10.1
15763
15763
  commandName: tskl
15764
15764
  compatibility: Designed for Agents implementing the Agent Skills specification.
15765
15765
  ---
@@ -17291,7 +17291,71 @@ Show:
17291
17291
 
17292
17292
  - \`taskless help check\` — the command being wired into CI
17293
17293
  - \`taskless help rule create\` — required if no rules exist yet
17294
- `, t1 = `# Topic: existing (CLI v%(CLI_VERSION)s / topic v1)
17294
+ `, t1 = `# Topic: detect (CLI v%(CLI_VERSION)s / topic v1)
17295
+
17296
+ ## Goal
17297
+ Scan the working directory for the linters it configures, the
17298
+ languages it uses, and the styles of any rules the repo already
17299
+ authors. Offline and deterministic — no network, no auth, no state
17300
+ change. This is the discovery step that feeds rule-authoring: the
17301
+ routing flow reads \`detect\` to decide where a new rule should live.
17302
+
17303
+ ## Preconditions
17304
+ - None. Works in any directory; doesn't require \`.taskless/\`.
17305
+
17306
+ ## Steps
17307
+
17308
+ 1. **Invoke the CLI** with JSON output:
17309
+ \`\`\`
17310
+ npx @taskless/cli detect --json
17311
+ \`\`\`
17312
+
17313
+ 2. **Parse the response.** Shape:
17314
+ \`\`\`json
17315
+ {
17316
+ "success": true,
17317
+ "linters": [
17318
+ {
17319
+ "name": "eslint",
17320
+ "evidence": ["eslint.config.js", "dependency eslint (package.json)"]
17321
+ }
17322
+ ],
17323
+ "languages": ["typescript", "javascript"],
17324
+ "ruleStyles": [
17325
+ {
17326
+ "source": ".taskless/rules",
17327
+ "description": "ast-grep rules with YAML metadata sidecars"
17328
+ }
17329
+ ]
17330
+ }
17331
+ \`\`\`
17332
+ - \`linters\` — each has a \`name\` and \`evidence\` (config-file paths,
17333
+ a pyproject table marker, or a dependency marker from the
17334
+ language's package file; not every entry is a path).
17335
+ - \`languages\` — inferred from manifests and the detected linters.
17336
+ - \`ruleStyles\` — how the repo authors its own rules, surfaced for
17337
+ downstream reuse.
17338
+
17339
+ 3. **Use the signals to route.** Feed the output into rule authoring:
17340
+ - A detected linter the repo already uses → author the rule there
17341
+ (\`taskless help existing\`).
17342
+ - No suitable linter, local-only → \`taskless help static\`.
17343
+ - See \`taskless help route\` for the full decision.
17344
+
17345
+ ## Errors
17346
+
17347
+ When \`--json\` is set, failures emit \`{ ok: false, code, message }\`:
17348
+
17349
+ | code | meaning | fix |
17350
+ |-------------------|----------------------------------|---------------------------|
17351
+ | \`INTERNAL_ERROR\` | Internal schema validation | Report; likely a CLI bug |
17352
+
17353
+ ## See Also
17354
+
17355
+ - \`taskless help route\` — decide where to author a rule from these signals
17356
+ - \`taskless help existing\` — author a rule in a linter the repo already uses
17357
+ - \`taskless help check\` — run rules against the codebase
17358
+ `, n1 = `# Topic: existing (CLI v%(CLI_VERSION)s / topic v1)
17295
17359
 
17296
17360
  ## Goal
17297
17361
  Author a rule in a linter the repository ALREADY uses, expressed in that
@@ -17348,7 +17412,7 @@ then write the rule where that tool expects it.
17348
17412
  - \`taskless help route\` — re-decide the destination if this no longer fits
17349
17413
  - \`taskless help static\` — author a local ast-grep rule instead
17350
17414
  - \`taskless help remote\` — generate via the Taskless service (login)
17351
- `, n1 = `# Topic: info (CLI v%(CLI_VERSION)s / topic v1)
17415
+ `, s1 = `# Topic: info (CLI v%(CLI_VERSION)s / topic v1)
17352
17416
 
17353
17417
  ## Goal
17354
17418
  Report local Taskless state: CLI version, installed skill versions
@@ -17415,7 +17479,7 @@ failing.)
17415
17479
 
17416
17480
  - \`taskless help auth\` — log in / log out / status detail
17417
17481
  - \`taskless help check\` — run rules against the codebase
17418
- `, s1 = `# Topic: init (CLI v%(CLI_VERSION)s / topic v1)
17482
+ `, r1 = `# Topic: init (CLI v%(CLI_VERSION)s / topic v1)
17419
17483
 
17420
17484
  ## Goal
17421
17485
  Install or update the Taskless skill into the user's coding-agent
@@ -17469,7 +17533,7 @@ what was removed.
17469
17533
 
17470
17534
  - \`taskless help info\` — verify what's installed and check staleness
17471
17535
  - \`taskless help auth\` — authenticate after installing
17472
- `, r1 = `# Topic: onboard (CLI v%(CLI_VERSION)s / topic v1)
17536
+ `, i1 = `# Topic: onboard (CLI v%(CLI_VERSION)s / topic v1)
17473
17537
 
17474
17538
  ## Goal
17475
17539
  Help a user who has just installed Taskless go from zero rules to a
@@ -17591,7 +17655,7 @@ rules as a bullet list the user can choose to materialize via the
17591
17655
  - \`taskless help rule create\` — materialize an accepted bullet into a real rule
17592
17656
  - \`taskless help check\` — validate newly created rules against the codebase
17593
17657
  - \`taskless help info\` — inspect the current \`.taskless/taskless.json\` state
17594
- `, i1 = `# Topic: remote (CLI v%(CLI_VERSION)s / topic v1)
17658
+ `, o1 = `# Topic: remote (CLI v%(CLI_VERSION)s / topic v1)
17595
17659
 
17596
17660
  ## Goal
17597
17661
  Generate a rule using the Taskless service. Your job on this path is to
@@ -17651,7 +17715,7 @@ confirmed.
17651
17715
  - \`taskless help rule create\` — the generation backend this path uses
17652
17716
  - \`taskless help auth\` — log in before generating
17653
17717
  - \`taskless help check\` — validate the generated rule
17654
- `, o1 = `# Topic: route (CLI v%(CLI_VERSION)s / topic v1)
17718
+ `, a1 = `# Topic: route (CLI v%(CLI_VERSION)s / topic v1)
17655
17719
 
17656
17720
  ## Goal
17657
17721
  Decide where a rule-authoring request should be built: in a linter the
@@ -17746,7 +17810,7 @@ failed and the user confirms.
17746
17810
  - \`taskless help existing\` — author in a linter the repo already uses
17747
17811
  - \`taskless help static\` — author a local ast-grep rule (no login)
17748
17812
  - \`taskless help remote\` — generate via the Taskless service (login)
17749
- `, a1 = "# Topic: rule create (anonymous) (CLI v%(CLI_VERSION)s / topic v1)\n\n## Goal\nCreate a new ast-grep rule **locally** without contacting the Taskless\nAPI. You (the agent) derive the rule yourself using the ast-grep\nschema as a guide, write the rule and test files, then validate them\nusing `rule verify` in a feedback loop.\n\n## Preconditions\n- `.taskless/` directory exists.\n- The agent can read/write files and run shell commands.\n- No auth required.\n\n## Steps\n\n1. **Learn the ast-grep rule format.** Before writing a rule, consult\n the ast-grep rule reference at https://ast-grep.github.io/guide/rule-config.html\n for valid fields, operators (`pattern`, `kind`, `regex`,\n `any`/`all`/`has`/`inside`/`not`), and meta-variable syntax. The\n Taskless-required fields you'll add on top are listed in step 5.\n\n2. **Gather the rule description.** Even if the user already provided\n one, ask clarifying questions:\n - What specific code pattern should be flagged? (concrete examples)\n - What language is it in?\n - Are there exceptions or edge cases where the pattern is OK?\n - Can they show valid and invalid examples?\n\n3. **Check for similar existing rules.** Scan `.taskless/rules/`. If\n anything overlaps, point it out and ask whether the user wants to\n improve an existing rule via `taskless help rule improve --anonymous`.\n\n4. **Search the codebase for real instances.** Show the user what you\n found and confirm any exclusions.\n\n5. **Derive the rule.** Write a YAML file at `.taskless/rules/<id>.yml`\n with at minimum:\n - `id`: kebab-case identifier (e.g. `no-eval`, `prefer-const`)\n - `language`: target language\n - `severity`: `error`, `warning`, `info`, or `hint`\n - `message`: concise single-line explanation\n - `rule`: the ast-grep rule object\n\n Optional but useful: `note` (multi-line guidance, supports markdown),\n `fix` (auto-fix pattern), `ignores` (file patterns to skip).\n\n6. **Write test cases.** Create `.taskless/rule-tests/<id>-YYYYMMDD-test.yml`\n with `id`, `valid: [...]`, and `invalid: [...]` arrays. Include at\n least 2 valid and 2 invalid cases. Use real patterns from the\n codebase where possible.\n\n7. **Run the verify feedback loop.** Run:\n ```\n npx @taskless/cli rule verify <id> --json\n ```\n - If `success: true`: the rule passes. Report success to the user.\n - If `success: false`: read the per-layer errors (`schema`,\n `requirements`, `tests`). Fix the rule or tests. Re-run verify.\n Repeat up to 3 times. If still failing after 3 iterations, report\n to the user with the latest errors.\n\n Common fixes:\n - Schema errors → check field types against the ast-grep schema.\n - Missing required fields → add what the requirements list demands.\n - Regex without kind → add a `kind` field alongside any `regex`.\n - Test failures → adjust pattern or test cases so valid cases pass\n and invalid cases trigger.\n\n8. **Report results.** Show the rule file path, test file path, and a\n one-line summary of what the rule detects. Suggest fetching\n `taskless help check` to validate against the broader codebase.\n\n## Important Notes\n\n- Do NOT write files to `.taskless/rule-metadata/`. Anonymous rules\n have no metadata sidecar (the API path uses metadata for\n iteration; anonymous rules iterate directly via file edits).\n- Do NOT make any HTTP requests to taskless.io.\n- The verify feedback loop is the quality gate — always run it before\n reporting success.\n\n## ast-grep schema\n\nThis recipe does not embed the full ast-grep schema. Read it from the\nupstream docs at https://ast-grep.github.io/guide/rule-config.html\nbefore authoring a rule. The Taskless-specific required fields layered\non top of the ast-grep rule are listed in step 5.\n\n## Errors\n\n`rule verify --json` has two output shapes depending on whether the\n`<id>` argument is supplied:\n\n- When `<id>` is missing, the command emits the standardized\n `{ ok:false, code:\"INVALID_INPUT\", message }` envelope on stdout\n and exits non-zero.\n- When `<id>` is supplied, the command emits the layered result\n `{ success, schema, requirements, tests, ... }` on stdout (success\n or failure exit code depending on the layers).\n\n| where | code / shape | meaning | fix |\n|---------------------|-----------------|------------------------------------------|--------------------------------------------|\n| envelope (no `<id>`)| `INVALID_INPUT` | Rule ID missing | Pass a valid rule ID positionally |\n| layered: schema | (schema layer) | YAML didn't match ast-grep schema | Fix the rule structure |\n| layered: req | (req layer) | Missing Taskless-required field | Add `id`/`language`/`severity`/etc. |\n| layered: tests | (tests layer) | A test case didn't behave as expected | Fix the rule pattern OR the test case |\n\n## See Also\n\n- `taskless help rule create` — API-backed flow (auth required)\n- `taskless help rule improve --anonymous` — iterate locally\n- `taskless help check` — validate the new rule against the codebase\n", l1 = `# Topic: rule create (CLI v%(CLI_VERSION)s / topic v1)
17813
+ `, l1 = "# Topic: rule create (anonymous) (CLI v%(CLI_VERSION)s / topic v1)\n\n## Goal\nCreate a new ast-grep rule **locally** without contacting the Taskless\nAPI. You (the agent) derive the rule yourself using the ast-grep\nschema as a guide, write the rule and test files, then validate them\nusing `rule verify` in a feedback loop.\n\n## Preconditions\n- `.taskless/` directory exists.\n- The agent can read/write files and run shell commands.\n- No auth required.\n\n## Steps\n\n1. **Learn the ast-grep rule format.** Before writing a rule, consult\n the ast-grep rule reference at https://ast-grep.github.io/guide/rule-config.html\n for valid fields, operators (`pattern`, `kind`, `regex`,\n `any`/`all`/`has`/`inside`/`not`), and meta-variable syntax. The\n Taskless-required fields you'll add on top are listed in step 5.\n\n2. **Gather the rule description.** Even if the user already provided\n one, ask clarifying questions:\n - What specific code pattern should be flagged? (concrete examples)\n - What language is it in?\n - Are there exceptions or edge cases where the pattern is OK?\n - Can they show valid and invalid examples?\n\n3. **Check for similar existing rules.** Scan `.taskless/rules/`. If\n anything overlaps, point it out and ask whether the user wants to\n improve an existing rule via `taskless help rule improve --anonymous`.\n\n4. **Search the codebase for real instances.** Show the user what you\n found and confirm any exclusions.\n\n5. **Derive the rule.** Write a YAML file at `.taskless/rules/<id>.yml`\n with at minimum:\n - `id`: kebab-case identifier (e.g. `no-eval`, `prefer-const`)\n - `language`: target language\n - `severity`: `error`, `warning`, `info`, or `hint`\n - `message`: concise single-line explanation\n - `rule`: the ast-grep rule object\n\n Optional but useful: `note` (multi-line guidance, supports markdown),\n `fix` (auto-fix pattern), `ignores` (file patterns to skip).\n\n6. **Write test cases.** Create `.taskless/rule-tests/<id>-YYYYMMDD-test.yml`\n with `id`, `valid: [...]`, and `invalid: [...]` arrays. Include at\n least 2 valid and 2 invalid cases. Use real patterns from the\n codebase where possible.\n\n7. **Run the verify feedback loop.** Run:\n ```\n npx @taskless/cli rule verify <id> --json\n ```\n - If `success: true`: the rule passes. Report success to the user.\n - If `success: false`: read the per-layer errors (`schema`,\n `requirements`, `tests`). Fix the rule or tests. Re-run verify.\n Repeat up to 3 times. If still failing after 3 iterations, report\n to the user with the latest errors.\n\n Common fixes:\n - Schema errors → check field types against the ast-grep schema.\n - Missing required fields → add what the requirements list demands.\n - Regex without kind → add a `kind` field alongside any `regex`.\n - Test failures → adjust pattern or test cases so valid cases pass\n and invalid cases trigger.\n\n8. **Report results.** Show the rule file path, test file path, and a\n one-line summary of what the rule detects. Suggest fetching\n `taskless help check` to validate against the broader codebase.\n\n## Important Notes\n\n- Do NOT write files to `.taskless/rule-metadata/`. Anonymous rules\n have no metadata sidecar (the API path uses metadata for\n iteration; anonymous rules iterate directly via file edits).\n- Do NOT make any HTTP requests to taskless.io.\n- The verify feedback loop is the quality gate — always run it before\n reporting success.\n\n## ast-grep schema\n\nThis recipe does not embed the full ast-grep schema. Read it from the\nupstream docs at https://ast-grep.github.io/guide/rule-config.html\nbefore authoring a rule. The Taskless-specific required fields layered\non top of the ast-grep rule are listed in step 5.\n\n## Errors\n\n`rule verify --json` has two output shapes depending on whether the\n`<id>` argument is supplied:\n\n- When `<id>` is missing, the command emits the standardized\n `{ ok:false, code:\"INVALID_INPUT\", message }` envelope on stdout\n and exits non-zero.\n- When `<id>` is supplied, the command emits the layered result\n `{ success, schema, requirements, tests, ... }` on stdout (success\n or failure exit code depending on the layers).\n\n| where | code / shape | meaning | fix |\n|---------------------|-----------------|------------------------------------------|--------------------------------------------|\n| envelope (no `<id>`)| `INVALID_INPUT` | Rule ID missing | Pass a valid rule ID positionally |\n| layered: schema | (schema layer) | YAML didn't match ast-grep schema | Fix the rule structure |\n| layered: req | (req layer) | Missing Taskless-required field | Add `id`/`language`/`severity`/etc. |\n| layered: tests | (tests layer) | A test case didn't behave as expected | Fix the rule pattern OR the test case |\n\n## See Also\n\n- `taskless help rule create` — API-backed flow (auth required)\n- `taskless help rule improve --anonymous` — iterate locally\n- `taskless help check` — validate the new rule against the codebase\n", c1 = `# Topic: rule create (CLI v%(CLI_VERSION)s / topic v1)
17750
17814
 
17751
17815
  ## Goal
17752
17816
  Generate a new ast-grep rule from a description and write the rule and
@@ -17847,7 +17911,7 @@ When \`--json\` is set, failures emit \`{ ok: false, code, message }\`:
17847
17911
  - \`taskless help rule create --anonymous\` — local-only flow (no API)
17848
17912
  - \`taskless help rule improve\` — iterate on an existing rule
17849
17913
  - \`taskless help check\` — validate the new rule against the codebase
17850
- `, c1 = `# Topic: rule delete (CLI v%(CLI_VERSION)s / topic v1)
17914
+ `, u1 = `# Topic: rule delete (CLI v%(CLI_VERSION)s / topic v1)
17851
17915
 
17852
17916
  ## Goal
17853
17917
  Remove a rule and its associated test files from \`.taskless/\`. Does
@@ -17895,7 +17959,7 @@ emitted from this command.
17895
17959
 
17896
17960
  - \`taskless help rule create\` — make a new rule
17897
17961
  - \`taskless help check\` — run remaining rules to confirm nothing broke
17898
- `, u1 = `# Topic: rule improve (anonymous) (CLI v%(CLI_VERSION)s / topic v1)
17962
+ `, f1 = `# Topic: rule improve (anonymous) (CLI v%(CLI_VERSION)s / topic v1)
17899
17963
 
17900
17964
  ## Goal
17901
17965
  Iterate on an existing ast-grep rule **locally** without contacting
@@ -17983,7 +18047,7 @@ The verify primitive returns structured errors per layer:
17983
18047
  - \`taskless help rule improve\` — API-backed flow (auth required)
17984
18048
  - \`taskless help rule create --anonymous\` — make a new rule locally
17985
18049
  - \`taskless help check\` — validate the updated rule
17986
- `, f1 = `# Topic: rule improve (CLI v%(CLI_VERSION)s / topic v1)
18050
+ `, d1 = `# Topic: rule improve (CLI v%(CLI_VERSION)s / topic v1)
17987
18051
 
17988
18052
  ## Goal
17989
18053
  Iterate on an existing Taskless rule. The CLI submits the user's
@@ -18087,7 +18151,7 @@ When \`--json\` is set, failures emit \`{ ok: false, code, message }\`:
18087
18151
  - \`taskless help rule improve --anonymous\` — local-only flow
18088
18152
  - \`taskless help rule create\` — make a new rule from scratch
18089
18153
  - \`taskless help check\` — validate the updated rule
18090
- `, d1 = `# Topic: rule meta (CLI v%(CLI_VERSION)s / topic v1)
18154
+ `, h1 = `# Topic: rule meta (CLI v%(CLI_VERSION)s / topic v1)
18091
18155
 
18092
18156
  ## Goal
18093
18157
  Read sidecar metadata for an API-generated rule. Used internally by
@@ -18117,7 +18181,7 @@ version, etc.
18117
18181
  ## See Also
18118
18182
 
18119
18183
  - \`taskless help rule improve\` — the primary consumer of this command
18120
- `, h1 = `# Topic: rule verify (CLI v%(CLI_VERSION)s / topic v1)
18184
+ `, p1 = `# Topic: rule verify (CLI v%(CLI_VERSION)s / topic v1)
18121
18185
 
18122
18186
  ## Goal
18123
18187
  Validate a rule against the ast-grep schema and run its test cases.
@@ -18175,7 +18239,7 @@ attempts and report to the user if still failing.
18175
18239
 
18176
18240
  - \`taskless help rule create --anonymous\` — primary consumer (loop)
18177
18241
  - \`taskless help rule improve --anonymous\` — primary consumer (loop)
18178
- `, p1 = `# Topic: rule (CLI v%(CLI_VERSION)s / topic v1)
18242
+ `, m1 = `# Topic: rule (CLI v%(CLI_VERSION)s / topic v1)
18179
18243
 
18180
18244
  ## Goal
18181
18245
  Umbrella for rule operations. Use the specific subcommand for the
@@ -18197,7 +18261,7 @@ help fetch.
18197
18261
  ## See Also
18198
18262
 
18199
18263
  - \`taskless help check\` — run all configured rules
18200
- `, m1 = "# Topic: static (CLI v%(CLI_VERSION)s / topic v1)\n\n## Goal\nAuthor a Taskless ast-grep rule **locally**, on this machine, without\ncontacting the Taskless service. You derive the rule yourself, write it\nin the canonical on-disk shape, and validate it with `rule verify` in a\nfeedback loop. The files you produce match exactly what the service\nwrites, so `check`, `improve`, and `verify` treat them identically.\n\n## Preconditions\n- `.taskless/` directory exists.\n- The agent can read/write files and run shell commands.\n- No auth required.\n\n## Steps\n\n1. **Learn the ast-grep rule format.** Consult the ast-grep rule\n reference at https://ast-grep.github.io/guide/rule-config.html for\n valid fields and operators (`pattern`, `kind`, `regex`,\n `any`/`all`/`has`/`inside`/`not`) and meta-variable syntax.\n\n2. **Gather and confirm the pattern.** Make sure you have concrete\n success cases (code that should pass) and failure cases (code that\n should be flagged), the target language, and any exceptions. Search\n the codebase for real instances and confirm exclusions with the user.\n\n3. **Author the rule in the canonical shape.** Write the rule to\n `.taskless/rules/<id>.yml` with at minimum `id` (kebab-case),\n `language`, `severity` (`error`/`warning`/`info`/`hint`), `message`,\n and the `rule` object. Write tests to\n `.taskless/rule-tests/<id>-YYYYMMDD-test.yml` with the matching `id`\n field plus `valid` and `invalid` arrays (at least two of each). The\n `id` must match the rule's `id` so ast-grep test filtering pairs them.\n These paths and shape are the same ones the service writes — do not\n invent a different layout.\n\n4. **Run the verify feedback loop.** Run:\n ```\n npx @taskless/cli rule verify <id> --json\n ```\n - `success: true` → the rule passes. Go to step 5.\n - `success: false` → read the per-layer errors (`schema`,\n `requirements`, `tests`), fix the rule or tests, and re-run. Repeat\n up to 3 times.\n\n5. **On success, report.** Show the rule and test file paths and a\n one-line summary of what the rule detects. Suggest `taskless help\n check` to validate against the broader codebase.\n\n6. **On failure, escalate via the route fallback — with confirmation.**\n If after the feedback loop the rule still cannot capture the user's\n cases, this is the try-verify-escalate fallback:\n - Delete the candidate `.taskless/rules/<id>.yml` and its test file so\n the repo is not left with a broken rule (guaranteed cleanup of the\n abandoned candidate).\n - Tell the user the local rule could not capture the cases, and that\n generating via the Taskless service uses a generation and requires\n login.\n - Only after the user confirms, fetch `taskless help remote` and\n follow it. Do not call the service silently.\n\n## Important Notes\n\n- Do NOT make any HTTP requests to taskless.io on this path.\n- Do NOT write to `.taskless/rule-metadata/` — local rules have no\n metadata sidecar; they iterate via file edits.\n- The verify loop is the quality gate. A clean failure is a legitimate\n reason to escalate, but only with the user's confirmation (step 6).\n\n## See Also\n\n- `taskless help route` — re-decide the destination\n- `taskless help remote` — generate via the Taskless service (login)\n- `taskless help check` — validate the new rule against the codebase\n", g1 = `# Topic: update (CLI v%(CLI_VERSION)s / topic v1)
18264
+ `, g1 = "# Topic: static (CLI v%(CLI_VERSION)s / topic v1)\n\n## Goal\nAuthor a Taskless ast-grep rule **locally**, on this machine, without\ncontacting the Taskless service. You derive the rule yourself, write it\nin the canonical on-disk shape, and validate it with `rule verify` in a\nfeedback loop. The files you produce match exactly what the service\nwrites, so `check`, `improve`, and `verify` treat them identically.\n\n## Preconditions\n- `.taskless/` directory exists.\n- The agent can read/write files and run shell commands.\n- No auth required.\n\n## Steps\n\n1. **Learn the ast-grep rule format.** Consult the ast-grep rule\n reference at https://ast-grep.github.io/guide/rule-config.html for\n valid fields and operators (`pattern`, `kind`, `regex`,\n `any`/`all`/`has`/`inside`/`not`) and meta-variable syntax.\n\n2. **Gather and confirm the pattern.** Make sure you have concrete\n success cases (code that should pass) and failure cases (code that\n should be flagged), the target language, and any exceptions. Search\n the codebase for real instances and confirm exclusions with the user.\n\n3. **Author the rule in the canonical shape.** Write the rule to\n `.taskless/rules/<id>.yml` with at minimum `id` (kebab-case),\n `language`, `severity` (`error`/`warning`/`info`/`hint`), `message`,\n and the `rule` object. Write tests to\n `.taskless/rule-tests/<id>-YYYYMMDD-test.yml` with the matching `id`\n field plus `valid` and `invalid` arrays (at least two of each). The\n `id` must match the rule's `id` so ast-grep test filtering pairs them.\n These paths and shape are the same ones the service writes — do not\n invent a different layout.\n\n4. **Run the verify feedback loop.** Run:\n ```\n npx @taskless/cli rule verify <id> --json\n ```\n - `success: true` → the rule passes. Go to step 5.\n - `success: false` → read the per-layer errors (`schema`,\n `requirements`, `tests`), fix the rule or tests, and re-run. Repeat\n up to 3 times.\n\n5. **On success, report.** Show the rule and test file paths and a\n one-line summary of what the rule detects. Suggest `taskless help\n check` to validate against the broader codebase.\n\n6. **On failure, escalate via the route fallback — with confirmation.**\n If after the feedback loop the rule still cannot capture the user's\n cases, this is the try-verify-escalate fallback:\n - Delete the candidate `.taskless/rules/<id>.yml` and its test file so\n the repo is not left with a broken rule (guaranteed cleanup of the\n abandoned candidate).\n - Tell the user the local rule could not capture the cases, and that\n generating via the Taskless service uses a generation and requires\n login.\n - Only after the user confirms, fetch `taskless help remote` and\n follow it. Do not call the service silently.\n\n## Important Notes\n\n- Do NOT make any HTTP requests to taskless.io on this path.\n- Do NOT write to `.taskless/rule-metadata/` — local rules have no\n metadata sidecar; they iterate via file edits.\n- The verify loop is the quality gate. A clean failure is a legitimate\n reason to escalate, but only with the user's confirmation (step 6).\n\n## See Also\n\n- `taskless help route` — re-decide the destination\n- `taskless help remote` — generate via the Taskless service (login)\n- `taskless help check` — validate the new rule against the codebase\n", y1 = `# Topic: update (CLI v%(CLI_VERSION)s / topic v1)
18201
18265
 
18202
18266
  ## Goal
18203
18267
  Update Taskless skills in the user's coding-agent tools to the
@@ -18247,7 +18311,7 @@ non-zero with the error message on stderr.
18247
18311
  - \`taskless help info\` — verify what's installed and check staleness
18248
18312
  `;
18249
18313
  var Rr = {}, ul;
18250
- function y1() {
18314
+ function b1() {
18251
18315
  return ul || (ul = 1, (function(e) {
18252
18316
  (function() {
18253
18317
  var t = {
@@ -18388,7 +18452,7 @@ function y1() {
18388
18452
  })();
18389
18453
  })(Rr)), Rr;
18390
18454
  }
18391
- var b1 = y1();
18455
+ var w1 = b1();
18392
18456
  const Nh = M({
18393
18457
  prompt: C().trim().min(1, "prompt must be a non-empty string").describe("Description of the rule to generate"),
18394
18458
  successCases: J(C()).optional().describe("Examples of correct code that should pass the rule"),
@@ -18420,30 +18484,31 @@ const Ph = M({
18420
18484
  M({
18421
18485
  error: C().describe("Error message")
18422
18486
  });
18423
- const w1 = /* @__PURE__ */ Object.assign({
18487
+ const v1 = /* @__PURE__ */ Object.assign({
18424
18488
  "../help/auth.txt": Q$,
18425
18489
  "../help/check.txt": X$,
18426
18490
  "../help/ci.txt": e1,
18427
- "../help/existing.txt": t1,
18428
- "../help/info.txt": n1,
18429
- "../help/init.txt": s1,
18430
- "../help/onboard.txt": r1,
18431
- "../help/remote.txt": i1,
18432
- "../help/route.txt": o1,
18433
- "../help/rule-create.anonymous.txt": a1,
18434
- "../help/rule-create.txt": l1,
18435
- "../help/rule-delete.txt": c1,
18436
- "../help/rule-improve.anonymous.txt": u1,
18437
- "../help/rule-improve.txt": f1,
18438
- "../help/rule-meta.txt": d1,
18439
- "../help/rule-verify.txt": h1,
18440
- "../help/rule.txt": p1,
18441
- "../help/static.txt": m1,
18442
- "../help/update.txt": g1
18491
+ "../help/detect.txt": t1,
18492
+ "../help/existing.txt": n1,
18493
+ "../help/info.txt": s1,
18494
+ "../help/init.txt": r1,
18495
+ "../help/onboard.txt": i1,
18496
+ "../help/remote.txt": o1,
18497
+ "../help/route.txt": a1,
18498
+ "../help/rule-create.anonymous.txt": l1,
18499
+ "../help/rule-create.txt": c1,
18500
+ "../help/rule-delete.txt": u1,
18501
+ "../help/rule-improve.anonymous.txt": f1,
18502
+ "../help/rule-improve.txt": d1,
18503
+ "../help/rule-meta.txt": h1,
18504
+ "../help/rule-verify.txt": p1,
18505
+ "../help/rule.txt": m1,
18506
+ "../help/static.txt": g1,
18507
+ "../help/update.txt": y1
18443
18508
  });
18444
- function v1() {
18509
+ function k1() {
18445
18510
  const e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
18446
- for (const [n, s] of Object.entries(w1)) {
18511
+ for (const [n, s] of Object.entries(v1)) {
18447
18512
  const r = n.split("/").pop()?.replace(/\.txt$/, "");
18448
18513
  if (r)
18449
18514
  if (r.endsWith(".anonymous")) {
@@ -18454,27 +18519,27 @@ function v1() {
18454
18519
  }
18455
18520
  return { helpMap: e, anonymousMap: t };
18456
18521
  }
18457
- const { helpMap: Ns, anonymousMap: Rh } = v1(), hl = [
18522
+ const { helpMap: Ns, anonymousMap: Rh } = k1(), hl = [
18458
18523
  ["route", "Decide where to author a rule (existing/static/remote)"],
18459
18524
  ["existing", "Author a rule in a linter the repo already uses"],
18460
18525
  ["static", "Author a local ast-grep rule on this machine (no login)"],
18461
18526
  ["remote", "Generate a rule via the Taskless service (login)"]
18462
- ], k1 = {
18527
+ ], _1 = {
18463
18528
  "rule-create": Nh,
18464
18529
  "rule-improve": Ph
18465
18530
  };
18466
18531
  function jh(e, t) {
18467
18532
  const n = {
18468
- CLI_VERSION: "0.10.0",
18533
+ CLI_VERSION: "0.10.1",
18469
18534
  PACKAGE_MANAGER_DLX: "<package-manager-dlx>"
18470
18535
  };
18471
18536
  if (e.includes("%(INPUT_SCHEMA)s")) {
18472
- const s = k1[t];
18537
+ const s = _1[t];
18473
18538
  n.INPUT_SCHEMA = s ? JSON.stringify(J0(s), null, 2) : "(no input schema for this topic)";
18474
18539
  }
18475
- return b1.sprintf(e, n);
18540
+ return w1.sprintf(e, n);
18476
18541
  }
18477
- function _1(e, t = {}) {
18542
+ function S1(e, t = {}) {
18478
18543
  const n = t.anonymous ? Rh.get(e) ?? Ns.get(e) : Ns.get(e);
18479
18544
  if (n !== void 0)
18480
18545
  return jh(n, e);
@@ -18482,11 +18547,11 @@ function _1(e, t = {}) {
18482
18547
  async function pl(e) {
18483
18548
  return typeof e == "function" ? e() : e;
18484
18549
  }
18485
- async function S1(e) {
18550
+ async function $1(e) {
18486
18551
  const t = await pl(e);
18487
18552
  return (t.meta ? await pl(t.meta) : void 0)?.description ?? "";
18488
18553
  }
18489
- function $1(e) {
18554
+ function I1(e) {
18490
18555
  return {
18491
18556
  meta: {
18492
18557
  name: "help",
@@ -18527,7 +18592,7 @@ function $1(e) {
18527
18592
  const c = [];
18528
18593
  for (const [u, d] of Object.entries(e)) {
18529
18594
  if (u === "help") continue;
18530
- const h = await S1(d);
18595
+ const h = await $1(d);
18531
18596
  c.push([u, h]);
18532
18597
  }
18533
18598
  const f = Math.max(
@@ -18555,7 +18620,7 @@ Authoring recipes:`);
18555
18620
  function Lh(e) {
18556
18621
  return e.commandsInstalled ? "Next: in your AI tool, run /tskl onboard or ask it to use the Taskless skill (or run `taskless onboard` from your terminal) to discover rule candidates from your codebase." : "Next: in your AI tool, ask it to use the Taskless skill (or run `taskless onboard` from your terminal) to discover rule candidates from your codebase.";
18557
18622
  }
18558
- const I1 = {
18623
+ const E1 = {
18559
18624
  meta: {
18560
18625
  name: "onboard",
18561
18626
  description: "Discover rule candidates from your codebase and history (post-install flow)"
@@ -18599,7 +18664,7 @@ const I1 = {
18599
18664
  );
18600
18665
  return;
18601
18666
  }
18602
- const o = _1("onboard");
18667
+ const o = S1("onboard");
18603
18668
  if (o === void 0)
18604
18669
  throw console.error("Internal error: onboard recipe is not available."), process.exitCode = 1, new mt("recipe missing");
18605
18670
  console.log(o.trimEnd());
@@ -18677,9 +18742,9 @@ const jr = 10, ml = (e = 0) => (t) => `\x1B[${t + e}m`, gl = (e = 0) => (t) => `
18677
18742
  }
18678
18743
  };
18679
18744
  Object.keys(V.modifier);
18680
- const E1 = Object.keys(V.color), T1 = Object.keys(V.bgColor);
18681
- [...E1, ...T1];
18682
- function A1() {
18745
+ const T1 = Object.keys(V.color), A1 = Object.keys(V.bgColor);
18746
+ [...T1, ...A1];
18747
+ function O1() {
18683
18748
  const e = /* @__PURE__ */ new Map();
18684
18749
  for (const [t, n] of Object.entries(V)) {
18685
18750
  for (const [s, r] of Object.entries(n))
@@ -18756,7 +18821,7 @@ function A1() {
18756
18821
  }
18757
18822
  }), V;
18758
18823
  }
18759
- const xe = A1(), bl = (() => {
18824
+ const xe = O1(), bl = (() => {
18760
18825
  if (!("navigator" in globalThis))
18761
18826
  return 0;
18762
18827
  if (globalThis.navigator.userAgentData) {
@@ -18767,11 +18832,11 @@ const xe = A1(), bl = (() => {
18767
18832
  return /\b(Chrome|Chromium)\//.test(globalThis.navigator.userAgent) ? 1 : 0;
18768
18833
  })(), wl = bl !== 0 && {
18769
18834
  level: bl
18770
- }, O1 = {
18835
+ }, C1 = {
18771
18836
  stdout: wl,
18772
18837
  stderr: wl
18773
18838
  };
18774
- function C1(e, t, n) {
18839
+ function x1(e, t, n) {
18775
18840
  let s = e.indexOf(t);
18776
18841
  if (s === -1)
18777
18842
  return e;
@@ -18782,7 +18847,7 @@ function C1(e, t, n) {
18782
18847
  while (s !== -1);
18783
18848
  return o += e.slice(i), o;
18784
18849
  }
18785
- function x1(e, t, n, s) {
18850
+ function F1(e, t, n, s) {
18786
18851
  let r = 0, i = "";
18787
18852
  do {
18788
18853
  const o = e[s - 1] === "\r";
@@ -18793,22 +18858,22 @@ function x1(e, t, n, s) {
18793
18858
  } while (s !== -1);
18794
18859
  return i += e.slice(r), i;
18795
18860
  }
18796
- const { stdout: vl, stderr: kl } = O1, si = /* @__PURE__ */ Symbol("GENERATOR"), Gt = /* @__PURE__ */ Symbol("STYLER"), yn = /* @__PURE__ */ Symbol("IS_EMPTY"), _l = [
18861
+ const { stdout: vl, stderr: kl } = C1, si = /* @__PURE__ */ Symbol("GENERATOR"), Gt = /* @__PURE__ */ Symbol("STYLER"), yn = /* @__PURE__ */ Symbol("IS_EMPTY"), _l = [
18797
18862
  "ansi",
18798
18863
  "ansi",
18799
18864
  "ansi256",
18800
18865
  "ansi16m"
18801
- ], Jt = /* @__PURE__ */ Object.create(null), F1 = (e, t = {}) => {
18866
+ ], Jt = /* @__PURE__ */ Object.create(null), N1 = (e, t = {}) => {
18802
18867
  if (t.level && !(Number.isInteger(t.level) && t.level >= 0 && t.level <= 3))
18803
18868
  throw new Error("The `level` option should be an integer from 0 to 3");
18804
18869
  const n = vl ? vl.level : 0;
18805
18870
  e.level = t.level === void 0 ? n : t.level;
18806
- }, N1 = (e) => {
18871
+ }, P1 = (e) => {
18807
18872
  const t = (...n) => n.join(" ");
18808
- return F1(t, e), Object.setPrototypeOf(t, Cn.prototype), t;
18873
+ return N1(t, e), Object.setPrototypeOf(t, Cn.prototype), t;
18809
18874
  };
18810
18875
  function Cn(e) {
18811
- return N1(e);
18876
+ return P1(e);
18812
18877
  }
18813
18878
  Object.setPrototypeOf(Cn.prototype, Function.prototype);
18814
18879
  for (const [e, t] of Object.entries(xe))
@@ -18824,8 +18889,8 @@ Jt.visible = {
18824
18889
  return Object.defineProperty(this, "visible", { value: e }), e;
18825
18890
  }
18826
18891
  };
18827
- const ri = (e, t, n, ...s) => e === "rgb" ? t === "ansi16m" ? xe[n].ansi16m(...s) : t === "ansi256" ? xe[n].ansi256(xe.rgbToAnsi256(...s)) : xe[n].ansi(xe.rgbToAnsi(...s)) : e === "hex" ? ri("rgb", t, n, ...xe.hexToRgb(...s)) : xe[n][e](...s), P1 = ["rgb", "hex", "ansi256"];
18828
- for (const e of P1) {
18892
+ const ri = (e, t, n, ...s) => e === "rgb" ? t === "ansi16m" ? xe[n].ansi16m(...s) : t === "ansi256" ? xe[n].ansi256(xe.rgbToAnsi256(...s)) : xe[n].ansi(xe.rgbToAnsi(...s)) : e === "hex" ? ri("rgb", t, n, ...xe.hexToRgb(...s)) : xe[n][e](...s), R1 = ["rgb", "hex", "ansi256"];
18893
+ for (const e of R1) {
18829
18894
  Jt[e] = {
18830
18895
  get() {
18831
18896
  const { level: n } = this;
@@ -18846,7 +18911,7 @@ for (const e of P1) {
18846
18911
  }
18847
18912
  };
18848
18913
  }
18849
- const R1 = Object.defineProperties(() => {
18914
+ const j1 = Object.defineProperties(() => {
18850
18915
  }, {
18851
18916
  ...Jt,
18852
18917
  level: {
@@ -18868,9 +18933,9 @@ const R1 = Object.defineProperties(() => {
18868
18933
  parent: n
18869
18934
  };
18870
18935
  }, Ps = (e, t, n) => {
18871
- const s = (...r) => j1(s, r.length === 1 ? "" + r[0] : r.join(" "));
18872
- return Object.setPrototypeOf(s, R1), s[si] = e, s[Gt] = t, s[yn] = n, s;
18873
- }, j1 = (e, t) => {
18936
+ const s = (...r) => L1(s, r.length === 1 ? "" + r[0] : r.join(" "));
18937
+ return Object.setPrototypeOf(s, j1), s[si] = e, s[Gt] = t, s[yn] = n, s;
18938
+ }, L1 = (e, t) => {
18874
18939
  if (e.level <= 0 || !t)
18875
18940
  return e[yn] ? "" : t;
18876
18941
  let n = e[Gt];
@@ -18879,16 +18944,16 @@ const R1 = Object.defineProperties(() => {
18879
18944
  const { openAll: s, closeAll: r } = n;
18880
18945
  if (t.includes("\x1B"))
18881
18946
  for (; n !== void 0; )
18882
- t = C1(t, n.close, n.open), n = n.parent;
18947
+ t = x1(t, n.close, n.open), n = n.parent;
18883
18948
  const i = t.indexOf(`
18884
18949
  `);
18885
- return i !== -1 && (t = x1(t, r, s, i)), s + t + r;
18950
+ return i !== -1 && (t = F1(t, r, s, i)), s + t + r;
18886
18951
  };
18887
18952
  Object.defineProperties(Cn.prototype, Jt);
18888
18953
  const oi = Cn();
18889
18954
  Cn({ level: kl ? kl.level : 0 });
18890
- const Dh = "0.10.0";
18891
- function L1() {
18955
+ const Dh = "0.10.1";
18956
+ function z1() {
18892
18957
  if (process.env.NO_COLOR) return 0;
18893
18958
  const e = process.env.FORCE_COLOR;
18894
18959
  if (e === "0") return 0;
@@ -18899,23 +18964,23 @@ function L1() {
18899
18964
  const n = process.env.TERM ?? "", s = process.env.COLORTERM ?? "";
18900
18965
  return s === "truecolor" || s === "24bit" ? 3 : /-256(color)?$/i.test(n) ? 2 : n === "" || n === "dumb" ? 0 : 1;
18901
18966
  }
18902
- oi.level = L1();
18903
- const z1 = `
18967
+ oi.level = z1();
18968
+ const D1 = `
18904
18969
  ██████████
18905
18970
  ▄▄▄▄ ▗▄▄ ▗▄█▙▄▖ ▗▄▄▖ ▄▄▄ ▐█ ▄▖ ▀▀█ ▄▄▖ ▄▄▄ ▄▄▄
18906
18971
  ██▛▘▗▟████ ▝▀█▛▀▘ ▀ ▝█▖ █▙ ▝▘▐█▗▟▀ █ ▗█▘ ▜▙ █▙ ▝▘ █▙ ▝▘
18907
18972
  █▛ ▗██████ █▌ ▐█▀▀█▌ ▀▀▜▙▐█▀▜▙ █ ▐█▀▀▀▀ ▀▀▜▙ ▀▀▜▙
18908
18973
  █▘ ███████ ▀▀▀▘▝▀▀▀▀▀ ▀▀▀▀▘▝▀ ▀▘ ▀▀▀▀▀ ▝▀▀▀▘ ▀▀▀▀▘ ▀▀▀▀▘
18909
18974
  `.trim();
18910
- function D1() {
18911
- const e = oi.hex("#2B7384")(z1), t = oi.dim(`v${Dh}`);
18975
+ function M1() {
18976
+ const e = oi.hex("#2B7384")(D1), t = oi.dim(`v${Dh}`);
18912
18977
  return `${e}
18913
18978
  ${t}`;
18914
18979
  }
18915
18980
  function Mh() {
18916
18981
  return Dh;
18917
18982
  }
18918
- function M1(e, t = []) {
18983
+ function U1(e, t = []) {
18919
18984
  const n = new Set(e.map((a) => a.installDir)), s = new Set(
18920
18985
  t.filter((a) => a !== Co)
18921
18986
  ), r = Cs.map((a) => a.dir).filter(
@@ -18927,8 +18992,8 @@ function M1(e, t = []) {
18927
18992
  hint: s.has(a.dir) ? "installed" : n.has(a.dir) ? "detected" : a.dir === xs ? "generic agent skills" : "not detected"
18928
18993
  })), initialValues: i };
18929
18994
  }
18930
- async function U1(e) {
18931
- const t = await fr(e), n = await Oo(e), s = Object.keys(n.targets), { options: r, initialValues: i } = M1(
18995
+ async function B1(e) {
18996
+ const t = await fr(e), n = await Oo(e), s = Object.keys(n.targets), { options: r, initialValues: i } = U1(
18932
18997
  t,
18933
18998
  s
18934
18999
  );
@@ -18949,7 +19014,7 @@ async function U1(e) {
18949
19014
  return o;
18950
19015
  }
18951
19016
  }
18952
- async function B1(e) {
19017
+ async function Z1(e) {
18953
19018
  if (await st(e, { silent: !0 }))
18954
19019
  return { prompted: !1, loggedIn: !0 };
18955
19020
  if (Y$(
@@ -18977,7 +19042,7 @@ async function B1(e) {
18977
19042
  };
18978
19043
  }
18979
19044
  var es = { exports: {} }, Sl;
18980
- function Z1() {
19045
+ function q1() {
18981
19046
  if (Sl) return es.exports;
18982
19047
  Sl = 1;
18983
19048
  var e = String, t = function() {
@@ -18985,9 +19050,9 @@ function Z1() {
18985
19050
  };
18986
19051
  return es.exports = t(), es.exports.createColors = t, es.exports;
18987
19052
  }
18988
- var q1 = /* @__PURE__ */ Z1();
18989
- const lt = /* @__PURE__ */ S$(q1);
18990
- async function G1(e) {
19053
+ var G1 = /* @__PURE__ */ q1();
19054
+ const lt = /* @__PURE__ */ S$(G1);
19055
+ async function J1(e) {
18991
19056
  const t = [];
18992
19057
  for (const n of e.entries)
18993
19058
  if (!(!(n.additions.skills.length > 0 || n.additions.commands.length > 0 || n.removals.skills.length > 0 || n.removals.commands.length > 0) && n.unchanged.skills.length === 0)) {
@@ -19010,12 +19075,12 @@ async function G1(e) {
19010
19075
  `) || "No changes."), e.hasRemovals ? Lo(
19011
19076
  "summary",
19012
19077
  () => Fh({
19013
- message: J1(e),
19078
+ message: V1(e),
19014
19079
  initialValue: !0
19015
19080
  })
19016
19081
  ) : !0;
19017
19082
  }
19018
- function J1(e) {
19083
+ function V1(e) {
19019
19084
  const t = [];
19020
19085
  for (const n of e.entries) {
19021
19086
  if (n.mode === "canonical") continue;
@@ -19026,15 +19091,15 @@ function J1(e) {
19026
19091
  }
19027
19092
  return t.length === 0 ? "Some files recorded in the previous install will be removed. Proceed?" : `Remove Taskless from ${t.join(", ")}?`;
19028
19093
  }
19029
- async function V1(e) {
19094
+ async function W1(e) {
19030
19095
  const t = Date.now(), n = await _e(e.cwd);
19031
19096
  let s, r = [];
19032
19097
  const i = [];
19033
19098
  let o = !1, a = !1;
19034
- console.error(D1()), J$(" Taskless setup ");
19099
+ console.error(M1()), J$(" Taskless setup ");
19035
19100
  try {
19036
- r = await U1(e.cwd);
19037
- const c = await B1(e.cwd);
19101
+ r = await B1(e.cwd);
19102
+ const c = await Z1(e.cwd);
19038
19103
  o = c.prompted, a = c.loggedIn;
19039
19104
  const f = wh(
19040
19105
  r,
@@ -19044,7 +19109,7 @@ async function V1(e) {
19044
19109
  cliVersion: u.cliVersion,
19045
19110
  targets: vh(f)
19046
19111
  });
19047
- if (!await G1(d))
19112
+ if (!await J1(d))
19048
19113
  return cl("Install cancelled. Run `taskless init` to try again."), s = "summary", l({ status: "cancelled" });
19049
19114
  await Vt(e.cwd, {
19050
19115
  onNotice: (p) => Fe.info(p)
@@ -19075,7 +19140,7 @@ async function V1(e) {
19075
19140
  };
19076
19141
  }
19077
19142
  }
19078
- function W1(e) {
19143
+ function K1(e) {
19079
19144
  return e || process.env.CI === "true" || process.env.CI === "1" ? !1 : process.stdout.isTTY === !0 && process.stdin.isTTY === !0;
19080
19145
  }
19081
19146
  const Uh = {
@@ -19102,8 +19167,8 @@ const Uh = {
19102
19167
  },
19103
19168
  async run({ args: e }) {
19104
19169
  const t = D(e.dir ?? process.cwd()), n = await _e(t);
19105
- if (W1(e["no-interactive"])) {
19106
- (await V1({ cwd: t })).status === "cancelled" && (process.exitCode = 1);
19170
+ if (K1(e["no-interactive"])) {
19171
+ (await W1({ cwd: t })).status === "cancelled" && (process.exitCode = 1);
19107
19172
  return;
19108
19173
  }
19109
19174
  !e["no-interactive"] && process.stdout.isTTY !== !0 && console.error(
@@ -19114,7 +19179,7 @@ const Uh = {
19114
19179
  Lh({ commandsInstalled: r.commandsInstalled })
19115
19180
  ), n.capture("cli_installed");
19116
19181
  }
19117
- }, K1 = {
19182
+ }, H1 = {
19118
19183
  meta: {
19119
19184
  name: "update",
19120
19185
  description: "Update Taskless skills in detected tools (non-interactive install)"
@@ -19206,30 +19271,30 @@ function ts(e) {
19206
19271
  }
19207
19272
  return t;
19208
19273
  }
19209
- const H1 = M({
19274
+ const Y1 = M({
19210
19275
  name: C(),
19211
19276
  installedVersion: C().optional(),
19212
19277
  currentVersion: C(),
19213
19278
  current: bt()
19214
- }), Y1 = M({
19215
- name: C(),
19216
- skills: J(H1)
19217
19279
  }), Q1 = M({
19280
+ name: C(),
19281
+ skills: J(Y1)
19282
+ }), X1 = M({
19218
19283
  user: C(),
19219
19284
  email: C(),
19220
19285
  orgs: J(C())
19221
- }), X1 = M({
19286
+ }), eI = M({
19222
19287
  success: it(!0),
19223
19288
  version: C().describe("CLI version"),
19224
- tools: J(Y1).describe("Detected tools and skill status"),
19289
+ tools: J(Q1).describe("Detected tools and skill status"),
19225
19290
  loggedIn: bt().describe("Whether the user is authenticated"),
19226
- auth: Q1.optional().describe("User identity if logged in")
19291
+ auth: X1.optional().describe("User identity if logged in")
19227
19292
  });
19228
19293
  M({
19229
19294
  success: it(!1),
19230
19295
  error: C().describe("Error message")
19231
19296
  });
19232
- const eI = {
19297
+ const tI = {
19233
19298
  meta: {
19234
19299
  name: "info",
19235
19300
  description: "Show Taskless CLI information"
@@ -19267,13 +19332,13 @@ const eI = {
19267
19332
  }
19268
19333
  const i = {
19269
19334
  success: !0,
19270
- version: "0.10.0",
19335
+ version: "0.10.1",
19271
19336
  tools: n,
19272
19337
  loggedIn: s !== void 0,
19273
19338
  auth: r
19274
19339
  };
19275
19340
  if (e.json) {
19276
- const o = X1.safeParse(i);
19341
+ const o = eI.safeParse(i);
19277
19342
  if (!o.success) {
19278
19343
  console.log(
19279
19344
  JSON.stringify(
@@ -19288,7 +19353,7 @@ const eI = {
19288
19353
  console.log(JSON.stringify(o.data));
19289
19354
  return;
19290
19355
  }
19291
- if (console.log(`Taskless CLI v0.10.0
19356
+ if (console.log(`Taskless CLI v0.10.1
19292
19357
  `), n.length === 0)
19293
19358
  console.log("Tools: none detected");
19294
19359
  else {
@@ -19330,22 +19395,22 @@ async function Zh(e) {
19330
19395
  );
19331
19396
  return { token: t, orgSubject: s, repositoryUrl: n };
19332
19397
  }
19333
- const tI = "https://json-schema.org/draft/2020-12/schema", nI = "ast-grep rule", sI = "Used for global rules, rewriters, and pyo3/napi", rI = "object", iI = { rule: { description: "A rule object to find matching AST nodes", $ref: "#/$defs/SerializableRule" }, constraints: { description: "Additional meta variables pattern to filter matching", type: ["object", "null"], additionalProperties: { $ref: "#/$defs/SerializableRule" } }, utils: { description: "Utility rules that can be used in `matches`", type: ["object", "null"], additionalProperties: { $ref: "#/$defs/SerializableRule" } }, transform: { description: `A dictionary for metavariable manipulation. Dict key is the new variable name.
19398
+ const nI = "https://json-schema.org/draft/2020-12/schema", sI = "ast-grep rule", rI = "Used for global rules, rewriters, and pyo3/napi", iI = "object", oI = { rule: { description: "A rule object to find matching AST nodes", $ref: "#/$defs/SerializableRule" }, constraints: { description: "Additional meta variables pattern to filter matching", type: ["object", "null"], additionalProperties: { $ref: "#/$defs/SerializableRule" } }, utils: { description: "Utility rules that can be used in `matches`", type: ["object", "null"], additionalProperties: { $ref: "#/$defs/SerializableRule" } }, transform: { description: `A dictionary for metavariable manipulation. Dict key is the new variable name.
19334
19399
  Dict value is a [transformation] that specifies how meta var is processed.
19335
19400
  See [transformation doc](https://ast-grep.github.io/reference/yaml/transformation.html).`, type: ["object", "null"], additionalProperties: { $ref: "#/$defs/Transformation" } }, fix: { description: `A pattern string or a FixConfig object to auto fix the issue.
19336
19401
  It can reference metavariables appeared in rule.
19337
19402
  See details in fix [object reference](https://ast-grep.github.io/reference/yaml/fix.html#fixconfig).`, anyOf: [{ $ref: "#/$defs/SerializableFixer" }, { type: "null" }] }, id: { description: "Unique, descriptive identifier, e.g., no-unused-variable", type: "string", default: "" }, language: { description: "Specify the language to parse and the file extension to include in matching.", $ref: "#/$defs/Language" }, rewriters: { description: "Rewrite rules for `rewrite` transformation", type: ["array", "null"], items: { $ref: "#/$defs/SerializableRewriter" } }, message: { description: `Main message highlighting why this rule fired. It should be single line and concise,
19338
19403
  but specific enough to be understood without additional context.`, type: "string", default: "" }, note: { description: "Additional notes to elaborate the message and provide potential fix to the issue.\n`notes` can contain markdown syntax, but it cannot reference meta-variables.", type: ["string", "null"] }, severity: { description: "One of: hint, info, warning, or error", $ref: "#/$defs/Severity", default: "hint" }, labels: { description: `Custom label dictionary to configure reporting. Key is the meta-variable name and
19339
- value is the label message and label style.`, type: ["object", "null"], additionalProperties: { $ref: "#/$defs/LabelConfig" } }, files: { description: "Glob patterns to specify that the rule only applies to matching files", type: ["array", "null"], items: { $ref: "#/$defs/RuleFileGlob" } }, ignores: { description: "Glob patterns that exclude rules from applying to files", type: ["array", "null"], items: { $ref: "#/$defs/RuleFileGlob" } }, url: { description: "Documentation link to this rule", type: ["string", "null"] }, metadata: { description: "Extra information for the rule", anyOf: [{ $ref: "#/$defs/Metadata" }, { type: "null" }] } }, oI = ["rule", "language"], aI = /* @__PURE__ */ JSON.parse('{"SerializableRule":{"description":"A rule object to find matching AST nodes. We have three categories of rules in ast-grep.\\n\\n* Atomic: the most basic rule to match AST. We have two variants: Pattern and Kind.\\n\\n* Relational: filter matched target according to their position relative to other nodes.\\n\\n* Composite: use logic operation all/any/not to compose the above rules to larger rules.\\n\\nEvery rule has it\'s unique name so we can combine several rules in one object.","type":"object","properties":{"pattern":{"description":"A pattern string or a pattern object.","$ref":"#/$defs/PatternStyle"},"kind":{"description":"The kind name of the node to match. You can look up code\'s kind names in playground.","type":"string"},"regex":{"description":"A Rust regular expression to match the node\'s text. https://docs.rs/regex/latest/regex/#syntax","type":"string"},"nthChild":{"description":"`nth_child` accepts number, string or object.\\nIt specifies the position in nodes\' sibling list.","$ref":"#/$defs/SerializableNthChild"},"range":{"description":"`range` accepts a range object.\\nthe target node must exactly appear in the range.","$ref":"#/$defs/SerializableRange"},"inside":{"description":"`inside` accepts a relational rule object.\\nthe target node must appear inside of another node matching the `inside` sub-rule.","$ref":"#/$defs/Relation"},"has":{"description":"`has` accepts a relational rule object.\\nthe target node must has a descendant node matching the `has` sub-rule.","$ref":"#/$defs/Relation"},"precedes":{"description":"`precedes` accepts a relational rule object.\\nthe target node must appear before another node matching the `precedes` sub-rule.","$ref":"#/$defs/Relation"},"follows":{"description":"`follows` accepts a relational rule object.\\nthe target node must appear after another node matching the `follows` sub-rule.","$ref":"#/$defs/Relation"},"all":{"description":"A list of sub rules and matches a node if all of sub rules match.\\nThe meta variables of the matched node contain all variables from the sub-rules.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"any":{"description":"A list of sub rules and matches a node if any of sub rules match.\\nThe meta variables of the matched node only contain those of the matched sub-rule.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"not":{"description":"A single sub-rule and matches a node if the sub rule does not match.","$ref":"#/$defs/SerializableRule"},"matches":{"description":"A utility rule id and matches a node if the utility rule matches.","type":"string"}},"additionalProperties":false},"PatternStyle":{"description":"A String pattern will match one single AST node according to pattern syntax.\\nOr an object with field `context`, `selector` and optionally `strictness`.","anyOf":[{"type":"string"},{"type":"object","properties":{"context":{"description":"The surrounding code that helps to resolve any ambiguity in the syntax.","type":"string"},"selector":{"description":"The sub-syntax node kind that is the actual matcher of the pattern.","type":["string","null"]},"strictness":{"description":"Strictness of the pattern. More strict pattern matches fewer nodes.","anyOf":[{"$ref":"#/$defs/Strictness"},{"type":"null"}]}},"additionalProperties":false,"required":["context"]}]},"Strictness":{"oneOf":[{"description":"all nodes are matched","type":"string","const":"cst"},{"description":"all nodes except source trivial nodes are matched.","type":"string","const":"smart"},{"description":"only ast nodes are matched","type":"string","const":"ast"},{"description":"ast-nodes excluding comments are matched","type":"string","const":"relaxed"},{"description":"ast-nodes excluding comments, without text","type":"string","const":"signature"},{"description":"similar to smart, but node kinds are ignored, only text is matched.","type":"string","const":"template"}]},"SerializableNthChild":{"description":"`nthChild` accepts either a number, a string or an object.","anyOf":[{"description":"Simple syntax","$ref":"#/$defs/NthChildSimple"},{"description":"Object style syntax","type":"object","properties":{"position":{"description":"nth-child syntax","$ref":"#/$defs/NthChildSimple"},"ofRule":{"description":"select the nth node that matches the rule, like CSS\'s of syntax","anyOf":[{"$ref":"#/$defs/SerializableRule"},{"type":"null"}]},"reverse":{"description":"matches from the end instead like CSS\'s nth-last-child","type":"boolean","default":false}},"required":["position"]}]},"NthChildSimple":{"description":"A string or number describing the indices of matching nodes in a list of siblings.","anyOf":[{"description":"A number indicating the precise element index","type":"integer","format":"uint","minimum":0},{"description":"Functional notation like CSS\'s An + B","type":"string"}]},"SerializableRange":{"description":"Represents a position in source code using 0-based line and column numbers","type":"object","properties":{"start":{"description":"start position in the source code","$ref":"#/$defs/SerializablePosition"},"end":{"description":"end position in the source code","$ref":"#/$defs/SerializablePosition"}},"required":["start","end"]},"SerializablePosition":{"description":"Represents a zero-based character-wise position in a document","type":"object","properties":{"line":{"description":"0-based line number in the source code","type":"integer","format":"uint","minimum":0},"column":{"description":"0-based column number in the source code","type":["integer","null"],"format":"uint","minimum":0}},"required":["line"]},"Relation":{"description":"A relational rule object, which is a Rule object with two additional fields stopBy and field.","type":"object","properties":{"pattern":{"description":"A pattern string or a pattern object.","$ref":"#/$defs/PatternStyle"},"kind":{"description":"The kind name of the node to match. You can look up code\'s kind names in playground.","type":"string"},"regex":{"description":"A Rust regular expression to match the node\'s text. https://docs.rs/regex/latest/regex/#syntax","type":"string"},"nthChild":{"description":"`nth_child` accepts number, string or object.\\nIt specifies the position in nodes\' sibling list.","$ref":"#/$defs/SerializableNthChild"},"range":{"description":"`range` accepts a range object.\\nthe target node must exactly appear in the range.","$ref":"#/$defs/SerializableRange"},"inside":{"description":"`inside` accepts a relational rule object.\\nthe target node must appear inside of another node matching the `inside` sub-rule.","$ref":"#/$defs/Relation"},"has":{"description":"`has` accepts a relational rule object.\\nthe target node must has a descendant node matching the `has` sub-rule.","$ref":"#/$defs/Relation"},"precedes":{"description":"`precedes` accepts a relational rule object.\\nthe target node must appear before another node matching the `precedes` sub-rule.","$ref":"#/$defs/Relation"},"follows":{"description":"`follows` accepts a relational rule object.\\nthe target node must appear after another node matching the `follows` sub-rule.","$ref":"#/$defs/Relation"},"all":{"description":"A list of sub rules and matches a node if all of sub rules match.\\nThe meta variables of the matched node contain all variables from the sub-rules.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"any":{"description":"A list of sub rules and matches a node if any of sub rules match.\\nThe meta variables of the matched node only contain those of the matched sub-rule.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"not":{"description":"A single sub-rule and matches a node if the sub rule does not match.","$ref":"#/$defs/SerializableRule"},"matches":{"description":"A utility rule id and matches a node if the utility rule matches.","type":"string"},"stopBy":{"$ref":"#/$defs/SerializableStopBy","default":"neighbor"},"field":{"type":["string","null"]}}},"SerializableStopBy":{"description":"Control how the relational rule search should stop","oneOf":[{"type":"string","enum":["neighbor","end"]},{"$ref":"#/$defs/SerializableRule"}]},"Transformation":{"anyOf":[{"type":"string"},{"$ref":"#/$defs/Trans"}]},"Trans":{"description":"Represents a transformation that can be applied to a matched AST node.\\nAvailable transformations are `substring`, `replace` and `convert`.","oneOf":[{"type":"object","properties":{"substring":{"$ref":"#/$defs/Substring"}},"required":["substring"],"additionalProperties":false},{"type":"object","properties":{"replace":{"$ref":"#/$defs/Replace"}},"required":["replace"],"additionalProperties":false},{"type":"object","properties":{"convert":{"$ref":"#/$defs/Convert"}},"required":["convert"],"additionalProperties":false},{"type":"object","properties":{"rewrite":{"$ref":"#/$defs/Rewrite"}},"required":["rewrite"],"additionalProperties":false}]},"Substring":{"description":"Extracts a substring from the meta variable\'s text content.\\n\\nBoth `start_char` and `end_char` support negative indexing,\\nwhich counts character from the end of an array, moving backwards.","type":"object","properties":{"source":{"description":"source meta variable to be transformed","type":"string"},"startChar":{"description":"optional starting character index of the substring, defaults to 0.","type":["integer","null"],"format":"int32"},"endChar":{"description":"optional ending character index of the substring, defaults to the end of the string.","type":["integer","null"],"format":"int32"}},"required":["source"]},"Replace":{"description":"Replaces a substring in the meta variable\'s text content with another string.","type":"object","properties":{"source":{"description":"source meta variable to be transformed","type":"string"},"replace":{"description":"a regex to find substring to be replaced","type":"string"},"by":{"description":"the replacement string","type":"string"}},"required":["source","replace","by"]},"Convert":{"description":"Converts the source meta variable\'s text content to a specified case format.","type":"object","properties":{"source":{"description":"source meta variable to be transformed","type":"string"},"toCase":{"description":"the target case format to convert the text content to","$ref":"#/$defs/StringCase"},"separatedBy":{"description":"optional separators to specify how to separate word","type":["array","null"],"items":{"$ref":"#/$defs/Separator"}}},"required":["source","toCase"]},"StringCase":{"description":"An enumeration representing different cases for strings.","type":"string","enum":["lowerCase","upperCase","capitalize","camelCase","snakeCase","kebabCase","pascalCase"]},"Separator":{"description":"Separator to split string. e.g. `user_accountName` -> `user`, `accountName`\\nIt will be rejoin according to `StringCase`.","type":"string","enum":["caseChange","dash","dot","slash","space","underscore"]},"Rewrite":{"type":"object","properties":{"source":{"type":"string"},"rewriters":{"type":"array","items":{"type":"string"}},"joinBy":{"type":["string","null"]}},"required":["source","rewriters"]},"SerializableFixer":{"description":"A pattern string or fix object to auto fix the issue.\\nIt can reference metavariables appeared in rule.","anyOf":[{"type":"string"},{"$ref":"#/$defs/SerializableFixConfig"},{"type":"array","items":{"$ref":"#/$defs/SerializableFixConfig"}}]},"SerializableFixConfig":{"type":"object","properties":{"template":{"type":"string"},"expandEnd":{"$ref":"#/$defs/Relation"},"expandStart":{"$ref":"#/$defs/Relation"},"title":{"type":["string","null"]}},"required":["template"]},"Language":{"description":"Placeholder for language, used in JSON schema only.","type":"string","example":"typescript"},"SerializableRewriter":{"description":"Used for global rules, rewriters, and pyo3/napi","type":"object","properties":{"rule":{"description":"A rule object to find matching AST nodes","$ref":"#/$defs/SerializableRule"},"constraints":{"description":"Additional meta variables pattern to filter matching","type":["object","null"],"additionalProperties":{"$ref":"#/$defs/SerializableRule"}},"utils":{"description":"Utility rules that can be used in `matches`","type":["object","null"],"additionalProperties":{"$ref":"#/$defs/SerializableRule"}},"transform":{"description":"A dictionary for metavariable manipulation. Dict key is the new variable name.\\nDict value is a [transformation] that specifies how meta var is processed.\\nSee [transformation doc](https://ast-grep.github.io/reference/yaml/transformation.html).","type":["object","null"],"additionalProperties":{"$ref":"#/$defs/Transformation"}},"fix":{"description":"A pattern string or a FixConfig object to auto fix the issue.\\nIt can reference metavariables appeared in rule.\\nSee details in fix [object reference](https://ast-grep.github.io/reference/yaml/fix.html#fixconfig).","anyOf":[{"$ref":"#/$defs/SerializableFixer"},{"type":"null"}]},"id":{"description":"Unique, descriptive identifier, e.g., no-unused-variable","type":"string"}},"required":["rule","id"]},"Severity":{"oneOf":[{"description":"A kind reminder for code with potential improvement.","type":"string","const":"hint"},{"description":"A suggestion that code can be improved or optimized.","type":"string","const":"info"},{"description":"A warning that code might produce bugs or does not follow best practice.","type":"string","const":"warning"},{"description":"An error that code produces bugs or has logic errors.","type":"string","const":"error"},{"description":"Turns off the rule.","type":"string","const":"off"}]},"LabelConfig":{"type":"object","properties":{"style":{"$ref":"#/$defs/LabelStyle"},"message":{"type":["string","null"]}},"required":["style"]},"LabelStyle":{"oneOf":[{"description":"Labels that describe the primary cause of a diagnostic.","type":"string","const":"primary"},{"description":"Labels that provide additional context for a diagnostic.","type":"string","const":"secondary"}]},"RuleFileGlob":{"anyOf":[{"description":"A glob pattern string","type":"string"},{"type":"object","properties":{"glob":{"description":"A glob pattern string","type":"string"},"caseInsensitive":{"description":"Whether the glob matching is case insensitive","type":"boolean","default":false}},"required":["glob"]}]},"Metadata":{"description":"Additional metadata for the rule, can be used to store extra information.","type":"object","additionalProperties":true}}'), lI = "Generated by fetch-ast-grep-schema.ts at 2026-03-31T02:04:24.481Z from ast-grep v0.41.0 (https://raw.githubusercontent.com/ast-grep/ast-grep/0.41.0/schemas/rule.json)", cI = {
19340
- $schema: tI,
19341
- title: nI,
19342
- description: sI,
19343
- type: rI,
19344
- properties: iI,
19345
- required: oI,
19346
- $defs: aI,
19347
- $comment: lI
19348
- }, uI = _k(cI), fI = [
19404
+ value is the label message and label style.`, type: ["object", "null"], additionalProperties: { $ref: "#/$defs/LabelConfig" } }, files: { description: "Glob patterns to specify that the rule only applies to matching files", type: ["array", "null"], items: { $ref: "#/$defs/RuleFileGlob" } }, ignores: { description: "Glob patterns that exclude rules from applying to files", type: ["array", "null"], items: { $ref: "#/$defs/RuleFileGlob" } }, url: { description: "Documentation link to this rule", type: ["string", "null"] }, metadata: { description: "Extra information for the rule", anyOf: [{ $ref: "#/$defs/Metadata" }, { type: "null" }] } }, aI = ["rule", "language"], lI = /* @__PURE__ */ JSON.parse('{"SerializableRule":{"description":"A rule object to find matching AST nodes. We have three categories of rules in ast-grep.\\n\\n* Atomic: the most basic rule to match AST. We have two variants: Pattern and Kind.\\n\\n* Relational: filter matched target according to their position relative to other nodes.\\n\\n* Composite: use logic operation all/any/not to compose the above rules to larger rules.\\n\\nEvery rule has it\'s unique name so we can combine several rules in one object.","type":"object","properties":{"pattern":{"description":"A pattern string or a pattern object.","$ref":"#/$defs/PatternStyle"},"kind":{"description":"The kind name of the node to match. You can look up code\'s kind names in playground.","type":"string"},"regex":{"description":"A Rust regular expression to match the node\'s text. https://docs.rs/regex/latest/regex/#syntax","type":"string"},"nthChild":{"description":"`nth_child` accepts number, string or object.\\nIt specifies the position in nodes\' sibling list.","$ref":"#/$defs/SerializableNthChild"},"range":{"description":"`range` accepts a range object.\\nthe target node must exactly appear in the range.","$ref":"#/$defs/SerializableRange"},"inside":{"description":"`inside` accepts a relational rule object.\\nthe target node must appear inside of another node matching the `inside` sub-rule.","$ref":"#/$defs/Relation"},"has":{"description":"`has` accepts a relational rule object.\\nthe target node must has a descendant node matching the `has` sub-rule.","$ref":"#/$defs/Relation"},"precedes":{"description":"`precedes` accepts a relational rule object.\\nthe target node must appear before another node matching the `precedes` sub-rule.","$ref":"#/$defs/Relation"},"follows":{"description":"`follows` accepts a relational rule object.\\nthe target node must appear after another node matching the `follows` sub-rule.","$ref":"#/$defs/Relation"},"all":{"description":"A list of sub rules and matches a node if all of sub rules match.\\nThe meta variables of the matched node contain all variables from the sub-rules.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"any":{"description":"A list of sub rules and matches a node if any of sub rules match.\\nThe meta variables of the matched node only contain those of the matched sub-rule.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"not":{"description":"A single sub-rule and matches a node if the sub rule does not match.","$ref":"#/$defs/SerializableRule"},"matches":{"description":"A utility rule id and matches a node if the utility rule matches.","type":"string"}},"additionalProperties":false},"PatternStyle":{"description":"A String pattern will match one single AST node according to pattern syntax.\\nOr an object with field `context`, `selector` and optionally `strictness`.","anyOf":[{"type":"string"},{"type":"object","properties":{"context":{"description":"The surrounding code that helps to resolve any ambiguity in the syntax.","type":"string"},"selector":{"description":"The sub-syntax node kind that is the actual matcher of the pattern.","type":["string","null"]},"strictness":{"description":"Strictness of the pattern. More strict pattern matches fewer nodes.","anyOf":[{"$ref":"#/$defs/Strictness"},{"type":"null"}]}},"additionalProperties":false,"required":["context"]}]},"Strictness":{"oneOf":[{"description":"all nodes are matched","type":"string","const":"cst"},{"description":"all nodes except source trivial nodes are matched.","type":"string","const":"smart"},{"description":"only ast nodes are matched","type":"string","const":"ast"},{"description":"ast-nodes excluding comments are matched","type":"string","const":"relaxed"},{"description":"ast-nodes excluding comments, without text","type":"string","const":"signature"},{"description":"similar to smart, but node kinds are ignored, only text is matched.","type":"string","const":"template"}]},"SerializableNthChild":{"description":"`nthChild` accepts either a number, a string or an object.","anyOf":[{"description":"Simple syntax","$ref":"#/$defs/NthChildSimple"},{"description":"Object style syntax","type":"object","properties":{"position":{"description":"nth-child syntax","$ref":"#/$defs/NthChildSimple"},"ofRule":{"description":"select the nth node that matches the rule, like CSS\'s of syntax","anyOf":[{"$ref":"#/$defs/SerializableRule"},{"type":"null"}]},"reverse":{"description":"matches from the end instead like CSS\'s nth-last-child","type":"boolean","default":false}},"required":["position"]}]},"NthChildSimple":{"description":"A string or number describing the indices of matching nodes in a list of siblings.","anyOf":[{"description":"A number indicating the precise element index","type":"integer","format":"uint","minimum":0},{"description":"Functional notation like CSS\'s An + B","type":"string"}]},"SerializableRange":{"description":"Represents a position in source code using 0-based line and column numbers","type":"object","properties":{"start":{"description":"start position in the source code","$ref":"#/$defs/SerializablePosition"},"end":{"description":"end position in the source code","$ref":"#/$defs/SerializablePosition"}},"required":["start","end"]},"SerializablePosition":{"description":"Represents a zero-based character-wise position in a document","type":"object","properties":{"line":{"description":"0-based line number in the source code","type":"integer","format":"uint","minimum":0},"column":{"description":"0-based column number in the source code","type":["integer","null"],"format":"uint","minimum":0}},"required":["line"]},"Relation":{"description":"A relational rule object, which is a Rule object with two additional fields stopBy and field.","type":"object","properties":{"pattern":{"description":"A pattern string or a pattern object.","$ref":"#/$defs/PatternStyle"},"kind":{"description":"The kind name of the node to match. You can look up code\'s kind names in playground.","type":"string"},"regex":{"description":"A Rust regular expression to match the node\'s text. https://docs.rs/regex/latest/regex/#syntax","type":"string"},"nthChild":{"description":"`nth_child` accepts number, string or object.\\nIt specifies the position in nodes\' sibling list.","$ref":"#/$defs/SerializableNthChild"},"range":{"description":"`range` accepts a range object.\\nthe target node must exactly appear in the range.","$ref":"#/$defs/SerializableRange"},"inside":{"description":"`inside` accepts a relational rule object.\\nthe target node must appear inside of another node matching the `inside` sub-rule.","$ref":"#/$defs/Relation"},"has":{"description":"`has` accepts a relational rule object.\\nthe target node must has a descendant node matching the `has` sub-rule.","$ref":"#/$defs/Relation"},"precedes":{"description":"`precedes` accepts a relational rule object.\\nthe target node must appear before another node matching the `precedes` sub-rule.","$ref":"#/$defs/Relation"},"follows":{"description":"`follows` accepts a relational rule object.\\nthe target node must appear after another node matching the `follows` sub-rule.","$ref":"#/$defs/Relation"},"all":{"description":"A list of sub rules and matches a node if all of sub rules match.\\nThe meta variables of the matched node contain all variables from the sub-rules.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"any":{"description":"A list of sub rules and matches a node if any of sub rules match.\\nThe meta variables of the matched node only contain those of the matched sub-rule.","type":"array","items":{"$ref":"#/$defs/SerializableRule"}},"not":{"description":"A single sub-rule and matches a node if the sub rule does not match.","$ref":"#/$defs/SerializableRule"},"matches":{"description":"A utility rule id and matches a node if the utility rule matches.","type":"string"},"stopBy":{"$ref":"#/$defs/SerializableStopBy","default":"neighbor"},"field":{"type":["string","null"]}}},"SerializableStopBy":{"description":"Control how the relational rule search should stop","oneOf":[{"type":"string","enum":["neighbor","end"]},{"$ref":"#/$defs/SerializableRule"}]},"Transformation":{"anyOf":[{"type":"string"},{"$ref":"#/$defs/Trans"}]},"Trans":{"description":"Represents a transformation that can be applied to a matched AST node.\\nAvailable transformations are `substring`, `replace` and `convert`.","oneOf":[{"type":"object","properties":{"substring":{"$ref":"#/$defs/Substring"}},"required":["substring"],"additionalProperties":false},{"type":"object","properties":{"replace":{"$ref":"#/$defs/Replace"}},"required":["replace"],"additionalProperties":false},{"type":"object","properties":{"convert":{"$ref":"#/$defs/Convert"}},"required":["convert"],"additionalProperties":false},{"type":"object","properties":{"rewrite":{"$ref":"#/$defs/Rewrite"}},"required":["rewrite"],"additionalProperties":false}]},"Substring":{"description":"Extracts a substring from the meta variable\'s text content.\\n\\nBoth `start_char` and `end_char` support negative indexing,\\nwhich counts character from the end of an array, moving backwards.","type":"object","properties":{"source":{"description":"source meta variable to be transformed","type":"string"},"startChar":{"description":"optional starting character index of the substring, defaults to 0.","type":["integer","null"],"format":"int32"},"endChar":{"description":"optional ending character index of the substring, defaults to the end of the string.","type":["integer","null"],"format":"int32"}},"required":["source"]},"Replace":{"description":"Replaces a substring in the meta variable\'s text content with another string.","type":"object","properties":{"source":{"description":"source meta variable to be transformed","type":"string"},"replace":{"description":"a regex to find substring to be replaced","type":"string"},"by":{"description":"the replacement string","type":"string"}},"required":["source","replace","by"]},"Convert":{"description":"Converts the source meta variable\'s text content to a specified case format.","type":"object","properties":{"source":{"description":"source meta variable to be transformed","type":"string"},"toCase":{"description":"the target case format to convert the text content to","$ref":"#/$defs/StringCase"},"separatedBy":{"description":"optional separators to specify how to separate word","type":["array","null"],"items":{"$ref":"#/$defs/Separator"}}},"required":["source","toCase"]},"StringCase":{"description":"An enumeration representing different cases for strings.","type":"string","enum":["lowerCase","upperCase","capitalize","camelCase","snakeCase","kebabCase","pascalCase"]},"Separator":{"description":"Separator to split string. e.g. `user_accountName` -> `user`, `accountName`\\nIt will be rejoin according to `StringCase`.","type":"string","enum":["caseChange","dash","dot","slash","space","underscore"]},"Rewrite":{"type":"object","properties":{"source":{"type":"string"},"rewriters":{"type":"array","items":{"type":"string"}},"joinBy":{"type":["string","null"]}},"required":["source","rewriters"]},"SerializableFixer":{"description":"A pattern string or fix object to auto fix the issue.\\nIt can reference metavariables appeared in rule.","anyOf":[{"type":"string"},{"$ref":"#/$defs/SerializableFixConfig"},{"type":"array","items":{"$ref":"#/$defs/SerializableFixConfig"}}]},"SerializableFixConfig":{"type":"object","properties":{"template":{"type":"string"},"expandEnd":{"$ref":"#/$defs/Relation"},"expandStart":{"$ref":"#/$defs/Relation"},"title":{"type":["string","null"]}},"required":["template"]},"Language":{"description":"Placeholder for language, used in JSON schema only.","type":"string","example":"typescript"},"SerializableRewriter":{"description":"Used for global rules, rewriters, and pyo3/napi","type":"object","properties":{"rule":{"description":"A rule object to find matching AST nodes","$ref":"#/$defs/SerializableRule"},"constraints":{"description":"Additional meta variables pattern to filter matching","type":["object","null"],"additionalProperties":{"$ref":"#/$defs/SerializableRule"}},"utils":{"description":"Utility rules that can be used in `matches`","type":["object","null"],"additionalProperties":{"$ref":"#/$defs/SerializableRule"}},"transform":{"description":"A dictionary for metavariable manipulation. Dict key is the new variable name.\\nDict value is a [transformation] that specifies how meta var is processed.\\nSee [transformation doc](https://ast-grep.github.io/reference/yaml/transformation.html).","type":["object","null"],"additionalProperties":{"$ref":"#/$defs/Transformation"}},"fix":{"description":"A pattern string or a FixConfig object to auto fix the issue.\\nIt can reference metavariables appeared in rule.\\nSee details in fix [object reference](https://ast-grep.github.io/reference/yaml/fix.html#fixconfig).","anyOf":[{"$ref":"#/$defs/SerializableFixer"},{"type":"null"}]},"id":{"description":"Unique, descriptive identifier, e.g., no-unused-variable","type":"string"}},"required":["rule","id"]},"Severity":{"oneOf":[{"description":"A kind reminder for code with potential improvement.","type":"string","const":"hint"},{"description":"A suggestion that code can be improved or optimized.","type":"string","const":"info"},{"description":"A warning that code might produce bugs or does not follow best practice.","type":"string","const":"warning"},{"description":"An error that code produces bugs or has logic errors.","type":"string","const":"error"},{"description":"Turns off the rule.","type":"string","const":"off"}]},"LabelConfig":{"type":"object","properties":{"style":{"$ref":"#/$defs/LabelStyle"},"message":{"type":["string","null"]}},"required":["style"]},"LabelStyle":{"oneOf":[{"description":"Labels that describe the primary cause of a diagnostic.","type":"string","const":"primary"},{"description":"Labels that provide additional context for a diagnostic.","type":"string","const":"secondary"}]},"RuleFileGlob":{"anyOf":[{"description":"A glob pattern string","type":"string"},{"type":"object","properties":{"glob":{"description":"A glob pattern string","type":"string"},"caseInsensitive":{"description":"Whether the glob matching is case insensitive","type":"boolean","default":false}},"required":["glob"]}]},"Metadata":{"description":"Additional metadata for the rule, can be used to store extra information.","type":"object","additionalProperties":true}}'), cI = "Generated by fetch-ast-grep-schema.ts at 2026-03-31T02:04:24.481Z from ast-grep v0.41.0 (https://raw.githubusercontent.com/ast-grep/ast-grep/0.41.0/schemas/rule.json)", uI = {
19405
+ $schema: nI,
19406
+ title: sI,
19407
+ description: rI,
19408
+ type: iI,
19409
+ properties: oI,
19410
+ required: aI,
19411
+ $defs: lI,
19412
+ $comment: cI
19413
+ }, fI = _k(uI), dI = [
19349
19414
  "id",
19350
19415
  "language",
19351
19416
  "severity",
@@ -19384,22 +19449,22 @@ function Rs(e, t = "") {
19384
19449
  }
19385
19450
  return n;
19386
19451
  }
19387
- const dI = /^[a-z0-9][a-z0-9-]*$/;
19452
+ const hI = /^[a-z0-9][a-z0-9-]*$/;
19388
19453
  function xn(e) {
19389
- return dI.test(e);
19454
+ return hI.test(e);
19390
19455
  }
19391
- function hI(e) {
19456
+ function pI(e) {
19392
19457
  return e.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
19393
19458
  }
19394
- function pI(e) {
19395
- const t = uI.safeParse(e);
19459
+ function mI(e) {
19460
+ const t = fI.safeParse(e);
19396
19461
  return t.success ? { valid: !0, errors: [] } : { valid: !1, errors: t.error.issues.map(
19397
19462
  (s) => `${s.path.join(".")}: ${s.message}`
19398
19463
  ) };
19399
19464
  }
19400
- async function mI(e, t, n) {
19465
+ async function gI(e, t, n) {
19401
19466
  const s = [];
19402
- for (const o of fI)
19467
+ for (const o of dI)
19403
19468
  (!(o in n) || n[o] === void 0 || n[o] === null || n[o] === "") && s.push(`Missing required field: ${o}`);
19404
19469
  for (const o of ["rule", "constraints", "utils"]) {
19405
19470
  const a = n[o];
@@ -19431,7 +19496,7 @@ async function mI(e, t, n) {
19431
19496
  `No test file found for rule "${t}" in .taskless/rule-tests/`
19432
19497
  ), { valid: s.length === 0, errors: s, hasTestFile: i };
19433
19498
  }
19434
- async function gI(e, t) {
19499
+ async function yI(e, t) {
19435
19500
  await lc(e);
19436
19501
  const n = _i();
19437
19502
  return new Promise((s) => {
@@ -19443,7 +19508,7 @@ async function gI(e, t) {
19443
19508
  ".taskless/sgconfig.yml",
19444
19509
  "--skip-snapshot-tests",
19445
19510
  "--filter",
19446
- `^${hI(t)}$`
19511
+ `^${pI(t)}$`
19447
19512
  ],
19448
19513
  {
19449
19514
  cwd: e,
@@ -19481,7 +19546,7 @@ async function gI(e, t) {
19481
19546
  });
19482
19547
  });
19483
19548
  }
19484
- async function yI(e, t) {
19549
+ async function bI(e, t) {
19485
19550
  if (!xn(t)) {
19486
19551
  const l = `Invalid rule ID "${t}". Rule IDs must be lowercase alphanumeric with hyphens.`;
19487
19552
  return {
@@ -19537,11 +19602,11 @@ async function yI(e, t) {
19537
19602
  }
19538
19603
  };
19539
19604
  }
19540
- const i = pI(r), o = await mI(
19605
+ const i = mI(r), o = await gI(
19541
19606
  e,
19542
19607
  t,
19543
19608
  r && typeof r == "object" ? r : {}
19544
- ), a = o.hasTestFile ? await gI(e, t) : {
19609
+ ), a = o.hasTestFile ? await yI(e, t) : {
19545
19610
  valid: !1,
19546
19611
  errors: ["Skipped: no test file found"],
19547
19612
  passed: 0,
@@ -19569,7 +19634,7 @@ function qh() {
19569
19634
  ].join(`
19570
19635
  `);
19571
19636
  }
19572
- async function bI(e, t) {
19637
+ async function wI(e, t) {
19573
19638
  const n = Ls(e), { data: s, error: r, response: i } = await n.POST("/cli/api/rule", {
19574
19639
  body: t
19575
19640
  });
@@ -19604,7 +19669,7 @@ async function Gh(e, t) {
19604
19669
  }
19605
19670
  return s;
19606
19671
  }
19607
- async function wI(e, t, n) {
19672
+ async function vI(e, t, n) {
19608
19673
  const s = Ls(e), { data: r, error: i, response: o } = await s.POST(
19609
19674
  "/cli/api/rule/{ruleId}/iterate",
19610
19675
  {
@@ -19650,7 +19715,7 @@ async function Wh(e, t) {
19650
19715
  }
19651
19716
  return s;
19652
19717
  }
19653
- async function vI(e, t) {
19718
+ async function kI(e, t) {
19654
19719
  if (!xn(t))
19655
19720
  return null;
19656
19721
  const n = O(e, ".taskless", "rule-metadata", `${t}.yml`);
@@ -19663,7 +19728,7 @@ async function vI(e, t) {
19663
19728
  throw s;
19664
19729
  }
19665
19730
  }
19666
- async function kI(e, t) {
19731
+ async function _I(e, t) {
19667
19732
  if (!xn(t))
19668
19733
  return !1;
19669
19734
  const n = O(e, ".taskless", "rules"), s = O(n, `${t}.yml`);
@@ -19702,7 +19767,7 @@ async function kI(e, t) {
19702
19767
  }
19703
19768
  return r;
19704
19769
  }
19705
- const _I = M({
19770
+ const SI = M({
19706
19771
  id: C().describe("Rule ID"),
19707
19772
  ticketId: C().describe("Ticket ID that produced this rule"),
19708
19773
  installationId: C().optional().describe("GitHub App installation ID (absent for public repos)"),
@@ -19733,17 +19798,17 @@ M({
19733
19798
  const ai = M({
19734
19799
  valid: bt(),
19735
19800
  errors: J(C()).describe("Human-readable error messages")
19736
- }), SI = ai.extend({
19801
+ }), $I = ai.extend({
19737
19802
  passed: Qe().describe("Number of test cases that passed"),
19738
19803
  failed: Qe().describe("Number of test cases that failed")
19739
- }), $I = M({
19804
+ }), II = M({
19740
19805
  success: bt().describe("True if all layers passed"),
19741
19806
  ruleId: C(),
19742
19807
  schema: ai.describe("Layer 1: Zod schema validation"),
19743
19808
  requirements: ai.describe(
19744
19809
  "Layer 2: Taskless requirement checks"
19745
19810
  ),
19746
- tests: SI.describe("Layer 3: sg test execution")
19811
+ tests: $I.describe("Layer 3: sg test execution")
19747
19812
  });
19748
19813
  M({
19749
19814
  success: it(!1),
@@ -19762,7 +19827,7 @@ function Yh() {
19762
19827
  ].join(`
19763
19828
  `);
19764
19829
  }
19765
- const II = {
19830
+ const EI = {
19766
19831
  meta: {
19767
19832
  name: "create",
19768
19833
  description: "Create a new rule from a JSON file (use --from to specify the input file)"
@@ -19841,7 +19906,7 @@ const II = {
19841
19906
  }
19842
19907
  let f;
19843
19908
  try {
19844
- f = (await bI(c.token, {
19909
+ f = (await wI(c.token, {
19845
19910
  orgId: c.orgSubject,
19846
19911
  repositoryUrl: c.repositoryUrl,
19847
19912
  prompt: l.prompt,
@@ -19940,7 +20005,7 @@ const II = {
19940
20005
  r !== void 0 && n.capture("cli_rule_created", { ruleCount: r });
19941
20006
  }
19942
20007
  }
19943
- }, EI = {
20008
+ }, TI = {
19944
20009
  meta: {
19945
20010
  name: "improve",
19946
20011
  description: "Improve an existing rule with guidance (use --from to specify the input file)"
@@ -20019,7 +20084,7 @@ const II = {
20019
20084
  }
20020
20085
  let f;
20021
20086
  try {
20022
- f = (await wI(c.token, l.ruleId, {
20087
+ f = (await vI(c.token, l.ruleId, {
20023
20088
  orgId: c.orgSubject,
20024
20089
  guidance: l.guidance,
20025
20090
  references: l.references
@@ -20122,7 +20187,7 @@ const II = {
20122
20187
  });
20123
20188
  }
20124
20189
  }
20125
- }, TI = {
20190
+ }, AI = {
20126
20191
  meta: {
20127
20192
  name: "meta",
20128
20193
  description: "Show sidecar metadata for a rule"
@@ -20154,14 +20219,14 @@ const II = {
20154
20219
  function n(r, i = "INTERNAL_ERROR") {
20155
20220
  throw e.json ? console.log(JSON.stringify(Te(i, r))) : console.error(`Error: ${r}`), process.exitCode = 1, new mt(r);
20156
20221
  }
20157
- const s = await vI(t, e.id);
20222
+ const s = await kI(t, e.id);
20158
20223
  if (s || n(
20159
20224
  `No metadata found for rule "${e.id}". Expected .taskless/rule-metadata/${e.id}.yml`,
20160
20225
  "RULE_NOT_FOUND"
20161
20226
  ), e.json) {
20162
20227
  let r;
20163
20228
  try {
20164
- r = _I.parse({ id: e.id, ...s });
20229
+ r = SI.parse({ id: e.id, ...s });
20165
20230
  } catch (i) {
20166
20231
  i instanceof ji && n(
20167
20232
  `Invalid metadata for rule "${e.id}": ${i.issues.map((o) => o.message).join(", ")}`,
@@ -20176,7 +20241,7 @@ const II = {
20176
20241
  console.log(` ${r}: ${String(i)}`);
20177
20242
  }
20178
20243
  }
20179
- }, AI = {
20244
+ }, OI = {
20180
20245
  meta: {
20181
20246
  name: "delete",
20182
20247
  description: "Delete a rule and its test files"
@@ -20207,7 +20272,7 @@ const II = {
20207
20272
  const t = D(e.dir ?? process.cwd()), n = await _e(t), s = e.id;
20208
20273
  let r = !1;
20209
20274
  try {
20210
- if (await kI(t, s))
20275
+ if (await _I(t, s))
20211
20276
  e.json || console.log(`Deleted rule "${s}" and associated test files.`), r = !0;
20212
20277
  else {
20213
20278
  const o = `Rule "${s}" not found in .taskless/rules/${s}.yml`;
@@ -20219,7 +20284,7 @@ const II = {
20219
20284
  r && n.capture("cli_rule_deleted");
20220
20285
  }
20221
20286
  }
20222
- }, OI = {
20287
+ }, CI = {
20223
20288
  meta: {
20224
20289
  name: "verify",
20225
20290
  description: "Validate a rule against the ast-grep schema and run tests"
@@ -20259,9 +20324,9 @@ const II = {
20259
20324
  ), process.exitCode = 1;
20260
20325
  return;
20261
20326
  }
20262
- const n = await yI(t, e.id);
20327
+ const n = await bI(t, e.id);
20263
20328
  if (e.json)
20264
- console.log(JSON.stringify($I.parse(n)));
20329
+ console.log(JSON.stringify(II.parse(n)));
20265
20330
  else {
20266
20331
  console.log(`Verifying rule: ${n.ruleId}
20267
20332
  `), console.log(
@@ -20286,20 +20351,20 @@ Result: ${n.success ? "✓ All checks passed" : "✗ Verification failed"}`
20286
20351
  }
20287
20352
  n.success || (process.exitCode = 1);
20288
20353
  }
20289
- }, CI = {
20354
+ }, xI = {
20290
20355
  meta: {
20291
20356
  name: "rule",
20292
20357
  description: "Manage Taskless rules"
20293
20358
  },
20294
20359
  subCommands: {
20295
- create: II,
20296
- improve: EI,
20297
- meta: TI,
20298
- delete: AI,
20299
- verify: OI
20360
+ create: EI,
20361
+ improve: TI,
20362
+ meta: AI,
20363
+ delete: OI,
20364
+ verify: CI
20300
20365
  }
20301
20366
  };
20302
- function xI(e) {
20367
+ function FI(e) {
20303
20368
  const t = /* @__PURE__ */ new Set(["-d", "--dir"]), n = [];
20304
20369
  for (let r = 0; r < e.length; r++) {
20305
20370
  const i = e[r];
@@ -20313,7 +20378,7 @@ function xI(e) {
20313
20378
  const s = n[0];
20314
20379
  return s === "rule" && n[1] ? `rule ${n[1]}` : s;
20315
20380
  }
20316
- function FI(e) {
20381
+ function NI(e) {
20317
20382
  for (let t = 0; t < e.length; t++) {
20318
20383
  const n = e[t];
20319
20384
  if ((n === "-d" || n === "--dir") && e[t + 1])
@@ -20323,7 +20388,7 @@ function FI(e) {
20323
20388
  }
20324
20389
  return process.cwd();
20325
20390
  }
20326
- function NI(e, t) {
20391
+ function PI(e, t) {
20327
20392
  if (t.error !== void 0) {
20328
20393
  const n = t.error instanceof mt && t.error.code ? t.error.code : "INTERNAL_ERROR";
20329
20394
  e.capture("cli_error", { command: t.command, code: n });
@@ -20338,17 +20403,17 @@ function NI(e, t) {
20338
20403
  }
20339
20404
  const Qh = {
20340
20405
  init: Uh,
20341
- update: K1,
20342
- info: eI,
20406
+ update: H1,
20407
+ info: tI,
20343
20408
  detect: MS,
20344
20409
  check: cS,
20345
20410
  auth: hy,
20346
- onboard: I1,
20347
- rule: CI
20348
- }, $l = $1(Qh), PI = {
20411
+ onboard: E1,
20412
+ rule: xI
20413
+ }, $l = I1(Qh), RI = {
20349
20414
  meta: {
20350
20415
  name: "taskless",
20351
- version: "0.10.0",
20416
+ version: "0.10.1",
20352
20417
  description: "Taskless CLI"
20353
20418
  },
20354
20419
  args: {
@@ -20392,19 +20457,19 @@ const Qh = {
20392
20457
  "Taskless CLI — non-interactive context detected.\n For interactive install, run from a terminal.\n For scripted install, run `taskless init --no-interactive`.\n For agent recipes, run `taskless help` (no args) for the topic index.\n"
20393
20458
  ), await hs($l, { rawArgs: ["help", ...e] });
20394
20459
  }
20395
- }, li = process.argv.slice(2), Xh = FI(li), RI = Date.now(), Il = await iy(Xh);
20460
+ }, li = process.argv.slice(2), Xh = NI(li), jI = Date.now(), Il = await iy(Xh);
20396
20461
  let Lr;
20397
20462
  try {
20398
- await hs(PI, { rawArgs: li });
20463
+ await hs(RI, { rawArgs: li });
20399
20464
  } catch (e) {
20400
20465
  Lr = e, e instanceof mt || (process.exitCode = 1, console.error(e instanceof Error ? e.message : String(e)));
20401
20466
  } finally {
20402
20467
  try {
20403
20468
  const e = await _e(Xh), t = Lr === void 0 && (process.exitCode === void 0 || process.exitCode === 0);
20404
- NI(e, {
20405
- command: xI(li),
20469
+ PI(e, {
20470
+ command: FI(li),
20406
20471
  success: t,
20407
- durationMs: Date.now() - RI,
20472
+ durationMs: Date.now() - jI,
20408
20473
  anonymous: Il.anonymous,
20409
20474
  loggedIn: Il.loggedIn,
20410
20475
  error: Lr
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taskless/cli",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",