maxc-cli 0.1.5__tar.gz → 0.1.7__tar.gz

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 (62) hide show
  1. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/PKG-INFO +4 -2
  2. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/setup.py +4 -2
  3. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/__init__.py +1 -1
  4. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/query.py +8 -1
  5. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/cli.py +5 -0
  6. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/exceptions.py +12 -0
  7. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/SKILL.md +2 -9
  8. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli.egg-info/PKG-INFO +4 -2
  9. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/MANIFEST.in +0 -0
  10. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/README.md +0 -0
  11. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/pyproject.toml +0 -0
  12. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/scripts/regression_test.py +0 -0
  13. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/setup.cfg +0 -0
  14. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/__main__.py +0 -0
  15. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/app.py +0 -0
  16. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/audit.py +0 -0
  17. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/auth_providers.py +0 -0
  18. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/__init__.py +0 -0
  19. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/auth.py +0 -0
  20. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/catalog.py +0 -0
  21. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/data.py +0 -0
  22. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/job.py +0 -0
  23. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/meta.py +0 -0
  24. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/backend/odps.py +0 -0
  25. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/cache.py +0 -0
  26. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/config.py +0 -0
  27. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/helpers.py +0 -0
  28. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/masking.py +0 -0
  29. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/models.py +0 -0
  30. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/output.py +0 -0
  31. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/setting_parser.py +0 -0
  32. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/agents/openai.yaml +0 -0
  33. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/nohup.out +0 -0
  34. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/references/bootstrap-auth.md +0 -0
  35. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/references/command-patterns.md +0 -0
  36. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/references/maxcompute-sql-notes.md +0 -0
  37. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/references/migrate-from-odpscmd.md +0 -0
  38. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/references/partition-guide.md +0 -0
  39. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/skills/references/setup-install.md +0 -0
  40. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/store.py +0 -0
  41. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli/utils.py +0 -0
  42. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli.egg-info/SOURCES.txt +0 -0
  43. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli.egg-info/dependency_links.txt +0 -0
  44. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli.egg-info/entry_points.txt +0 -0
  45. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli.egg-info/requires.txt +0 -0
  46. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/src/maxc_cli.egg-info/top_level.txt +0 -0
  47. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_agent_hints_and_cli.py +0 -0
  48. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_agent_skill_commands_context.py +0 -0
  49. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_cache.py +0 -0
  50. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_catalog.py +0 -0
  51. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_cli_mock.py +0 -0
  52. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_compat.py +0 -0
  53. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_e2e_smoke.py +0 -0
  54. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_error_self_correction.py +0 -0
  55. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_external_auth.py +0 -0
  56. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_integration.py +0 -0
  57. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_integration_real.py +0 -0
  58. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_job_improvements.py +0 -0
  59. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_masking.py +0 -0
  60. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_phase1_improvements.py +0 -0
  61. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_query_auto_promote.py +0 -0
  62. {maxc_cli-0.1.5 → maxc_cli-0.1.7}/tests/test_setting_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maxc-cli
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: Agent-native MaxCompute CLI for external coding agents
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.8
@@ -8,7 +8,9 @@ Classifier: Programming Language :: Python :: 3.9
8
8
  Classifier: Programming Language :: Python :: 3.10
9
9
  Classifier: Programming Language :: Python :: 3.11
10
10
  Classifier: Programming Language :: Python :: 3.12
11
- Requires-Python: >=3.8,<3.13
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Python: >=3.8
12
14
  Description-Content-Type: text/markdown
13
15
  Requires-Dist: PyYAML>=5.4
14
16
  Requires-Dist: pyodps
@@ -9,11 +9,11 @@ README = ROOT / "README.md"
9
9
 
