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.
- {llm_api_scope-0.6.0/llm_api_scope.egg-info → llm_api_scope-0.7.0}/PKG-INFO +1 -1
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/config.py +6 -1
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/main.py +2 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/app.py +10 -1
- llm_api_scope-0.7.0/apiscope/skill/__init__.py +5 -0
- llm_api_scope-0.7.0/apiscope/skill/_usage.py +72 -0
- llm_api_scope-0.7.0/apiscope/skill/app.py +19 -0
- llm_api_scope-0.7.0/apiscope/skill/docs.py +111 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0/llm_api_scope.egg-info}/PKG-INFO +1 -1
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/SOURCES.txt +4 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/pyproject.toml +1 -1
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/LICENSE +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/README.md +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/__init__.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/__init__.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/fetch.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/reader.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/schema.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/spec/__init__.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/spec/app.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/openapi/spec/schema.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/__init__.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/app.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/fetch.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/repo/schema.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/__init__.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/app.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/fetch.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/parse_txt.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/parse_xml.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/schema.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/rfc/search.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/apiscope/schema.py +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/dependency_links.txt +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/entry_points.txt +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/requires.txt +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/llm_api_scope.egg-info/top_level.txt +0 -0
- {llm_api_scope-0.6.0 → llm_api_scope-0.7.0}/setup.cfg +0 -0
|
@@ -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
|
|
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
|
-
|
|
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,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
|
+
"""
|
|
@@ -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
|
|
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
|
|
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
|
|
File without changes
|