llm-api-scope 0.6.0__tar.gz → 0.7.0__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 (38) hide show
  1. {llm_api_scope-0.6.0/llm_api_scope.egg-info → llm_api_scope-0.7.0}/PKG-INFO +1 -1
  2. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/config.py +6 -1
  3. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/main.py +2 -0
  4. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/app.py +10 -1
  5. llm_api_scope-0.7.0/apiscope/skill/__init__.py +5 -0
  6. llm_api_scope-0.7.0/apiscope/skill/_usage.py +72 -0
  7. llm_api_scope-0.7.0/apiscope/skill/app.py +19 -0
  8. llm_api_scope-0.7.0/apiscope/skill/docs.py +111 -0
  9. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0/llm_api_scope.egg-info}/PKG-INFO +1 -1
  10. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/SOURCES.txt +4 -0
  11. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/pyproject.toml +1 -1
  12. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/LICENSE +0 -0
  13. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/README.md +0 -0
  14. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/__init__.py +0 -0
  15. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/__init__.py +0 -0
  16. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/fetch.py +0 -0
  17. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/reader.py +0 -0
  18. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/schema.py +0 -0
  19. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/spec/__init__.py +0 -0
  20. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/spec/app.py +0 -0
  21. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/spec/schema.py +0 -0
  22. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/__init__.py +0 -0
  23. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/app.py +0 -0
  24. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/fetch.py +0 -0
  25. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/schema.py +0 -0
  26. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/__init__.py +0 -0
  27. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/app.py +0 -0
  28. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/fetch.py +0 -0
  29. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/parse_txt.py +0 -0
  30. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/parse_xml.py +0 -0
  31. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/schema.py +0 -0
  32. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/search.py +0 -0
  33. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/schema.py +0 -0
  34. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/dependency_links.txt +0 -0
  35. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/entry_points.txt +0 -0
  36. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/requires.txt +0 -0
  37. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/top_level.txt +0 -0
  38. {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llm-api-scope
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: read and cache structured documents from remote for LLM agents
5
5
  Author-email: D7x7z49 <85430783+D7x7z49@users.noreply.github.com>
6
6
  License: MIT License
@@ -153,7 +153,12 @@ def get_config() -> Config:
153
153
 
154
154
  # load and merge the project config
155
155
  project_config_path = get_project_config_path()
156
- if project_config_path is not None and project_config_path.exists():
156
+ if project_config_path is not None:
157
+ if not project_config_path.exists() or project_config_path.stat().st_size == 0:
158
+ # create default project config if not exists
159
+ project_config_path.write_text(
160
+ json.dumps({"$schema": DEFAULT_CONFIG_SCHEMA_PATH.as_uri()}, indent=2) + "\n"
161
+ )
157
162
  project_config = Config.model_validate_json(project_config_path.read_text())
158
163
  return global_config.merge(project_config)
159
164
 
@@ -28,6 +28,7 @@ from apiscope.openapi import openapi_app
28
28
  from apiscope.repo import check_repo_deps, repo_app
29
29
  from apiscope.rfc import check_rfc_deps, rfc_app
30
30
  from apiscope.schema import CommandContext
31
+ from apiscope.skill import skill_app
31
32
 
32
33
  # ==============================================================================
33
34
  # app
@@ -59,6 +60,7 @@ def callback(ctx: typer.Context) -> None:
59
60
  app.add_typer(openapi_app, name="openapi")
60
61
  app.add_typer(rfc_app, name="rfc")
61
62
  app.add_typer(repo_app, name="repo")
63
+ app.add_typer(skill_app, name="skill")
62
64
 
63
65
  # ==============================================================================
64
66
  # commands
@@ -65,6 +65,8 @@ def list_operations(
65
65
  source: str = typer.Argument(help="alias or path to the OpenAPI spec"),
66
66
  tag: str | None = typer.Option(default=None, help="filter by tag"),
67
67
  method: str | None = typer.Option(default=None, help="filter by HTTP method"),
68
+ limit: int = typer.Option(default=20, help="max results shown"),
69
+ offset: int = typer.Option(default=0, help="skip first N results"),
68
70
  force: bool = typer.Option(False, "--force", help="force re-fetch ignoring cache"),
69
71
  ) -> None:
70
72
  reader = _get_reader(source, ctx, force=force)
@@ -98,7 +100,14 @@ def list_operations(
98
100
  }
99
101
  )
100
102
 
101
- typer.echo(json.dumps(operations, ensure_ascii=False))
103
+ total = len(operations)
104
+ operations = operations[offset : offset + limit]
105
+ typer.echo(
106
+ json.dumps(
107
+ {"total": total, "offset": offset, "limit": limit, "items": operations},
108
+ ensure_ascii=False,
109
+ )
110
+ )
102
111
 
103
112
 
104
113
  @app.command(name="describe", help="describe a single operation")