10
10
  setup(
11
11
  name="maxc-cli",
12
- version="0.1.5",
12
+ version="0.1.7",
13
13
  description="Agent-native MaxCompute CLI for external coding agents",
14
14
  long_description=README.read_text(encoding="utf-8"),
15
15
  long_description_content_type="text/markdown",
16
- python_requires=">=3.8,<3.13",
16
+ python_requires=">=3.8",
17
17
  package_dir={"": "src"},
18
18
  packages=find_packages(where="src"),
19
19
  include_package_data=True,
@@ -31,6 +31,8 @@ setup(
31
31
  "Programming Language :: Python :: 3.10",
32
32
  "Programming Language :: Python :: 3.11",
33
33
  "Programming Language :: Python :: 3.12",
34
+ "Programming Language :: Python :: 3.13",
35
+ "Programming Language :: Python :: 3.14",
34
36
  ],
35
37
  install_requires=[
36
38
  "PyYAML>=5.4",
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.1.5"
5
+ __version__ = "0.1.7"
@@ -115,10 +115,17 @@ class QueryMixin:
115
115
  instance = self.client.execute_sql(
116
116
  actual_sql, project=project, hints=hints,
117
117
  )
118
+ except Exception as exc:
119
+ raise translate_odps_error(exc) from exc
120
+
121
+ try:
118
122
  # Default timeout: 300 seconds (5 minutes) to prevent indefinite blocking
119
123
  instance.wait_for_success(timeout=timeout or 300)
120
124
  except Exception as exc:
121
- raise translate_odps_error(exc) from exc
125
+ err = translate_odps_error(exc)
126
+ err.instance_id = instance.id
127
+ err.logview = self._safe_logview(instance)
128
+ raise err from exc
122
129
 
123
130
  elapsed_ms = int((monotonic() - started_monotonic) * 1000)
124
131
  result = self._instance_to_query_result(
@@ -512,6 +512,7 @@ def run(
512
512
  "BACKEND_CONNECTION_ERROR": _AUTH_HINTS,
513
513
  "PERMISSION_DENIED": AgentHints(
514
514
  actions=[action("auth.can-i"), action("auth.whoami")],
515
+ insights=[f"Current project: {app.config.default_project}"] if app else [],
515
516
  ),
516
517
  "NOT_FOUND": AgentHints(
517
518
  actions=[action("meta.search"), action("meta.list-tables")],
@@ -572,6 +573,10 @@ def run(
572
573
  emit_json(payload.to_dict(), stdout)
573
574
  else:
574
575
  stderr.write(render_error(exc.error_code, exc.message, exc.suggestion) + "\n")
576
+ if getattr(exc, "instance_id", None):
577
+ stderr.write(f" Instance ID: {exc.instance_id}\n")
578
+ if getattr(exc, "logview", None):
579
+ stderr.write(f" LogView: {exc.logview}\n")
575
580
  return exc.exit_code
576
581
  except Exception as exc:
577
582
  error_payload = ErrorPayload(
@@ -10,6 +10,8 @@ class ErrorPayload:
10
10
  suggestion: 'str | None'
11
11
  recoverable: 'bool'
12
12
  recovery_steps: 'list[str]' = field(default_factory=list)
13
+ instance_id: 'str | None' = None
14
+ logview: 'str | None' = None
13
15
 
14
16
  def to_dict(self) -> 'dict[str, Any]':
15
17
  payload: 'dict[str, Any]' = {
@@ -21,6 +23,10 @@ class ErrorPayload:
21
23
  payload["suggestion"] = self.suggestion
22
24
  if self.recovery_steps:
23
25
  payload["recovery_steps"] = self.recovery_steps
26
+ if self.instance_id:
27
+ payload["instance_id"] = self.instance_id
28
+ if self.logview:
29
+ payload["logview"] = self.logview
24
30
  return payload
25
31
 
26
32
 
@@ -35,10 +41,14 @@ class MaxCError(Exception):
35
41
  *,
36
42
  suggestion: 'str | None' = None,
37
43
  recoverable: 'bool | None' = None,
44
+ instance_id: 'str | None' = None,
45
+ logview: 'str | None' = None,
38
46
  ) -> 'None':
39
47
  super().__init__(message)
40
48
  self.message = message
41
49
  self.suggestion = suggestion
50
+ self.instance_id = instance_id
51
+ self.logview = logview
42
52
  if recoverable is None:
43
53
  self.recoverable = self.__class__.recoverable
44
54
  else:
@@ -52,6 +62,8 @@ class MaxCError(Exception):
52
62
  suggestion=self.suggestion,
53
63
  recoverable=self.recoverable,
54
64
  recovery_steps=steps,
65
+ instance_id=self.instance_id,
66
+ logview=self.logview,
55
67
  )
56
68
 
57
69
  def _default_recovery_steps(self) -> 'list[str]':
@@ -93,7 +93,6 @@ See [references/migrate-from-odpscmd.md](references/migrate-from-odpscmd.md) for
93
93
  - Trust runtime help and actual command output over stale snippets.
94
94
  - Never install or upgrade Python without explicit user confirmation.
95
95
  - Prefer `auth login` over hand-editing `~/.maxc/config.yaml`.
96
- - `meta list-tables` is cache-backed; falls back to live backend query on cache miss.
97
96
  - `meta search` uses Catalog API (server-side FTS via pyodps RestClient) when auto-routed; falls back to cache-backed substring match, then live scan. No extra SDK dependency required.
98
97
  - Most meta commands support `--schema` to override the session default (list-tables, search, search-columns).
99
98
  - `session set/show/unset` are local-only — no authenticated backend required.
@@ -101,11 +100,9 @@ See [references/migrate-from-odpscmd.md](references/migrate-from-odpscmd.md) for
101
100
  - `agent skill` returns the SKILL.md path and metadata.
102
101
  - `agent install-skill <platform>` registers the skill with an Agent platform (claude-code, cursor, windsurf, codex, qwen, qoder, qoderwork). Idempotent; re-run after `pip install --upgrade` to update local skill files.
103
102
  - Use normalized `data` shapes: `auth whoami` → `data.identity`, `query`/`job result` → `data.result`, `meta describe` → `data.table`, `data sample` → `data.sample`.
104
- - Use `agent_hints.actions[]` for structured action objects (Phase 1+); `action_ids` and `next_actions` are derived from `actions[]` and remain available for backward compatibility.
105
- - Use `agent_hints.action_ids` for stable program logic; `next_actions` are hints only.
103
+ - Use `agent_hints.actions[]` for structured navigation. Each action has `id`, `title`, `command`. Use `actions[].id` for stable program logic. Do not execute `next_actions` strings directly — they may have broken shell quoting; construct commands yourself from the action `id` and context.
106
104
  - Before exploring an unfamiliar project, ask the user which schema/table they need — do not iterate all schemas.
107
105
  - When a query fails with `SQL_ERROR`, read `error.suggestion` before retrying. Do not retry the same SQL unchanged.
108
- - `next_actions` commands may have broken shell quoting when SQL contains single quotes. Use `actions[].id` to identify the action, then construct the command yourself if needed.
109
106
  - For partitioned tables, always determine the partition value via `meta latest-partition` or `meta partitions` before querying.
110
107
  - When writing SQL for date-partitioned tables, use the exact partition format returned by `meta latest-partition` (format varies by table).
111
108
 
@@ -284,15 +281,12 @@ See [references/maxcompute-sql-notes.md](references/maxcompute-sql-notes.md) for
284
281
  | Using `maxc sql ...` | The command is `maxc query ...` |
285
282
  | Using `auth login --from-env` without checking env vars exist | Run `auth whoami --json` first; only use `--from-env` when env vars are confirmed set |
286
283
  | Hand-editing `~/.maxc/config.yaml` | Use `auth login` |
287
- | Calling `meta list-tables` on a cold cache | Tables are fetched live on cache miss; `cache build` improves speed for repeat queries |
288
284
  | Inventing endpoints | Only use endpoints the user provided or that exist in current config |
289
285
  | Using `job wait --stream` and expecting a JSON envelope | `--stream` emits NDJSON; use plain `job wait --json` for envelope |
290
286
  | Running a query without checking cost first | Use `query cost` before large queries; use `--cost-check` to set auto-abort threshold |
291
287
  | Ignoring `agent_hints.warnings` in the response | Always check warnings — they surface backend issues, cache staleness, and cost alerts |
292
288
  | Assuming `meta describe` data is live | Cache source may be stale; check `metadata.source` field and `agent_hints.warnings` |
293
- | Querying partitioned table without WHERE on partition column | Use `meta partitions` or `meta latest-partition` to get partition value first |
294
- | Using `MAX_PT()` in ad-hoc queries | Prefer literal values from `meta latest-partition`; MAX_PT may return incomplete partitions |
295
- | Hardcoding partition dates like `ds = '20260101'` | Use `meta latest-partition` to get the actual latest value |
289
+ | Querying partitioned table without partition filter, or hardcoding/guessing partition values | Always run `meta latest-partition` first; use the exact returned value in WHERE (see Partition Query Strategy) |
296
290
  | Assuming 2-tier naming (`project.table`) | Check if project uses 3-tier namespace with `meta list-schemas` |
297
291
 
298
292
  ## Agent Anti-Patterns
@@ -303,7 +297,6 @@ See [references/maxcompute-sql-notes.md](references/maxcompute-sql-notes.md) for
303
297
  | Retrying the exact same failed SQL without changes | Same input → same error | Read `error.suggestion`, fix the SQL, then retry |
304
298
  | Using `SELECT *` on unknown tables | May scan TB of data, hit cost limits | Use `meta describe` first, then select only needed columns with LIMIT |
305
299
  | Generating SQL without checking column names first | Column names are often non-obvious (Chinese, abbreviated) | Always `meta describe` before writing SQL |
306
- | Assuming partition format (e.g. `YYYY-MM-DD`) | Format varies by table (`20260415` vs `2026-04-15`) | Use `meta latest-partition` to get exact format |
307
300
  | Running multiple queries when one suffices | Wastes compute and time | Combine into a single query with JOINs or subqueries |
308
301
 
309
302
  ## Error Recovery
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maxc-cli
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: Agent-native MaxCompute CLI for external coding agents
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.8
@@ -8,7 +8,9 @@ Classifier: Programming Language :: Python :: 3.9
8
8
  Classifier: Programming Language :: Python :: 3.10
9
9
  Classifier: Programming Language :: Python :: 3.11
10
10
  Classifier: Programming Language :: Python :: 3.12
11
- Requires-Python: >=3.8,<3.13
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Python: >=3.8
12
14
  Description-Content-Type: text/markdown
13
15
  Requires-Dist: PyYAML>=5.4
14
16
  Requires-Dist: pyodps
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes