mainsequence 9.0.1.dev31__py3-none-any.whl → 9.0.2.dev32__py3-none-any.whl
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.
- agent_scaffold/AGENTS.md +6 -0
- agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +21 -6
- mainsequence/cli/cli.py +108 -95
- mainsequence/code_repository_skills.py +51 -200
- mainsequence/scaffold_skills.py +54 -18
- {mainsequence-9.0.1.dev31.dist-info → mainsequence-9.0.2.dev32.dist-info}/METADATA +1 -1
- {mainsequence-9.0.1.dev31.dist-info → mainsequence-9.0.2.dev32.dist-info}/RECORD +11 -11
- {mainsequence-9.0.1.dev31.dist-info → mainsequence-9.0.2.dev32.dist-info}/WHEEL +0 -0
- {mainsequence-9.0.1.dev31.dist-info → mainsequence-9.0.2.dev32.dist-info}/entry_points.txt +0 -0
- {mainsequence-9.0.1.dev31.dist-info → mainsequence-9.0.2.dev32.dist-info}/licenses/LICENSE +0 -0
- {mainsequence-9.0.1.dev31.dist-info → mainsequence-9.0.2.dev32.dist-info}/top_level.txt +0 -0
agent_scaffold/AGENTS.md
CHANGED
|
@@ -42,6 +42,7 @@ specific update:
|
|
|
42
42
|
|
|
43
43
|
- `mainsequence code-repository update-sdk --path .`
|
|
44
44
|
- `mainsequence code-repository update-agent-skills --path .`
|
|
45
|
+
- `mainsequence code-repository update-platform-skills --path .`
|
|
45
46
|
- `mainsequence code-repository update AGENTS.md --path .`
|
|
46
47
|
- `uv run ms-tau skills sync --path .`
|
|
47
48
|
|
|
@@ -51,6 +52,11 @@ to report, not permission to mutate the repository. The same rule applies to
|
|
|
51
52
|
requested, use the `code_repository_maintenance` skill. The `mainsequence` CLI
|
|
52
53
|
never owns or updates the `ms_tau_sdk` namespace.
|
|
53
54
|
|
|
55
|
+
The SDK owns all of `.agents/skills/mainsequence/`. Its skill copy is local,
|
|
56
|
+
requires no sign-in, and deletes everything absent from the installed SDK
|
|
57
|
+
bundle. Platform skills are installed separately under
|
|
58
|
+
`.agents/skills/mainsequence_platform/` by the authenticated platform update.
|
|
59
|
+
|
|
54
60
|
## Route By Task
|
|
55
61
|
|
|
56
62
|
- Product architecture, platform ontology, and CodeRepository Blueprint work:
|
|
@@ -172,22 +172,37 @@ to publish the CodeRepository changes.
|
|
|
172
172
|
## Refresh Managed Skills And Instructions
|
|
173
173
|
|
|
174
174
|
Run either managed-scaffold command only when the user explicitly requests that
|
|
175
|
-
specific update. When both are requested, refresh the SDK-owned
|
|
176
|
-
|
|
175
|
+
specific update. When both are requested, refresh the SDK-owned skills first,
|
|
176
|
+
then update the managed Main Sequence block in
|
|
177
177
|
`AGENTS.md`:
|
|
178
178
|
|
|
179
179
|
```bash
|
|
180
|
-
mainsequence code-repository update-agent-skills --path .
|
|
181
|
-
mainsequence code-repository update AGENTS.md --path .
|
|
180
|
+
uv run --offline mainsequence code-repository update-agent-skills --path .
|
|
181
|
+
uv run --offline mainsequence code-repository update AGENTS.md --path .
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
Verify `.agents/skills/mainsequence/PINNED_FROM.txt` after success:
|
|
185
185
|
|
|
186
|
-
- `
|
|
187
|
-
-
|
|
186
|
+
- `pinned_version` must match the installed CodeRepository SDK;
|
|
187
|
+
- the namespace must contain exactly the installed SDK's skill folders;
|
|
188
188
|
- repository-owned skills outside `.agents/skills/mainsequence/` must remain
|
|
189
189
|
untouched.
|
|
190
190
|
|
|
191
|
+
The SDK owns the whole `mainsequence` namespace. Copying it requires no login
|
|
192
|
+
or platform access and deletes obsolete folders, including retired table
|
|
193
|
+
workflow skills. Do not preserve old or platform-owned content in that folder.
|
|
194
|
+
The installed `metatables` package owns table workflows in its own namespace.
|
|
195
|
+
|
|
196
|
+
When the user requests platform skills, use the separate authenticated command:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
mainsequence code-repository update-platform-skills --path .
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
It owns only `.agents/skills/mainsequence_platform/` and records the platform
|
|
203
|
+
manifest, ontology, and resource hashes there. A backend or authentication
|
|
204
|
+
failure in this command must not block a local SDK skill copy.
|
|
205
|
+
|
|
191
206
|
The skill update is staged and atomic. If it fails, report the failing lane and
|
|
192
207
|
preserve the previous valid managed tree. Because this operation can update
|
|
193
208
|
this skill, reload the refreshed `code_repository_maintenance/SKILL.md` before starting
|
mainsequence/cli/cli.py
CHANGED
|
@@ -56,8 +56,9 @@ from ..code_repository_context import (
|
|
|
56
56
|
)
|
|
57
57
|
from ..code_repository_skills import (
|
|
58
58
|
CodeRepositorySkillAssemblyError,
|
|
59
|
-
|
|
59
|
+
install_platform_code_repository_skills,
|
|
60
60
|
)
|
|
61
|
+
from ..scaffold_skills import ScaffoldSkillCopyBlocked, copy_scaffold_skills
|
|
61
62
|
from . import config as cfg
|
|
62
63
|
from .api import (
|
|
63
64
|
ApiError,
|
|
@@ -7845,6 +7846,33 @@ def code_repository_update_sdk(
|
|
|
7845
7846
|
run_uv(uv, ["sync"], cwd=code_repository_dir)
|
|
7846
7847
|
|
|
7847
7848
|
success("SDK update complete.")
|
|
7849
|
+
_warn_if_sdk_skills_stale(code_repository_dir)
|
|
7850
|
+
|
|
7851
|
+
|
|
7852
|
+
def _warn_if_sdk_skills_stale(code_repository_dir: pathlib.Path) -> None:
|
|
7853
|
+
try:
|
|
7854
|
+
version = _code_repository_installed_package_version(code_repository_dir, "mainsequence")
|
|
7855
|
+
sentinel = code_repository_dir / ".agents" / "skills" / "mainsequence" / "PINNED_FROM.txt"
|
|
7856
|
+
values = (
|
|
7857
|
+
dict(
|
|
7858
|
+
line.split("=", 1)
|
|
7859
|
+
for line in sentinel.read_text(encoding="utf-8").splitlines()
|
|
7860
|
+
if "=" in line
|
|
7861
|
+
)
|
|
7862
|
+
if sentinel.is_file()
|
|
7863
|
+
else {}
|
|
7864
|
+
)
|
|
7865
|
+
except (OSError, ValueError, typer.Exit):
|
|
7866
|
+
warn("Could not check the vendored SDK skill pin. Run update-agent-skills to refresh it.")
|
|
7867
|
+
return
|
|
7868
|
+
pinned = values.get("pinned_version", values.get("sdk_version"))
|
|
7869
|
+
if pinned != version:
|
|
7870
|
+
warn(
|
|
7871
|
+
f"Vendored SDK skills are stale or missing (pinned: {pinned or 'missing'}; installed: {version}). "
|
|
7872
|
+
"No scaffold files were changed. Refresh with "
|
|
7873
|
+
"`uv run --offline mainsequence code-repository update-agent-skills --path .` "
|
|
7874
|
+
"and `uv run --offline mainsequence code-repository update AGENTS.md --path .`."
|
|
7875
|
+
)
|
|
7848
7876
|
|
|
7849
7877
|
|
|
7850
7878
|
@code_repository.command("update")
|
|
@@ -7935,124 +7963,61 @@ def code_repository_update_agent_skills(
|
|
|
7935
7963
|
path: str | None = typer.Option(None, "--path", help="CodeRepository directory"),
|
|
7936
7964
|
):
|
|
7937
7965
|
"""
|
|
7938
|
-
|
|
7966
|
+
Replace SDK-owned skills with the target checkout's installed SDK bundle.
|
|
7939
7967
|
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
such as `AGENTS.md` are not copied by this command.
|
|
7968
|
+
No sign-in or backend access is required unless a CodeRepository UID
|
|
7969
|
+
assertion is supplied. The SDK owns all of .agents/skills/mainsequence:
|
|
7970
|
+
files and folders absent from the installed bundle are deleted. Other
|
|
7971
|
+
namespaces are untouched. AGENTS.md is refreshed separately with
|
|
7972
|
+
code-repository update AGENTS.md. Platform skills use update-platform-skills.
|
|
7946
7973
|
|
|
7947
7974
|
Examples
|
|
7948
7975
|
--------
|
|
7949
|
-
```bash
|
|
7950
|
-
mainsequence code-repository update-agent-skills
|
|
7951
7976
|
mainsequence code-repository update-agent-skills --path .
|
|
7952
|
-
mainsequence code-repository update-agent-skills --code-repository-uid code-repository-uid-123
|
|
7953
|
-
```
|
|
7954
7977
|
"""
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
if not skills_dir.exists() or not skills_dir.is_dir():
|
|
7960
|
-
error(f"CodeRepository-installed agent_scaffold bundle is missing skills/: {skills_dir}")
|
|
7961
|
-
raise typer.Exit(1)
|
|
7962
|
-
|
|
7963
|
-
pinned_version = _code_repository_installed_package_version(code_repository_dir, "mainsequence")
|
|
7964
|
-
source_checkout_root = _mainsequence_source_checkout_root()
|
|
7965
|
-
protected_code_repository_roots = (
|
|
7966
|
-
(source_checkout_root,) if source_checkout_root is not None else ()
|
|
7967
|
-
)
|
|
7978
|
+
directory = _resolve_code_repository_dir(code_repository_id, path)
|
|
7979
|
+
skills_dir = _code_repository_agent_scaffold_bundle_dir(directory) / "skills"
|
|
7980
|
+
version = _code_repository_installed_package_version(directory, "mainsequence")
|
|
7981
|
+
source_root = _mainsequence_source_checkout_root()
|
|
7968
7982
|
try:
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
sdk_library_name="mainsequence",
|
|
7983
|
+
result = copy_scaffold_skills(
|
|
7984
|
+
code_repository_dir=directory,
|
|
7985
|
+
library_name="mainsequence",
|
|
7973
7986
|
namespace="mainsequence",
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
platform_catalog=platform_catalog,
|
|
7987
|
+
skills_path=skills_dir,
|
|
7988
|
+
pinned_version=version,
|
|
7977
7989
|
command="mainsequence code-repository update-agent-skills",
|
|
7978
|
-
protected_code_repository_roots=
|
|
7990
|
+
protected_code_repository_roots=(source_root,) if source_root else (),
|
|
7979
7991
|
)
|
|
7980
|
-
except (
|
|
7981
|
-
ApiError,
|
|
7982
|
-
CodeRepositorySkillAssemblyError,
|
|
7983
|
-
FileNotFoundError,
|
|
7984
|
-
OSError,
|
|
7985
|
-
ValueError,
|
|
7986
|
-
) as exc:
|
|
7992
|
+
except (ScaffoldSkillCopyBlocked, FileNotFoundError, OSError, ValueError) as exc:
|
|
7987
7993
|
error(str(exc))
|
|
7988
7994
|
raise typer.Exit(1) from exc
|
|
7989
|
-
|
|
7990
7995
|
updated = [
|
|
7991
|
-
{
|
|
7992
|
-
|
|
7993
|
-
"owner": item.owner,
|
|
7994
|
-
"source": item.source,
|
|
7995
|
-
"destination": item.destination,
|
|
7996
|
-
"content_sha256": item.content_sha256,
|
|
7997
|
-
}
|
|
7998
|
-
for item in install_result.installed
|
|
7996
|
+
{"name": item.name, "owner": "sdk", "source": item.source, "destination": item.destination}
|
|
7997
|
+
for item in result.copied
|
|
7999
7998
|
]
|
|
8000
|
-
|
|
8001
7999
|
payload = {
|
|
8002
|
-
"code_repository":
|
|
8003
|
-
"library_name":
|
|
8004
|
-
"namespace":
|
|
8005
|
-
"skills_path":
|
|
8006
|
-
"destination_root":
|
|
8007
|
-
"sentinel_path":
|
|
8008
|
-
"pinned_version":
|
|
8000
|
+
"code_repository": directory,
|
|
8001
|
+
"library_name": result.library_name,
|
|
8002
|
+
"namespace": result.namespace,
|
|
8003
|
+
"skills_path": result.skills_path,
|
|
8004
|
+
"destination_root": result.destination_root,
|
|
8005
|
+
"sentinel_path": result.sentinel_path,
|
|
8006
|
+
"pinned_version": result.pinned_version,
|
|
8009
8007
|
"sdk": {
|
|
8010
|
-
"library_name":
|
|
8011
|
-
"version":
|
|
8012
|
-
"skills_path":
|
|
8013
|
-
},
|
|
8014
|
-
"platform": {
|
|
8015
|
-
"source_url": platform_catalog.source_url,
|
|
8016
|
-
"manifest_version": platform_catalog.manifest_version,
|
|
8017
|
-
"manifest_sha256": platform_catalog.manifest_sha256,
|
|
8018
|
-
"ontology_uri": platform_catalog.ontology_uri,
|
|
8019
|
-
"ontology_sha256": platform_catalog.ontology_sha256,
|
|
8020
|
-
"resources": [
|
|
8021
|
-
{
|
|
8022
|
-
"name": resource.name,
|
|
8023
|
-
"uri": resource.uri,
|
|
8024
|
-
"path": str(resource.resource_path),
|
|
8025
|
-
"content_sha256": resource.content_sha256,
|
|
8026
|
-
}
|
|
8027
|
-
for resource in platform_catalog.resources
|
|
8028
|
-
],
|
|
8029
|
-
"skills": [
|
|
8030
|
-
{
|
|
8031
|
-
"name": skill.name,
|
|
8032
|
-
"uri": skill.uri,
|
|
8033
|
-
"path": str(skill.relative_path),
|
|
8034
|
-
"content_sha256": skill.content_sha256,
|
|
8035
|
-
}
|
|
8036
|
-
for skill in platform_catalog.skills
|
|
8037
|
-
],
|
|
8008
|
+
"library_name": result.library_name,
|
|
8009
|
+
"version": version,
|
|
8010
|
+
"skills_path": result.skills_path,
|
|
8038
8011
|
},
|
|
8039
8012
|
"updated_count": len(updated),
|
|
8040
8013
|
"updated": updated,
|
|
8041
8014
|
}
|
|
8042
8015
|
if _emit_json(payload):
|
|
8043
8016
|
return
|
|
8044
|
-
|
|
8045
|
-
success("Updated .agents/skills/mainsequence from installed SDK and platform sources.")
|
|
8017
|
+
success("Replaced SDK-owned .agents/skills/mainsequence with the installed bundle.")
|
|
8046
8018
|
print_kv(
|
|
8047
8019
|
"CodeRepository Skill Provenance",
|
|
8048
|
-
[
|
|
8049
|
-
("SDK Library", install_result.sdk_library_name),
|
|
8050
|
-
("SDK Version", install_result.sdk_version),
|
|
8051
|
-
("Platform Manifest", platform_catalog.manifest_sha256),
|
|
8052
|
-
("Platform Resources", len(platform_catalog.resources)),
|
|
8053
|
-
("Platform Skills", len(platform_catalog.skills)),
|
|
8054
|
-
("Sentinel", str(install_result.sentinel_path)),
|
|
8055
|
-
],
|
|
8020
|
+
[("SDK Version", version), ("Sentinel", str(result.sentinel_path))],
|
|
8056
8021
|
)
|
|
8057
8022
|
print_table(
|
|
8058
8023
|
"Updated CodeRepository Skills",
|
|
@@ -8061,6 +8026,54 @@ def code_repository_update_agent_skills(
|
|
|
8061
8026
|
)
|
|
8062
8027
|
|
|
8063
8028
|
|
|
8029
|
+
@code_repository.command("update-platform-skills")
|
|
8030
|
+
def code_repository_update_platform_skills(
|
|
8031
|
+
path: str | None = typer.Option(None, "--path", help="CodeRepository directory"),
|
|
8032
|
+
):
|
|
8033
|
+
"""Refresh authenticated platform skills in .agents/skills/mainsequence_platform.
|
|
8034
|
+
|
|
8035
|
+
This requires a signed-in session and a reachable backend. The SDK-owned
|
|
8036
|
+
mainsequence namespace and other library namespaces remain untouched.
|
|
8037
|
+
"""
|
|
8038
|
+
directory = _resolve_code_repository_dir(None, path)
|
|
8039
|
+
source_root = _mainsequence_source_checkout_root()
|
|
8040
|
+
try:
|
|
8041
|
+
catalog = fetch_platform_code_repository_skill_catalog()
|
|
8042
|
+
destination, installed = install_platform_code_repository_skills(
|
|
8043
|
+
code_repository_dir=directory,
|
|
8044
|
+
platform_catalog=catalog,
|
|
8045
|
+
protected_code_repository_roots=(source_root,) if source_root else (),
|
|
8046
|
+
)
|
|
8047
|
+
except (
|
|
8048
|
+
ApiError,
|
|
8049
|
+
CodeRepositorySkillAssemblyError,
|
|
8050
|
+
ScaffoldSkillCopyBlocked,
|
|
8051
|
+
FileNotFoundError,
|
|
8052
|
+
OSError,
|
|
8053
|
+
ValueError,
|
|
8054
|
+
) as exc:
|
|
8055
|
+
error(str(exc))
|
|
8056
|
+
raise typer.Exit(1) from exc
|
|
8057
|
+
payload = {
|
|
8058
|
+
"code_repository": directory,
|
|
8059
|
+
"namespace": "mainsequence_platform",
|
|
8060
|
+
"destination_root": destination,
|
|
8061
|
+
"sentinel_path": destination / "PINNED_FROM.txt",
|
|
8062
|
+
"platform": {
|
|
8063
|
+
"source_url": catalog.source_url,
|
|
8064
|
+
"manifest_version": catalog.manifest_version,
|
|
8065
|
+
"manifest_sha256": catalog.manifest_sha256,
|
|
8066
|
+
"ontology_uri": catalog.ontology_uri,
|
|
8067
|
+
"ontology_sha256": catalog.ontology_sha256,
|
|
8068
|
+
},
|
|
8069
|
+
"updated_count": len(installed),
|
|
8070
|
+
"updated": [dataclasses.asdict(item) for item in installed],
|
|
8071
|
+
}
|
|
8072
|
+
if _emit_json(payload):
|
|
8073
|
+
return
|
|
8074
|
+
success("Updated .agents/skills/mainsequence_platform from the authenticated platform catalog.")
|
|
8075
|
+
|
|
8076
|
+
|
|
8064
8077
|
@skills.command("list")
|
|
8065
8078
|
def skills_list_cmd():
|
|
8066
8079
|
"""
|
|
@@ -1,25 +1,17 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Authenticated platform skill catalog validation and installation.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* SDK-owned execution skills from the target code repository's installed
|
|
7
|
-
``agent_scaffold/skills`` tree.
|
|
8
|
-
* Platform-owned skills retrieved from authenticated MCP resources.
|
|
9
|
-
|
|
10
|
-
Platform content is validated in memory and written only to the target code
|
|
11
|
-
repository. It is never persisted in the installed SDK package.
|
|
3
|
+
SDK-owned skills are mirrored separately by ``copy_scaffold_skills`` into the
|
|
4
|
+
``mainsequence`` namespace. Platform resources use ``mainsequence_platform``;
|
|
5
|
+
they are never mixed into the SDK-owned namespace or installed SDK package.
|
|
12
6
|
"""
|
|
13
7
|
|
|
14
8
|
from __future__ import annotations
|
|
15
9
|
|
|
16
10
|
import hashlib
|
|
17
11
|
import json
|
|
18
|
-
import os
|
|
19
12
|
import re
|
|
20
13
|
import shutil
|
|
21
14
|
import tempfile
|
|
22
|
-
import uuid
|
|
23
15
|
from collections.abc import Sequence
|
|
24
16
|
from dataclasses import dataclass
|
|
25
17
|
from pathlib import Path, PurePosixPath
|
|
@@ -29,11 +21,10 @@ import yaml
|
|
|
29
21
|
|
|
30
22
|
from .scaffold_skills import (
|
|
31
23
|
PINNED_FROM_FILENAME,
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
_check_code_repository_guards,
|
|
25
|
+
_replace_managed_tree,
|
|
34
26
|
)
|
|
35
27
|
|
|
36
|
-
DUAL_SOURCE_SENTINEL_SCHEMA = "2"
|
|
37
28
|
PLATFORM_RESOURCE_NAMESPACE = "mainsequence://platform/"
|
|
38
29
|
PLATFORM_ONTOLOGY_URI = "mainsequence://platform/ontology"
|
|
39
30
|
PLATFORM_SKILL_URI_PREFIX = f"{PLATFORM_RESOURCE_NAMESPACE}skills/"
|
|
@@ -129,20 +120,6 @@ class InstalledCodeRepositorySkill:
|
|
|
129
120
|
content_sha256: str | None = None
|
|
130
121
|
|
|
131
122
|
|
|
132
|
-
@dataclass(frozen=True)
|
|
133
|
-
class DualSourceCodeRepositorySkillInstallResult:
|
|
134
|
-
"""Result of one completed dual-source CodeRepository skill update."""
|
|
135
|
-
|
|
136
|
-
code_repository_dir: Path
|
|
137
|
-
destination_root: Path
|
|
138
|
-
sentinel_path: Path
|
|
139
|
-
sdk_library_name: str
|
|
140
|
-
sdk_version: str
|
|
141
|
-
sdk_skills_path: Path
|
|
142
|
-
platform_catalog: PlatformCodeRepositorySkillCatalog
|
|
143
|
-
installed: tuple[InstalledCodeRepositorySkill, ...]
|
|
144
|
-
|
|
145
|
-
|
|
146
123
|
def parse_platform_code_repository_skill_catalog(
|
|
147
124
|
rows: Sequence[dict[str, Any]],
|
|
148
125
|
*,
|
|
@@ -463,196 +440,70 @@ def _validate_platform_resource_payload(
|
|
|
463
440
|
)
|
|
464
441
|
|
|
465
442
|
|
|
466
|
-
def
|
|
443
|
+
def install_platform_code_repository_skills(
|
|
467
444
|
*,
|
|
468
445
|
code_repository_dir: Path,
|
|
469
|
-
sdk_library_name: str,
|
|
470
|
-
sdk_skills_path: Path,
|
|
471
|
-
sdk_version: str,
|
|
472
446
|
platform_catalog: PlatformCodeRepositorySkillCatalog,
|
|
473
|
-
namespace: str = "mainsequence",
|
|
474
|
-
command: str = "mainsequence code-repository update-agent-skills",
|
|
475
447
|
protected_code_repository_roots: Sequence[Path] = (),
|
|
476
|
-
) ->
|
|
477
|
-
"""
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
448
|
+
) -> tuple[Path, tuple[InstalledCodeRepositorySkill, ...]]:
|
|
449
|
+
"""Replace only the platform-owned mainsequence_platform skill namespace."""
|
|
450
|
+
repository = code_repository_dir.expanduser().resolve()
|
|
451
|
+
namespace = repository / ".agents" / "skills" / "mainsequence_platform"
|
|
452
|
+
if namespace.is_symlink():
|
|
453
|
+
raise CodeRepositorySkillAssemblyError("Platform namespace must not be a symlink.")
|
|
454
|
+
destination = namespace.resolve()
|
|
455
|
+
if not destination.is_relative_to(repository):
|
|
456
|
+
raise CodeRepositorySkillAssemblyError("Platform destination escapes the target checkout.")
|
|
457
|
+
_check_code_repository_guards(
|
|
458
|
+
code_repository_dir=repository,
|
|
487
459
|
protected_code_repository_roots=protected_code_repository_roots,
|
|
460
|
+
code_repository_guard=None,
|
|
488
461
|
)
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
462
|
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
463
|
+
staging = Path(
|
|
464
|
+
tempfile.mkdtemp(prefix=".mainsequence_platform.staging-", dir=destination.parent)
|
|
492
465
|
)
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
installed: list[InstalledCodeRepositorySkill] = []
|
|
466
|
+
installed = []
|
|
467
|
+
lines = [
|
|
468
|
+
"schema=platform-1",
|
|
469
|
+
"owner=platform",
|
|
470
|
+
f"platform_source_url={_sentinel_value(platform_catalog.source_url)}",
|
|
471
|
+
f"platform_retrieved_at_utc={_utc_timestamp()}",
|
|
472
|
+
f"platform_manifest_version={platform_catalog.manifest_version}",
|
|
473
|
+
f"platform_manifest_sha256={platform_catalog.manifest_sha256}",
|
|
474
|
+
f"platform_ontology_sha256={platform_catalog.ontology_sha256}",
|
|
475
|
+
]
|
|
505
476
|
try:
|
|
506
|
-
for item in sdk_plan.copied:
|
|
507
|
-
staged_destination = staging_root / item.name
|
|
508
|
-
shutil.copytree(item.source, staged_destination)
|
|
509
|
-
installed.append(
|
|
510
|
-
InstalledCodeRepositorySkill(
|
|
511
|
-
name=item.name,
|
|
512
|
-
owner="sdk",
|
|
513
|
-
source=str(item.source),
|
|
514
|
-
destination=destination_root / item.name,
|
|
515
|
-
)
|
|
516
|
-
)
|
|
517
|
-
|
|
518
477
|
for skill in platform_catalog.skills:
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
478
|
+
target = staging.joinpath(*skill.relative_path.parts)
|
|
479
|
+
if not target.resolve().is_relative_to(staging):
|
|
480
|
+
raise CodeRepositorySkillAssemblyError("Platform skill path escapes its namespace.")
|
|
481
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
482
|
+
target.write_text(skill.content, encoding="utf-8")
|
|
522
483
|
installed.append(
|
|
523
484
|
InstalledCodeRepositorySkill(
|
|
524
485
|
name=skill.name,
|
|
525
486
|
owner="platform",
|
|
526
487
|
source=skill.uri,
|
|
527
|
-
destination=
|
|
488
|
+
destination=destination.joinpath(*skill.relative_path.parts),
|
|
528
489
|
content_sha256=skill.content_sha256,
|
|
529
490
|
)
|
|
530
491
|
)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
encoding="utf-8",
|
|
543
|
-
)
|
|
544
|
-
_replace_managed_tree(
|
|
545
|
-
staging_root=staging_root,
|
|
546
|
-
destination_root=destination_root,
|
|
547
|
-
)
|
|
492
|
+
for resource in platform_catalog.resources:
|
|
493
|
+
prefix = f"platform_resource.{resource.name}"
|
|
494
|
+
lines.extend(
|
|
495
|
+
[
|
|
496
|
+
f"{prefix}.uri={_sentinel_value(resource.uri)}",
|
|
497
|
+
f"{prefix}.path={_sentinel_value(str(resource.resource_path))}",
|
|
498
|
+
f"{prefix}.content_sha256={resource.content_sha256}",
|
|
499
|
+
]
|
|
500
|
+
)
|
|
501
|
+
(staging / PINNED_FROM_FILENAME).write_text("\n".join([*lines, ""]), encoding="utf-8")
|
|
502
|
+
_replace_managed_tree(staging_root=staging, destination_root=destination)
|
|
548
503
|
except Exception:
|
|
549
|
-
|
|
550
|
-
shutil.rmtree(staging_root, ignore_errors=True)
|
|
551
|
-
raise
|
|
552
|
-
|
|
553
|
-
return DualSourceCodeRepositorySkillInstallResult(
|
|
554
|
-
code_repository_dir=sdk_plan.code_repository_dir,
|
|
555
|
-
destination_root=destination_root,
|
|
556
|
-
sentinel_path=destination_root / PINNED_FROM_FILENAME,
|
|
557
|
-
sdk_library_name=sdk_library_name,
|
|
558
|
-
sdk_version=sdk_version,
|
|
559
|
-
sdk_skills_path=sdk_plan.skills_path,
|
|
560
|
-
platform_catalog=platform_catalog,
|
|
561
|
-
installed=tuple(installed),
|
|
562
|
-
)
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
def render_dual_source_sentinel(
|
|
566
|
-
*,
|
|
567
|
-
sdk_library_name: str,
|
|
568
|
-
namespace: str,
|
|
569
|
-
sdk_version: str,
|
|
570
|
-
sdk_skills_path: Path,
|
|
571
|
-
platform_catalog: PlatformCodeRepositorySkillCatalog,
|
|
572
|
-
command: str,
|
|
573
|
-
) -> str:
|
|
574
|
-
"""Render the schema-2 dual-source provenance record."""
|
|
575
|
-
|
|
576
|
-
installed_at_utc = _utc_timestamp()
|
|
577
|
-
lines = [
|
|
578
|
-
f"schema={DUAL_SOURCE_SENTINEL_SCHEMA}",
|
|
579
|
-
f"library_name={_sentinel_value(sdk_library_name)}",
|
|
580
|
-
f"namespace={_sentinel_value(namespace)}",
|
|
581
|
-
f"pinned_version={_sentinel_value(sdk_version)}",
|
|
582
|
-
f"skills_path={_sentinel_value(str(sdk_skills_path.resolve()))}",
|
|
583
|
-
f"copied_at_utc={installed_at_utc}",
|
|
584
|
-
f"installed_at_utc={installed_at_utc}",
|
|
585
|
-
f"sdk_library_name={_sentinel_value(sdk_library_name)}",
|
|
586
|
-
f"sdk_version={_sentinel_value(sdk_version)}",
|
|
587
|
-
f"sdk_skills_path={_sentinel_value(str(sdk_skills_path.resolve()))}",
|
|
588
|
-
f"platform_source_url={_sentinel_value(platform_catalog.source_url)}",
|
|
589
|
-
f"platform_retrieved_at_utc={installed_at_utc}",
|
|
590
|
-
f"platform_manifest_version={platform_catalog.manifest_version}",
|
|
591
|
-
f"platform_manifest_sha256={platform_catalog.manifest_sha256}",
|
|
592
|
-
f"platform_ontology_uri={platform_catalog.ontology_uri}",
|
|
593
|
-
f"platform_ontology_sha256={platform_catalog.ontology_sha256}",
|
|
594
|
-
f"platform_resource_count={len(platform_catalog.resources)}",
|
|
595
|
-
f"platform_skill_count={len(platform_catalog.skills)}",
|
|
596
|
-
]
|
|
597
|
-
for resource in platform_catalog.resources:
|
|
598
|
-
prefix = f"platform_resource.{resource.name}"
|
|
599
|
-
lines.extend(
|
|
600
|
-
[
|
|
601
|
-
f"{prefix}.uri={_sentinel_value(resource.uri)}",
|
|
602
|
-
f"{prefix}.path={_sentinel_value(str(resource.resource_path))}",
|
|
603
|
-
f"{prefix}.content_sha256={resource.content_sha256}",
|
|
604
|
-
]
|
|
605
|
-
)
|
|
606
|
-
lines.extend(
|
|
607
|
-
[
|
|
608
|
-
f"command={_sentinel_value(command)}",
|
|
609
|
-
"",
|
|
610
|
-
]
|
|
611
|
-
)
|
|
612
|
-
return "\n".join(lines)
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
def _validate_source_ownership(
|
|
616
|
-
*,
|
|
617
|
-
sdk_skills: Sequence[CopiedScaffoldSkill],
|
|
618
|
-
platform_skills: Sequence[PlatformCodeRepositorySkill],
|
|
619
|
-
) -> None:
|
|
620
|
-
sdk_roots = {item.name for item in sdk_skills}
|
|
621
|
-
collisions = sorted(
|
|
622
|
-
{
|
|
623
|
-
skill.relative_path.parts[0]
|
|
624
|
-
for skill in platform_skills
|
|
625
|
-
if skill.relative_path.parts[0] in sdk_roots
|
|
626
|
-
}
|
|
627
|
-
)
|
|
628
|
-
if collisions:
|
|
629
|
-
raise CodeRepositorySkillAssemblyError(
|
|
630
|
-
"SDK/platform skill path ownership collision: "
|
|
631
|
-
+ ", ".join(collisions)
|
|
632
|
-
+ ". Refactor the SDK-owned skill path before updating the CodeRepository."
|
|
633
|
-
)
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
def _replace_managed_tree(*, staging_root: Path, destination_root: Path) -> None:
|
|
637
|
-
backup_root = destination_root.parent / (f".{destination_root.name}.backup-{uuid.uuid4().hex}")
|
|
638
|
-
destination_existed = destination_root.exists()
|
|
639
|
-
if destination_existed:
|
|
640
|
-
os.replace(destination_root, backup_root)
|
|
641
|
-
try:
|
|
642
|
-
os.replace(staging_root, destination_root)
|
|
643
|
-
except Exception as install_exc:
|
|
644
|
-
try:
|
|
645
|
-
if destination_existed and backup_root.exists():
|
|
646
|
-
os.replace(backup_root, destination_root)
|
|
647
|
-
except Exception as rollback_exc:
|
|
648
|
-
raise CodeRepositorySkillAssemblyError(
|
|
649
|
-
"CodeRepository skill installation failed and rollback also failed: "
|
|
650
|
-
f"{rollback_exc}. The previous managed tree remains at "
|
|
651
|
-
f"{backup_root} for manual recovery."
|
|
652
|
-
) from install_exc
|
|
504
|
+
shutil.rmtree(staging, ignore_errors=True)
|
|
653
505
|
raise
|
|
654
|
-
|
|
655
|
-
shutil.rmtree(backup_root, ignore_errors=True)
|
|
506
|
+
return destination, tuple(installed)
|
|
656
507
|
|
|
657
508
|
|
|
658
509
|
def _safe_platform_resource_path(
|
mainsequence/scaffold_skills.py
CHANGED
|
@@ -9,10 +9,13 @@ records the installed library version that supplied the copied skills.
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
11
|
import datetime as _datetime
|
|
12
|
+
import os
|
|
12
13
|
import re
|
|
13
14
|
import shutil
|
|
15
|
+
import tempfile
|
|
16
|
+
import uuid
|
|
14
17
|
from collections.abc import Callable, Sequence
|
|
15
|
-
from dataclasses import dataclass
|
|
18
|
+
from dataclasses import dataclass, replace
|
|
16
19
|
from pathlib import Path
|
|
17
20
|
|
|
18
21
|
PINNED_FROM_FILENAME = "PINNED_FROM.txt"
|
|
@@ -64,9 +67,10 @@ def copy_scaffold_skills(
|
|
|
64
67
|
"""Copy packaged scaffold skills into a managed CodeRepository skill namespace.
|
|
65
68
|
|
|
66
69
|
The helper copies each immediate child skill directory from `skills_path` to
|
|
67
|
-
`<code_repository_dir>/.agents/skills/<namespace
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
`<code_repository_dir>/.agents/skills/<namespace>/`. That entire namespace is
|
|
71
|
+
library-owned: folders no longer shipped by the library are removed. The
|
|
72
|
+
replacement is staged and atomic. Other namespaces are never changed.
|
|
73
|
+
Source files, hidden folders, and folders starting with `__` are skipped.
|
|
70
74
|
|
|
71
75
|
`pinned_version` is required and must be the installed version of the
|
|
72
76
|
library that owns `skills_path`. On successful non-dry-run copies, the
|
|
@@ -86,10 +90,15 @@ def copy_scaffold_skills(
|
|
|
86
90
|
if not resolved_skills_path.is_dir():
|
|
87
91
|
raise FileNotFoundError(f"Scaffold skill source directory does not exist: {skills_path}")
|
|
88
92
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
destination = resolved_code_repository_dir / ".agents" / "skills" / resolved_namespace
|
|
94
|
+
if destination.is_symlink():
|
|
95
|
+
raise ScaffoldSkillCopyBlocked("Blocked: the managed namespace must not be a symlink.")
|
|
96
|
+
destination_root = destination.resolve(strict=False)
|
|
92
97
|
sentinel_path = destination_root / PINNED_FROM_FILENAME
|
|
98
|
+
if not destination_root.is_relative_to(resolved_code_repository_dir):
|
|
99
|
+
raise ScaffoldSkillCopyBlocked(
|
|
100
|
+
"Blocked: destination namespace escapes the target checkout."
|
|
101
|
+
)
|
|
93
102
|
|
|
94
103
|
_check_code_repository_guards(
|
|
95
104
|
code_repository_dir=resolved_code_repository_dir,
|
|
@@ -134,13 +143,26 @@ def copy_scaffold_skills(
|
|
|
134
143
|
if dry_run:
|
|
135
144
|
return result
|
|
136
145
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
result,
|
|
141
|
-
command=command,
|
|
142
|
-
copied_at_utc=_utc_timestamp(),
|
|
146
|
+
destination_root.parent.mkdir(parents=True, exist_ok=True)
|
|
147
|
+
staging_root = Path(
|
|
148
|
+
tempfile.mkdtemp(prefix=f".{resolved_namespace}.staging-", dir=destination_root.parent)
|
|
143
149
|
)
|
|
150
|
+
try:
|
|
151
|
+
for item in copied:
|
|
152
|
+
shutil.copytree(item.source, staging_root / item.name)
|
|
153
|
+
_write_pin_sentinel(
|
|
154
|
+
replace(
|
|
155
|
+
result,
|
|
156
|
+
destination_root=staging_root,
|
|
157
|
+
sentinel_path=staging_root / PINNED_FROM_FILENAME,
|
|
158
|
+
),
|
|
159
|
+
command=command,
|
|
160
|
+
copied_at_utc=_utc_timestamp(),
|
|
161
|
+
)
|
|
162
|
+
_replace_managed_tree(staging_root=staging_root, destination_root=destination_root)
|
|
163
|
+
except Exception:
|
|
164
|
+
shutil.rmtree(staging_root, ignore_errors=True)
|
|
165
|
+
raise
|
|
144
166
|
return result
|
|
145
167
|
|
|
146
168
|
|
|
@@ -182,11 +204,25 @@ def _iter_skill_roots(skills_path: Path) -> list[Path]:
|
|
|
182
204
|
]
|
|
183
205
|
|
|
184
206
|
|
|
185
|
-
def
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
207
|
+
def _replace_managed_tree(*, staging_root: Path, destination_root: Path) -> None:
|
|
208
|
+
backup_root = destination_root.parent / f".{destination_root.name}.backup-{uuid.uuid4().hex}"
|
|
209
|
+
destination_existed = destination_root.exists()
|
|
210
|
+
if destination_existed:
|
|
211
|
+
os.replace(destination_root, backup_root)
|
|
212
|
+
try:
|
|
213
|
+
os.replace(staging_root, destination_root)
|
|
214
|
+
except Exception as install_exc:
|
|
215
|
+
try:
|
|
216
|
+
if destination_existed and backup_root.exists():
|
|
217
|
+
os.replace(backup_root, destination_root)
|
|
218
|
+
except Exception as rollback_exc:
|
|
219
|
+
raise ScaffoldSkillCopyBlocked(
|
|
220
|
+
f"Skill installation and rollback failed: {rollback_exc}. "
|
|
221
|
+
f"The previous tree remains at {backup_root} for recovery."
|
|
222
|
+
) from install_exc
|
|
223
|
+
raise
|
|
224
|
+
if backup_root.exists():
|
|
225
|
+
shutil.rmtree(backup_root, ignore_errors=True)
|
|
190
226
|
|
|
191
227
|
|
|
192
228
|
def _write_pin_sentinel(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
agent_scaffold/AGENTS.md,sha256=
|
|
1
|
+
agent_scaffold/AGENTS.md,sha256=yLTuL2VuT47JoBa7w7eekcWhenWciySPQmO9mAIBALE,6178
|
|
2
2
|
agent_scaffold/skills/a2a_sdk_execution/SKILL.md,sha256=NKtcXibE8TxZzKzz1KzJ2cVZ_EeuJJkb660U6wLvZ3s,11809
|
|
3
3
|
agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md,sha256=zETXg2fFCujdorOqI2yjhH4Zv1nS16il8uuohF3jz60,13883
|
|
4
4
|
agent_scaffold/skills/maintenance/bug_auditor/SKILL.md,sha256=pV8g6FbSgZu1ZsrCaWAbrf6MpetxMqoZKO1rBbtZMgs,8591
|
|
5
|
-
agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md,sha256=
|
|
5
|
+
agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md,sha256=PczPIOM1YPyXlgd7i5OyN5DkYVwGHrDowsyoxzAqsi8,13396
|
|
6
6
|
agent_scaffold/skills/maintenance/metatables_transition/SKILL.md,sha256=PisgpytcksJnfZMS6aiPCmahsT3fm8DIwk_cefXA2qU,3759
|
|
7
7
|
agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md,sha256=o1rIlYAC7ejV7gKKf-BaglIZY1YkDO5Y27F6e2eK_94,8571
|
|
8
8
|
agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md,sha256=F2I_pwzhbVW-32pBHQZfLnX6BC76iiILHZU1ewy2VYo,15245
|
|
@@ -12,16 +12,16 @@ mainsequence/__main__.py,sha256=KuAP69uduS2ImrPIgNMzbGBRepZzjqvUONu5vFh4v4A,176
|
|
|
12
12
|
mainsequence/_request_identity.py,sha256=jiroPFVDM8vphEf9VXuggQJKUOGohfk7-pDwJSOILEw,1211
|
|
13
13
|
mainsequence/bootstrap.py,sha256=AvG55Y46RcshVqJZsyqvUDN62CJg4CDbHu0Bvsbwfzs,2910
|
|
14
14
|
mainsequence/code_repository_context.py,sha256=8Q1ammEJr0m8G8aMR4Mf6nLHMPe51sPr4m72PSwp3D4,28588
|
|
15
|
-
mainsequence/code_repository_skills.py,sha256=
|
|
15
|
+
mainsequence/code_repository_skills.py,sha256=AyC1HFAxQXHXNBGbarVUJS2cHd4X5HwDx6u8XBophbE,23611
|
|
16
16
|
mainsequence/defaults.py,sha256=5r6s7AI-X40rpm1D3IgcNsWam7iJg4_lIxB3F_1u2z0,408
|
|
17
17
|
mainsequence/logconf.py,sha256=7OXSBb8yXrUbIbO4vX-l0vss1R8q1DlNi1-fBNkjX-w,18693
|
|
18
18
|
mainsequence/repository_identity_security.py,sha256=Cdywndhiy1zJFUPh-FfM90RjZ3Hg3tjhxBr64FRhmXs,1035
|
|
19
19
|
mainsequence/runtime_flags.py,sha256=1eTM7VRRhnuZ_GXcmFhqAmdEKwyQYMyZcPsio88vJRQ,378
|
|
20
|
-
mainsequence/scaffold_skills.py,sha256=
|
|
20
|
+
mainsequence/scaffold_skills.py,sha256=k0V6eKC5AwbHr9wB9UGMJNF-8eJ0_1izF4-BU01KHrg,10606
|
|
21
21
|
mainsequence/cli/__init__.py,sha256=sMWTnomCaISjnureLuXFRqOzkH2Y77uYEivsd-M6_8Y,28
|
|
22
22
|
mainsequence/cli/api.py,sha256=r9D0lSaw2Ah-39i04w9JgNkg3yjq88TLesB63B6nvug,128586
|
|
23
23
|
mainsequence/cli/browser_auth.py,sha256=C-Sbpt0Pr9Pv3Z9dO80TMk7zPcaaZ-4zvW0tbRVMrTU,9863
|
|
24
|
-
mainsequence/cli/cli.py,sha256=
|
|
24
|
+
mainsequence/cli/cli.py,sha256=JnueoyzZ0t99m7RIwmeUNWYNPUo8gNntpcBeaL0bERk,276172
|
|
25
25
|
mainsequence/cli/code_repository_status.py,sha256=SHEnU8YSWFowPG6dEdE4Yd8CS1tIcJSE1MXFLfvD3Os,5975
|
|
26
26
|
mainsequence/cli/config.py,sha256=4AGDEUPAJ1GzoDX3FzYYFvGMKfeAXM38Kh7Yv-OQLQQ,45595
|
|
27
27
|
mainsequence/cli/docker_utils.py,sha256=eAnp9MI042cHWwKasA5IF2I7INL3A6tV2JX-cSIe7rc,10687
|
|
@@ -50,9 +50,9 @@ mainsequence/instrumentation/utils.py,sha256=b-ihjSioAepeLfMpudM2SqCtvnxMqIXileH
|
|
|
50
50
|
mainsequence/server/__init__.py,sha256=559DiiBcCP6veWRmK2mXUEbsl7gbZofTvsbTUFjn0VE,82
|
|
51
51
|
mainsequence/server/caller_assertions.py,sha256=5q8LZrDYozaonG1eBb9P8DojKQlB2i2qUJwO5VhsrW4,9780
|
|
52
52
|
mainsequence/server/fastapi.py,sha256=tD1aVuJOgoBTu7H8bs9IldPNYRT4fhkr1leN3KZP1pI,10521
|
|
53
|
-
mainsequence-9.0.
|
|
54
|
-
mainsequence-9.0.
|
|
55
|
-
mainsequence-9.0.
|
|
56
|
-
mainsequence-9.0.
|
|
57
|
-
mainsequence-9.0.
|
|
58
|
-
mainsequence-9.0.
|
|
53
|
+
mainsequence-9.0.2.dev32.dist-info/licenses/LICENSE,sha256=b6Ecsk8wjsEby3lbSzdljR6hHiFGHBizt9iWV2p1c_I,1074
|
|
54
|
+
mainsequence-9.0.2.dev32.dist-info/METADATA,sha256=m2rgtp3Cz2nDtlUChD40l1GN8z3VdQcl0pykNLdxDGo,7435
|
|
55
|
+
mainsequence-9.0.2.dev32.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
56
|
+
mainsequence-9.0.2.dev32.dist-info/entry_points.txt,sha256=XGAOq3-mF2lWWpeRJvoaWyMarRcK167mH1g124aGdUs,88
|
|
57
|
+
mainsequence-9.0.2.dev32.dist-info/top_level.txt,sha256=BFeblM_Q9q0cUWBvTxnfWcWQEHtf5XZi9nOS-Gdfwus,28
|
|
58
|
+
mainsequence-9.0.2.dev32.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|