@@ -0,0 +1,5 @@
1
+ # apiscope/skill/__init__.py
2
+
3
+ from apiscope.skill.app import app as skill_app
4
+
5
+ __all__ = ["skill_app"]
@@ -0,0 +1,72 @@
1
+ # apiscope/skill/_usage.py
2
+ #
3
+ # synced with [docs/usage.txt] -> update both when a command changes.
4
+
5
+ USAGE_TEXT = """\
6
+ - apiscope # a reader for network resources
7
+ - health # check that apiscope is installed and working
8
+ - openapi # browse OpenAPI specifications
9
+ - info # show OpenAPI spec metadata
10
+ + [SOURCE] # alias or path to the OpenAPI spec
11
+ + [--force]? # force re-fetch ignoring cache
12
+ - list # list operations from an OpenAPI spec
13
+ + [SOURCE] # alias or path to the OpenAPI spec
14
+ + [--tag]? # filter by tag
15
+ + [--method]? # filter by HTTP method
16
+ + [--limit]? # max results shown
17
+ + [--offset]? # skip first N results
18
+ + [--force]? # force re-fetch ignoring cache
19
+ - describe # describe a single operation
20
+ + [SOURCE] # alias or path to the OpenAPI spec
21
+ + [PATH] # operation path
22
+ + [METHOD] # HTTP method
23
+ + [--request]? # show only request fields, omit responses
24
+ + [--force]? # force re-fetch ignoring cache
25
+ - spec # manage OpenAPI spec aliases
26
+ + [-g]? # edit global config instead of project config
27
+ - add # register a new alias for an OpenAPI spec
28
+ + [ALIAS] # alias name
29
+ + [SOURCE] # path or URL to the OpenAPI spec
30
+ - remove # remove a registered alias
31
+ + [ALIAS] # alias name
32
+ - list # list all registered aliases
33
+ - rfc # browse IETF RFC documents
34
+ - sync # download RFC metadata index via rsync
35
+ + [--force]? # force re-sync ignoring cache TTL
36
+ - info # show RFC metadata
37
+ + [NUMBER] # RFC number
38
+ + [--json]? # output as JSON
39
+ - read # show RFC content or table of contents
40
+ + [NUMBER] # RFC number
41
+ + [--section]? # extract by section id (XML only)
42
+ + [--page]? # extract by page number (TXT only)
43
+ + [--json]? # output as JSON
44
+ + [--force]? # force re-fetch ignoring cache TTL
45
+ - search # search RFC index or fulltext
46
+ + [NUMBER]? # RFC number (fulltext mode)
47
+ + [TERM]? # search term (fulltext mode)
48
+ + [--force]? # force re-fetch ignoring cache TTL (fulltext mode)
49
+ + [--status]...? # filter by status: ps, ds, std, bcp, info, exp, hist (index mode)
50
+ + [--since]? # filter by start year (index mode)
51
+ + [--until]? # filter by end year (index mode)
52
+ + [--author]? # filter by author name (index mode)
53
+ + [--title]? # filter by title keyword (index mode)
54
+ + [--abstract]? # filter by abstract keyword (index mode)
55
+ + [--keywords]? # filter by keywords field (index mode)
56
+ + [--source]? # filter by source / working group (index mode)
57
+ + [--context]? # lines of context around match (fulltext mode)
58
+ + [--no-snippet]? # hide content snippet (fulltext mode)
59
+ + [--limit]? # max results shown
60
+ + [--offset]? # skip first N results
61
+ - repo # sync documentation from git repositories
62
+ + [-g]? # edit global config instead of project config
63
+ - add # register a repo for syncing
64
+ + [URL] # git clone URL
65
+ + [DIR] # directory within repo to extract
66
+ + [--target]? # ref target (branch:, tag:, commit:)
67
+ - remove # remove a registered repo
68
+ + [URL] # git clone URL
69
+ - list # list registered repos
70
+ - sync # sync all registered repos to cache
71
+ + [--force]? # force re-sync ignoring cache TTL
72
+ """
@@ -0,0 +1,19 @@
1
+ # apiscope/skill/app.py
2
+
3
+ import typer
4
+
5
+ from apiscope.skill._usage import USAGE_TEXT
6
+ from apiscope.skill.docs import STRATEGY_GUIDE
7
+
8
+ app = typer.Typer(help="output usage guide for ai agents")
9
+
10
+
11
+ @app.callback(invoke_without_command=True)
12
+ def skill_callback() -> None:
13
+ typer.echo("=== COMMAND REFERENCE ===")
14
+ typer.echo()
15
+ typer.echo(USAGE_TEXT)
16
+ typer.echo()
17
+ typer.echo("=== STRATEGY GUIDE ===")
18
+ typer.echo()
19
+ typer.echo(STRATEGY_GUIDE)
@@ -0,0 +1,111 @@
1
+ # apiscope/skill/docs.py
2
+
3
+ STRATEGY_GUIDE = """\
4
+ PREMISE
5
+
6
+ apiscope is a content acquisition layer, not a consumption layer.
7
+ it fetches high-quality reference materials to local cache, then
8
+ you use your preferred tools (ripgrep, grep, less) to consume them.
9
+
10
+ - openapi: structured api specifications with built-in analysis helpers
11
+ - rfc: internet standards and best current practice documents
12
+ - repo: git repository documentation for offline access
13
+
14
+ CLASSIFICATION
15
+
16
+ management commands (run once, configure the tool)
17
+
18
+ - apiscope health
19
+ - apiscope openapi spec add / remove / list
20
+ - apiscope repo add / remove / list / sync
21
+ - apiscope rfc sync
22
+
23
+ usage commands (run repeatedly, query content)
24
+
25
+ - apiscope openapi info / list / describe
26
+ - apiscope rfc info / read / search
27
+
28
+ PREREQUISITES
29
+
30
+ the grammar notation used in this section follows <RFC 5234> ABNF.
31
+ the key words "MUST", "SHOULD", and "MAY" are to be interpreted
32
+ as described in <RFC 2119>.
33
+
34
+ openapi-query
35
+ = spec-add *(info / list / describe)
36
+ ; spec-add MUST precede any query command
37
+
38
+ rfc-local
39
+ = sync read
40
+ ; sync SHOULD precede read for local access
41
+
42
+ rfc-local-info
43
+ = sync info
44
+ ; sync SHOULD precede info for metadata lookup
45
+
46
+ repo-consume
47
+ = add sync grep
48
+ ; add then sync MUST precede local consumption
49
+
50
+ WORKFLOWS
51
+
52
+ explore-api
53
+ = spec-add info list describe
54
+ ; 1. register the spec
55
+ ; 2. check metadata
56
+ ; 3. browse operations
57
+ ; 4. examine a specific operation
58
+
59
+ read-rfc
60
+ = sync *search read
61
+ ; 1. sync index
62
+ ; 2. optionally search for relevant RFCs
63
+ ; 3. read the selected RFC
64
+
65
+ integrate-repo
66
+ = add sync grep
67
+ ; 1. register the repository
68
+ ; 2. sync all repos
69
+ ; 3. use ripgrep or grep on local cache
70
+
71
+ TIPS
72
+
73
+ cache strategy
74
+
75
+ each domain has a different cache ttl reflecting content
76
+ stability. the [--force] flag MUST only be used when you
77
+ expect the remote content has changed since last fetch.
78
+
79
+ - openapi: 1 day
80
+ - rfc: 30 days
81
+ - repo: 7 days
82
+
83
+ config hierarchy
84
+
85
+ global config (<~/.apiscope/config.json>) holds personal
86
+ defaults. project config (<.apiscope.config.json>) holds
87
+ team-specific entries. project values override global ones
88
+ where overlap is defined.
89
+
90
+ [openapi spec add] without [-g] writes to project config.
91
+ teammates who clone the project get the same aliases.
92
+
93
+ openapi alias naming
94
+
95
+ aliases are shortcuts for spec URLs. use a naming convention
96
+ that makes the source obvious without checking [spec list].
97
+
98
+ - github-api, petstore-v3, stripe-v1
99
+
100
+ acquisition before analysis
101
+
102
+ rfc and repo pull documents to local cache. do not treat
103
+ apiscope search as a replacement for grep or ripgrep. the
104
+ intended workflow is: acquire local copy, then analyze with
105
+ your preferred tools.
106
+
107
+ openapi is the exception. it provides [list] for breadth,
108
+ [describe] for depth, and [info] for metadata. use [list]
109
+ first to scan endpoints, then [describe] to extract a
110
+ specific operation in detail.
111
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llm-api-scope
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: read and cache structured documents from remote for LLM agents
5
5
  Author-email: D7x7z49 <85430783+D7x7z49@users.noreply.github.com>
6
6
  License: MIT License
@@ -24,6 +24,10 @@ apiscope/rfc/parse_txt.py
24
24
  apiscope/rfc/parse_xml.py
25
25
  apiscope/rfc/schema.py
26
26
  apiscope/rfc/search.py
27
+ apiscope/skill/__init__.py
28
+ apiscope/skill/_usage.py
29
+ apiscope/skill/app.py
30
+ apiscope/skill/docs.py
27
31
  llm_api_scope.egg-info/PKG-INFO
28
32
  llm_api_scope.egg-info/SOURCES.txt
29
33
  llm_api_scope.egg-info/dependency_links.txt
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "llm-api-scope"
7
- version = "0.6.0"
7
+ version = "0.7.0"
8
8
  description = "read and cache structured documents from remote for LLM agents"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
File without changes
File without changes
File without changes