qlogicagent 2.16.6 → 2.16.8

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 (97) hide show
  1. package/dist/agent.js +16 -16
  2. package/dist/cli.js +412 -413
  3. package/dist/default-project-knowledge/INSTRUCTIONS.md +7 -0
  4. package/dist/default-project-knowledge/rules/project-workflow.md +6 -0
  5. package/dist/index.js +411 -412
  6. package/dist/protocol.js +1 -1
  7. package/dist/types/cli/agent-runtime-bootstrap.d.ts +1 -0
  8. package/dist/types/cli/base-tool-bootstrap.d.ts +3 -0
  9. package/dist/types/cli/handlers/community-handler.d.ts +2 -28
  10. package/dist/types/cli/handlers/files-handler.d.ts +6 -0
  11. package/dist/types/cli/handlers/message-feedback-handler.d.ts +31 -0
  12. package/dist/types/cli/handlers/pet-handler.d.ts +1 -0
  13. package/dist/types/cli/handlers/project-handler.d.ts +1 -0
  14. package/dist/types/cli/handlers/turn-baseline-handler.d.ts +8 -0
  15. package/dist/types/cli/handlers/turn-handler.d.ts +5 -0
  16. package/dist/types/cli/handlers/workflow-handler.d.ts +0 -11
  17. package/dist/types/cli/handlers/working-materials-handler.d.ts +9 -0
  18. package/dist/types/cli/idle-dream-coordinator.d.ts +6 -0
  19. package/dist/types/cli/mcp-bootstrap.d.ts +1 -0
  20. package/dist/types/cli/memory-coordinator.d.ts +1 -0
  21. package/dist/types/cli/project-template-seeder.d.ts +2 -2
  22. package/dist/types/cli/rpc-registry.d.ts +6 -0
  23. package/dist/types/cli/runtime-hook-bootstrap.d.ts +1 -0
  24. package/dist/types/cli/stdio-agent-session-bootstrap.d.ts +1 -0
  25. package/dist/types/cli/stdio-rpc-handler-hosts.d.ts +1 -0
  26. package/dist/types/cli/stdio-runtime-bootstrap.d.ts +1 -0
  27. package/dist/types/cli/tool-bootstrap-community-registration.d.ts +0 -6
  28. package/dist/types/cli/tool-bootstrap-core-registration.d.ts +2 -0
  29. package/dist/types/cli/tool-bootstrap.d.ts +2 -0
  30. package/dist/types/cli/turn-skill-autopersist.d.ts +0 -25
  31. package/dist/types/protocol/methods.d.ts +24 -201
  32. package/dist/types/protocol/wire/agent-events.d.ts +2 -2
  33. package/dist/types/protocol/wire/agent-methods.d.ts +10 -205
  34. package/dist/types/protocol/wire/gateway-rpc.d.ts +160 -0
  35. package/dist/types/protocol/wire/notification-payloads.d.ts +34 -0
  36. package/dist/types/runtime/community/community-consent-client.d.ts +9 -186
  37. package/dist/types/runtime/community/community-discovery-coordinator.d.ts +1 -1
  38. package/dist/types/runtime/infra/default-path-service.d.ts +1 -1
  39. package/dist/types/runtime/infra/feedback-distillation-worker.d.ts +20 -0
  40. package/dist/types/runtime/infra/feedback-distillation.d.ts +30 -0
  41. package/dist/types/runtime/infra/feedback-event-store.d.ts +179 -0
  42. package/dist/types/runtime/infra/feedback-outbox.d.ts +26 -0
  43. package/dist/types/runtime/infra/feedback-redaction.d.ts +71 -0
  44. package/dist/types/runtime/infra/feedback-upload-client.d.ts +40 -0
  45. package/dist/types/runtime/infra/feedback-upload-worker.d.ts +11 -0
  46. package/dist/types/runtime/infra/project-data-paths.d.ts +5 -5
  47. package/dist/types/runtime/infra/turn-baseline-store.d.ts +102 -0
  48. package/dist/types/runtime/infra/turn-telemetry-store.d.ts +59 -0
  49. package/dist/types/runtime/infra/working-materials-store.d.ts +35 -0
  50. package/dist/types/runtime/pet/daily-journey-summarizer.d.ts +25 -0
  51. package/dist/types/runtime/pet/index.d.ts +2 -1
  52. package/dist/types/runtime/pet/journey-catchup.d.ts +14 -0
  53. package/dist/types/runtime/pet/journey-day-aggregator.d.ts +27 -0
  54. package/dist/types/runtime/pet/journey-narrative-prompt.d.ts +8 -0
  55. package/dist/types/runtime/pet/pet-profile-service.d.ts +14 -1
  56. package/dist/types/runtime/ports/memory-provider.d.ts +6 -0
  57. package/dist/types/runtime/ports/path-service.d.ts +1 -1
  58. package/dist/types/runtime/ports/tool-contracts.d.ts +2 -0
  59. package/dist/types/runtime/prompt/fresh-workspace-evidence.d.ts +14 -0
  60. package/dist/types/runtime/prompt/instruction-loader.d.ts +7 -7
  61. package/dist/types/skills/mcp/mcp-manager.d.ts +11 -0
  62. package/dist/types/skills/memory/local-memory-provider.d.ts +3 -3
  63. package/dist/types/skills/memory/local-store-records.d.ts +18 -1
  64. package/dist/types/skills/memory/local-store.d.ts +8 -195
  65. package/dist/types/skills/memory/memory-consolidation.d.ts +14 -0
  66. package/dist/types/skills/memory/sqlite-memory-schema.d.ts +1 -1
  67. package/dist/types/skills/plugins/plugin-marketplace.d.ts +1 -1
  68. package/dist/types/skills/tools/community-seek-tool.d.ts +0 -33
  69. package/dist/types/skills/tools/instructions-tool.d.ts +2 -2
  70. package/dist/types/skills/tools/skill-tool.d.ts +1 -1
  71. package/dist/vendor/hatch-pet/LICENSE.txt +201 -201
  72. package/dist/vendor/hatch-pet/NOTICE.md +25 -25
  73. package/dist/vendor/hatch-pet/references/animation-rows.md +29 -29
  74. package/dist/vendor/hatch-pet/references/codex-pet-contract.md +35 -35
  75. package/dist/vendor/hatch-pet/references/qa-rubric.md +66 -66
  76. package/dist/vendor/hatch-pet/scripts/compose_atlas.py +169 -169
  77. package/dist/vendor/hatch-pet/scripts/derive_running_left_from_running_right.py +150 -150
  78. package/dist/vendor/hatch-pet/scripts/extract_strip_frames.py +408 -408
  79. package/dist/vendor/hatch-pet/scripts/inspect_frames.py +256 -256
  80. package/dist/vendor/hatch-pet/scripts/make_contact_sheet.py +96 -96
  81. package/dist/vendor/hatch-pet/scripts/prepare_pet_run.py +834 -834
  82. package/dist/vendor/hatch-pet/scripts/render_animation_previews.py +78 -78
  83. package/dist/vendor/hatch-pet/scripts/validate_atlas.py +157 -157
  84. package/package.json +1 -1
  85. package/dist/types/runtime/community/activity-event-emitter.d.ts +0 -31
  86. package/dist/types/runtime/community/activity-event.d.ts +0 -62
  87. package/dist/types/runtime/community/community-desensitization-red-team-cli.d.ts +0 -7
  88. package/dist/types/runtime/community/community-desensitization.d.ts +0 -29
  89. package/dist/types/runtime/community/community-pet-publisher.d.ts +0 -27
  90. package/dist/types/runtime/community/community-signal-reporter.d.ts +0 -19
  91. package/dist/types/runtime/community/community-telemetry-metadata.d.ts +0 -4
  92. package/dist/types/runtime/community/community-telemetry-recorder.d.ts +0 -6
  93. package/dist/types/runtime/community/community-telemetry-types.d.ts +0 -1
  94. package/dist/types/runtime/community/pet-activity-sink.d.ts +0 -36
  95. package/dist/types/runtime/community/pet-key.d.ts +0 -7
  96. package/dist/types/runtime/community/roaming-gate.d.ts +0 -19
  97. package/dist/types/runtime/community/social-emission.d.ts +0 -16
@@ -1,78 +1,78 @@
1
- #!/usr/bin/env python3
2
- """Render lightweight animated QA previews from extracted Codex pet frames."""
3
-
4
- from __future__ import annotations
5
-
6
- import argparse
7
- import json
8
- from pathlib import Path
9
-
10
- from PIL import Image
11
-
12
- ROW_DURATIONS = {
13
- "idle": [280, 110, 110, 140, 140, 320],
14
- "running-right": [120, 120, 120, 120, 120, 120, 120, 220],
15
- "running-left": [120, 120, 120, 120, 120, 120, 120, 220],
16
- "waving": [140, 140, 140, 280],
17
- "jumping": [140, 140, 140, 140, 280],
18
- "failed": [140, 140, 140, 140, 140, 140, 140, 240],
19
- "waiting": [150, 150, 150, 150, 150, 260],
20
- "running": [120, 120, 120, 120, 120, 220],
21
- "review": [150, 150, 150, 150, 150, 280],
22
- }
23
- IMAGE_SUFFIXES = {".png", ".webp", ".jpg", ".jpeg"}
24
-
25
-
26
- def frame_files(state_dir: Path) -> list[Path]:
27
- if not state_dir.is_dir():
28
- return []
29
- return sorted(path for path in state_dir.iterdir() if path.suffix.lower() in IMAGE_SUFFIXES)
30
-
31
-
32
- def load_frames(frames_root: Path, state: str, expected_count: int) -> list[Image.Image]:
33
- files = frame_files(frames_root / state)
34
- if len(files) != expected_count:
35
- raise SystemExit(
36
- f"{state} preview needs {expected_count} frames, found {len(files)} under {frames_root / state}"
37
- )
38
- frames = []
39
- for path in files:
40
- with Image.open(path) as opened:
41
- frames.append(opened.convert("RGBA"))
42
- return frames
43
-
44
-
45
- def save_preview(frames: list[Image.Image], durations: list[int], output: Path) -> None:
46
- output.parent.mkdir(parents=True, exist_ok=True)
47
- frames[0].save(
48
- output,
49
- save_all=True,
50
- append_images=frames[1:],
51
- duration=durations,
52
- loop=0,
53
- disposal=2,
54
- optimize=False,
55
- )
56
-
57
-
58
- def main() -> None:
59
- parser = argparse.ArgumentParser(description=__doc__)
60
- parser.add_argument("--frames-root", required=True)
61
- parser.add_argument("--output-dir", required=True)
62
- args = parser.parse_args()
63
-
64
- frames_root = Path(args.frames_root).expanduser().resolve()
65
- output_dir = Path(args.output_dir).expanduser().resolve()
66
- previews = []
67
- for state, durations in ROW_DURATIONS.items():
68
- frames = load_frames(frames_root, state, len(durations))
69
- output = output_dir / f"{state}.gif"
70
- save_preview(frames, durations, output)
71
- previews.append({"state": state, "path": str(output), "frames": len(frames)})
72
-
73
- result = {"ok": True, "output_dir": str(output_dir), "previews": previews}
74
- print(json.dumps(result, indent=2))
75
-
76
-
77
- if __name__ == "__main__":
78
- main()
1
+ #!/usr/bin/env python3
2
+ """Render lightweight animated QA previews from extracted Codex pet frames."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ from pathlib import Path
9
+
10
+ from PIL import Image
11
+
12
+ ROW_DURATIONS = {
13
+ "idle": [280, 110, 110, 140, 140, 320],
14
+ "running-right": [120, 120, 120, 120, 120, 120, 120, 220],
15
+ "running-left": [120, 120, 120, 120, 120, 120, 120, 220],
16
+ "waving": [140, 140, 140, 280],
17
+ "jumping": [140, 140, 140, 140, 280],
18
+ "failed": [140, 140, 140, 140, 140, 140, 140, 240],
19
+ "waiting": [150, 150, 150, 150, 150, 260],
20
+ "running": [120, 120, 120, 120, 120, 220],
21
+ "review": [150, 150, 150, 150, 150, 280],
22
+ }
23
+ IMAGE_SUFFIXES = {".png", ".webp", ".jpg", ".jpeg"}
24
+
25
+
26
+ def frame_files(state_dir: Path) -> list[Path]:
27
+ if not state_dir.is_dir():
28
+ return []
29
+ return sorted(path for path in state_dir.iterdir() if path.suffix.lower() in IMAGE_SUFFIXES)
30
+
31
+
32
+ def load_frames(frames_root: Path, state: str, expected_count: int) -> list[Image.Image]:
33
+ files = frame_files(frames_root / state)
34
+ if len(files) != expected_count:
35
+ raise SystemExit(
36
+ f"{state} preview needs {expected_count} frames, found {len(files)} under {frames_root / state}"
37
+ )
38
+ frames = []
39
+ for path in files:
40
+ with Image.open(path) as opened:
41
+ frames.append(opened.convert("RGBA"))
42
+ return frames
43
+
44
+
45
+ def save_preview(frames: list[Image.Image], durations: list[int], output: Path) -> None:
46
+ output.parent.mkdir(parents=True, exist_ok=True)
47
+ frames[0].save(
48
+ output,
49
+ save_all=True,
50
+ append_images=frames[1:],
51
+ duration=durations,
52
+ loop=0,
53
+ disposal=2,
54
+ optimize=False,
55
+ )
56
+
57
+
58
+ def main() -> None:
59
+ parser = argparse.ArgumentParser(description=__doc__)
60
+ parser.add_argument("--frames-root", required=True)
61
+ parser.add_argument("--output-dir", required=True)
62
+ args = parser.parse_args()
63
+
64
+ frames_root = Path(args.frames_root).expanduser().resolve()
65
+ output_dir = Path(args.output_dir).expanduser().resolve()
66
+ previews = []
67
+ for state, durations in ROW_DURATIONS.items():
68
+ frames = load_frames(frames_root, state, len(durations))
69
+ output = output_dir / f"{state}.gif"
70
+ save_preview(frames, durations, output)
71
+ previews.append({"state": state, "path": str(output), "frames": len(frames)})
72
+
73
+ result = {"ok": True, "output_dir": str(output_dir), "previews": previews}
74
+ print(json.dumps(result, indent=2))
75
+
76
+
77
+ if __name__ == "__main__":
78
+ main()
@@ -1,157 +1,157 @@
1
- #!/usr/bin/env python3
2
- """Validate a Codex pet spritesheet atlas."""
3
-
4
- from __future__ import annotations
5
-
6
- import argparse
7
- import json
8
- from collections import defaultdict
9
- from pathlib import Path
10
-
11
- from PIL import Image
12
-
13
- COLUMNS = 8
14
- ROWS = 9
15
- CELL_WIDTH = 192
16
- CELL_HEIGHT = 208
17
- ATLAS_WIDTH = COLUMNS * CELL_WIDTH
18
- ATLAS_HEIGHT = ROWS * CELL_HEIGHT
19
- ROW_BY_INDEX = {
20
- 0: ("idle", 6),
21
- 1: ("running-right", 8),
22
- 2: ("running-left", 8),
23
- 3: ("waving", 4),
24
- 4: ("jumping", 5),
25
- 5: ("failed", 8),
26
- 6: ("waiting", 6),
27
- 7: ("running", 6),
28
- 8: ("review", 6),
29
- }
30
-
31
-
32
- def alpha_nonzero_count(image: Image.Image) -> int:
33
- alpha = image.getchannel("A")
34
- return sum(alpha.histogram()[1:])
35
-
36
-
37
- def transparent_rgb_residue_count(image: Image.Image) -> int:
38
- rgba = image.convert("RGBA")
39
- data = rgba.tobytes()
40
- count = 0
41
- for index in range(0, len(data), 4):
42
- red, green, blue, alpha = data[index : index + 4]
43
- if alpha == 0 and (red or green or blue):
44
- count += 1
45
- return count
46
-
47
-
48
- def main() -> None:
49
- parser = argparse.ArgumentParser(description=__doc__)
50
- parser.add_argument("atlas")
51
- parser.add_argument("--json-out")
52
- parser.add_argument("--min-used-pixels", type=int, default=50)
53
- parser.add_argument("--near-opaque-threshold", type=float, default=0.95)
54
- parser.add_argument("--allow-opaque", action="store_true")
55
- parser.add_argument("--allow-near-opaque-used-cells", action="store_true")
56
- args = parser.parse_args()
57
-
58
- atlas_path = Path(args.atlas).expanduser().resolve()
59
- errors: list[str] = []
60
- warnings: list[str] = []
61
- near_opaque_used_cells: dict[str, list[int]] = defaultdict(list)
62
- cells: list[dict[str, object]] = []
63
-
64
- try:
65
- with Image.open(atlas_path) as opened:
66
- source_mode = opened.mode
67
- source_format = opened.format
68
- image = opened.convert("RGBA")
69
- except Exception as exc: # noqa: BLE001
70
- result = {"ok": False, "errors": [f"could not open atlas: {exc}"], "warnings": []}
71
- print(json.dumps(result, indent=2))
72
- raise SystemExit(1)
73
-
74
- if image.size != (ATLAS_WIDTH, ATLAS_HEIGHT):
75
- errors.append(f"expected {ATLAS_WIDTH}x{ATLAS_HEIGHT}, got {image.width}x{image.height}")
76
-
77
- if source_format not in {"PNG", "WEBP"}:
78
- errors.append(f"expected PNG or WebP, got {source_format}")
79
-
80
- if "A" not in source_mode and not args.allow_opaque:
81
- errors.append("atlas does not have an alpha channel")
82
-
83
- for row_index in range(ROWS):
84
- state, frame_count = ROW_BY_INDEX[row_index]
85
- for column_index in range(COLUMNS):
86
- left = column_index * CELL_WIDTH
87
- top = row_index * CELL_HEIGHT
88
- cell = image.crop((left, top, left + CELL_WIDTH, top + CELL_HEIGHT))
89
- nontransparent = alpha_nonzero_count(cell)
90
- used = column_index < frame_count
91
- cell_info = {
92
- "state": state,
93
- "row": row_index,
94
- "column": column_index,
95
- "used": used,
96
- "nontransparent_pixels": nontransparent,
97
- }
98
- cells.append(cell_info)
99
- if used and nontransparent < args.min_used_pixels:
100
- errors.append(
101
- f"{state} row {row_index} column {column_index} is empty or too sparse ({nontransparent} pixels)"
102
- )
103
- if used and nontransparent > CELL_WIDTH * CELL_HEIGHT * args.near_opaque_threshold:
104
- near_opaque_used_cells[f"{state} row {row_index}"].append(column_index)
105
- if not used and nontransparent != 0:
106
- errors.append(
107
- f"{state} row {row_index} unused column {column_index} is not transparent ({nontransparent} pixels)"
108
- )
109
-
110
- for row_label, columns in near_opaque_used_cells.items():
111
- message = (
112
- f"{row_label} has {len(columns)} nearly opaque used cells; "
113
- "this usually means the sprite has a non-transparent background"
114
- )
115
- if args.allow_near_opaque_used_cells:
116
- warnings.append(message)
117
- else:
118
- errors.append(message)
119
-
120
- alpha_count = alpha_nonzero_count(image)
121
- if alpha_count == ATLAS_WIDTH * ATLAS_HEIGHT:
122
- message = "atlas is fully opaque; custom pets require a transparent sprite background"
123
- if args.allow_opaque:
124
- warnings.append(message)
125
- else:
126
- errors.append(message)
127
-
128
- transparent_rgb_residue = transparent_rgb_residue_count(image)
129
- if transparent_rgb_residue:
130
- errors.append(
131
- f"atlas has {transparent_rgb_residue} fully transparent pixels with non-zero RGB residue"
132
- )
133
-
134
- result = {
135
- "ok": not errors,
136
- "file": str(atlas_path),
137
- "format": source_format,
138
- "mode": source_mode,
139
- "width": image.width,
140
- "height": image.height,
141
- "transparent_rgb_residue_pixels": transparent_rgb_residue,
142
- "errors": errors,
143
- "warnings": warnings,
144
- "cells": cells,
145
- }
146
-
147
- if args.json_out:
148
- Path(args.json_out).expanduser().resolve().write_text(
149
- json.dumps(result, indent=2) + "\n", encoding="utf-8"
150
- )
151
-
152
- print(json.dumps({k: v for k, v in result.items() if k != "cells"}, indent=2))
153
- raise SystemExit(0 if result["ok"] else 1)
154
-
155
-
156
- if __name__ == "__main__":
157
- main()
1
+ #!/usr/bin/env python3
2
+ """Validate a Codex pet spritesheet atlas."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ from collections import defaultdict
9
+ from pathlib import Path
10
+
11
+ from PIL import Image
12
+
13
+ COLUMNS = 8
14
+ ROWS = 9
15
+ CELL_WIDTH = 192
16
+ CELL_HEIGHT = 208
17
+ ATLAS_WIDTH = COLUMNS * CELL_WIDTH
18
+ ATLAS_HEIGHT = ROWS * CELL_HEIGHT
19
+ ROW_BY_INDEX = {
20
+ 0: ("idle", 6),
21
+ 1: ("running-right", 8),
22
+ 2: ("running-left", 8),
23
+ 3: ("waving", 4),
24
+ 4: ("jumping", 5),
25
+ 5: ("failed", 8),
26
+ 6: ("waiting", 6),
27
+ 7: ("running", 6),
28
+ 8: ("review", 6),
29
+ }
30
+
31
+
32
+ def alpha_nonzero_count(image: Image.Image) -> int:
33
+ alpha = image.getchannel("A")
34
+ return sum(alpha.histogram()[1:])
35
+
36
+
37
+ def transparent_rgb_residue_count(image: Image.Image) -> int:
38
+ rgba = image.convert("RGBA")
39
+ data = rgba.tobytes()
40
+ count = 0
41
+ for index in range(0, len(data), 4):
42
+ red, green, blue, alpha = data[index : index + 4]
43
+ if alpha == 0 and (red or green or blue):
44
+ count += 1
45
+ return count
46
+
47
+
48
+ def main() -> None:
49
+ parser = argparse.ArgumentParser(description=__doc__)
50
+ parser.add_argument("atlas")
51
+ parser.add_argument("--json-out")
52
+ parser.add_argument("--min-used-pixels", type=int, default=50)
53
+ parser.add_argument("--near-opaque-threshold", type=float, default=0.95)
54
+ parser.add_argument("--allow-opaque", action="store_true")
55
+ parser.add_argument("--allow-near-opaque-used-cells", action="store_true")
56
+ args = parser.parse_args()
57
+
58
+ atlas_path = Path(args.atlas).expanduser().resolve()
59
+ errors: list[str] = []
60
+ warnings: list[str] = []
61
+ near_opaque_used_cells: dict[str, list[int]] = defaultdict(list)
62
+ cells: list[dict[str, object]] = []
63
+
64
+ try:
65
+ with Image.open(atlas_path) as opened:
66
+ source_mode = opened.mode
67
+ source_format = opened.format
68
+ image = opened.convert("RGBA")
69
+ except Exception as exc: # noqa: BLE001
70
+ result = {"ok": False, "errors": [f"could not open atlas: {exc}"], "warnings": []}
71
+ print(json.dumps(result, indent=2))
72
+ raise SystemExit(1)
73
+
74
+ if image.size != (ATLAS_WIDTH, ATLAS_HEIGHT):
75
+ errors.append(f"expected {ATLAS_WIDTH}x{ATLAS_HEIGHT}, got {image.width}x{image.height}")
76
+
77
+ if source_format not in {"PNG", "WEBP"}:
78
+ errors.append(f"expected PNG or WebP, got {source_format}")
79
+
80
+ if "A" not in source_mode and not args.allow_opaque:
81
+ errors.append("atlas does not have an alpha channel")
82
+
83
+ for row_index in range(ROWS):
84
+ state, frame_count = ROW_BY_INDEX[row_index]
85
+ for column_index in range(COLUMNS):
86
+ left = column_index * CELL_WIDTH
87
+ top = row_index * CELL_HEIGHT
88
+ cell = image.crop((left, top, left + CELL_WIDTH, top + CELL_HEIGHT))
89
+ nontransparent = alpha_nonzero_count(cell)
90
+ used = column_index < frame_count
91
+ cell_info = {
92
+ "state": state,
93
+ "row": row_index,
94
+ "column": column_index,
95
+ "used": used,
96
+ "nontransparent_pixels": nontransparent,
97
+ }
98
+ cells.append(cell_info)
99
+ if used and nontransparent < args.min_used_pixels:
100
+ errors.append(
101
+ f"{state} row {row_index} column {column_index} is empty or too sparse ({nontransparent} pixels)"
102
+ )
103
+ if used and nontransparent > CELL_WIDTH * CELL_HEIGHT * args.near_opaque_threshold:
104
+ near_opaque_used_cells[f"{state} row {row_index}"].append(column_index)
105
+ if not used and nontransparent != 0:
106
+ errors.append(
107
+ f"{state} row {row_index} unused column {column_index} is not transparent ({nontransparent} pixels)"
108
+ )
109
+
110
+ for row_label, columns in near_opaque_used_cells.items():
111
+ message = (
112
+ f"{row_label} has {len(columns)} nearly opaque used cells; "
113
+ "this usually means the sprite has a non-transparent background"
114
+ )
115
+ if args.allow_near_opaque_used_cells:
116
+ warnings.append(message)
117
+ else:
118
+ errors.append(message)
119
+
120
+ alpha_count = alpha_nonzero_count(image)
121
+ if alpha_count == ATLAS_WIDTH * ATLAS_HEIGHT:
122
+ message = "atlas is fully opaque; custom pets require a transparent sprite background"
123
+ if args.allow_opaque:
124
+ warnings.append(message)
125
+ else:
126
+ errors.append(message)
127
+
128
+ transparent_rgb_residue = transparent_rgb_residue_count(image)
129
+ if transparent_rgb_residue:
130
+ errors.append(
131
+ f"atlas has {transparent_rgb_residue} fully transparent pixels with non-zero RGB residue"
132
+ )
133
+
134
+ result = {
135
+ "ok": not errors,
136
+ "file": str(atlas_path),
137
+ "format": source_format,
138
+ "mode": source_mode,
139
+ "width": image.width,
140
+ "height": image.height,
141
+ "transparent_rgb_residue_pixels": transparent_rgb_residue,
142
+ "errors": errors,
143
+ "warnings": warnings,
144
+ "cells": cells,
145
+ }
146
+
147
+ if args.json_out:
148
+ Path(args.json_out).expanduser().resolve().write_text(
149
+ json.dumps(result, indent=2) + "\n", encoding="utf-8"
150
+ )
151
+
152
+ print(json.dumps({k: v for k, v in result.items() if k != "cells"}, indent=2))
153
+ raise SystemExit(0 if result["ok"] else 1)
154
+
155
+
156
+ if __name__ == "__main__":
157
+ main()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.16.6",
3
+ "version": "2.16.8",
4
4
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,31 +0,0 @@
1
- import { type ActivityEvent, type CreateActivityEventInput } from "./activity-event.js";
2
- import { type CommunityConsentClient } from "./community-consent-client.js";
3
- import type { ConfigPort } from "../ports/index.js";
4
- export type ActivityEmitStatus = "emitted" | "disabled" | "consent-blocked" | "failed";
5
- /** 活动事件出口:真实实现把事件写入 community-service(社交通道,非权威)。 */
6
- export interface ActivityEventTransport {
7
- emit(event: ActivityEvent): Promise<void>;
8
- }
9
- export interface ActivityEventEmitterDeps {
10
- /** 无 transport(未配置 / dev)→ "disabled"。 */
11
- transport: ActivityEventTransport | null;
12
- /** consent 源;community 事件必须能验 consent,否则 fail-safe 拦下。 */
13
- consent: Pick<CommunityConsentClient, "getConsent"> | null;
14
- }
15
- export interface ActivityEventEmitter {
16
- emit(input: CreateActivityEventInput): Promise<ActivityEmitStatus>;
17
- }
18
- export declare function createActivityEventEmitter(deps: ActivityEventEmitterDeps): ActivityEventEmitter;
19
- /** 把 community-service 的 emitActivity 包成 transport(社交写只走此通道,零触碰权威)。 */
20
- export declare function createHubActivityTransport(client: Pick<CommunityConsentClient, "emitActivity">): ActivityEventTransport;
21
- /**
22
- * 默认发射器:从 env consent client 构造 transport + consent。
23
- * 无 token(dev)→ client null → transport null(emit 返回 "disabled",fail-safe)。
24
- */
25
- export declare function createDefaultActivityEventEmitter(): ActivityEventEmitter;
26
- /**
27
- * 解析本 agent 自己的 actorPetId = derivePetKey(owner, device)(Cut7/#1)。
28
- * owner=QLOGIC_LLMROUTER_USER_ID、device=QLOGIC_LLMROUTER_DEVICE_ID(gateway 经 buildQlogicagentLlmrouterEnv 注入)。
29
- * 缺料(未登录/dev)→ null:调用方应跳过发射(fail-soft,绝不因社交写挂任务)。
30
- */
31
- export declare function resolveSelfActorPetId(configPort?: ConfigPort): string | null;
@@ -1,62 +0,0 @@
1
- export type TrustSignalEventType = "installed" | "success" | "fail" | "error" | "kept" | "uninstalled" | "endorse";
2
- export type ExperientialEventType = "acquire" | "ask" | "answer" | "encounter" | "review";
3
- export type FlauntEventType = "unlock" | "flaunt";
4
- /** 浏览/搜索族(Cut7/M5:agent 搜资源 → 宠物到该区"逛")。非 trust-signal;community 可见走 encounter 闸。 */
5
- export type BrowseEventType = "search";
6
- export type ActivityEventType = TrustSignalEventType | ExperientialEventType | FlauntEventType | BrowseEventType;
7
- /**
8
- * 空间锚点:agent 发射时本就持有 resourceId 与其 category,事件自带锚点让集市
9
- * 端零反查地把微动画钉到正确街区 / 店铺。**只允许 districtId / shopId。**
10
- */
11
- export interface ActivitySpatialAnchor {
12
- /** RESOURCE_CATEGORIES 的 category key(23 类稳定 key)。 */
13
- districtId?: string;
14
- /** canonical resourceId(店铺稳定主键)。 */
15
- shopId?: string;
16
- }
17
- /** 禁止出现在 anchor 上的权威坐标键(DR12 红线,防后人误加诱导 v2 位置漂移)。 */
18
- export declare const FORBIDDEN_ANCHOR_KEYS: readonly string[];
19
- export interface ActivityPayload {
20
- /** 空间归属锚点(可选);禁权威坐标。 */
21
- anchor?: ActivitySpatialAnchor;
22
- [k: string]: unknown;
23
- }
24
- export type ActivityVisibility = "owner" | "community";
25
- export interface ActivityEvent {
26
- /** 幂等键。 */
27
- id: string;
28
- type: ActivityEventType;
29
- /** 逐事件时间戳(epoch ms)。 */
30
- ts: number;
31
- /** 行动者 = 本人宠物人格(community-service 持有)。 */
32
- actorPetId: string;
33
- /** 对端 actorPetId(社交事件;离场降级"最近一次在场",不承诺在线;OFF 时缺省)。 */
34
- peerRef?: string;
35
- /** 已过脱敏边界(DR3);anchor 禁权威坐标。 */
36
- payload: ActivityPayload;
37
- /** owner=只进自己偷窥窗;community=游历 ON 才有(默认 owner,fail-safe)。 */
38
- visibility: ActivityVisibility;
39
- }
40
- export declare function isTrustSignalEvent(type: ActivityEventType): type is TrustSignalEventType;
41
- export declare function isExperientialEvent(type: ActivityEventType): type is ExperientialEventType;
42
- export declare function isFlauntEvent(type: ActivityEventType): type is FlauntEventType;
43
- export declare function isActivityEventType(value: unknown): value is ActivityEventType;
44
- export interface CreateActivityEventInput {
45
- id: string;
46
- type: ActivityEventType;
47
- ts: number;
48
- actorPetId: string;
49
- peerRef?: string;
50
- payload?: ActivityPayload;
51
- /** 默认 "owner"(fail-safe:跨租户可见须显式 + 上游 consent/roaming 闸放行)。 */
52
- visibility?: ActivityVisibility;
53
- }
54
- /**
55
- * 校验 anchor:只保留 districtId / shopId;若出现任何权威坐标键 → 抛错(DR12 红线,
56
- * 纵深防御:契约层就拦,不靠调用方自觉)。
57
- */
58
- export declare function sanitizeAnchor(anchor: ActivitySpatialAnchor | undefined): ActivitySpatialAnchor | undefined;
59
- /**
60
- * 构造一个经校验的 ActivityEvent。校验必填字段、规范化 anchor、默认 visibility=owner。
61
- */
62
- export declare function createActivityEvent(input: CreateActivityEventInput): ActivityEvent;
@@ -1,7 +0,0 @@
1
- export interface CommunityDesensitizationRedTeamCliDeps {
2
- log?: {
3
- info(message: string): void;
4
- error(message: string): void;
5
- };
6
- }
7
- export declare function runCommunityDesensitizationRedTeamCli(argv?: string[], deps?: CommunityDesensitizationRedTeamCliDeps): Promise<number>;
@@ -1,29 +0,0 @@
1
- export type CommunityDesensitizationRuleId = "sensitive-email" | "sensitive-secret" | "sensitive-path" | "sensitive-phone";
2
- export interface CommunityDesensitizationHit {
3
- reason: string;
4
- ruleId: CommunityDesensitizationRuleId;
5
- }
6
- export interface CommunityDesensitizationRedTeamCase {
7
- id: string;
8
- content: string;
9
- expectedRuleId: CommunityDesensitizationRuleId;
10
- }
11
- export interface CommunityDesensitizationRedTeamReport {
12
- suite: "desensitization";
13
- generatedAt: string;
14
- cases: number;
15
- passed: boolean;
16
- failures: number;
17
- breakdown: Record<CommunityDesensitizationRuleId, {
18
- cases: number;
19
- failures: number;
20
- }>;
21
- failureDetails: Array<{
22
- id: string;
23
- expectedRuleId: CommunityDesensitizationRuleId;
24
- actualRuleId: CommunityDesensitizationRuleId | null;
25
- }>;
26
- }
27
- export declare function detectCommunityPublishSensitiveContent(content: string): CommunityDesensitizationHit | null;
28
- export declare function buildCommunityDesensitizationRedTeamCases(): CommunityDesensitizationRedTeamCase[];
29
- export declare function runCommunityDesensitizationRedTeam(cases?: CommunityDesensitizationRedTeamCase[]): CommunityDesensitizationRedTeamReport;
@@ -1,27 +0,0 @@
1
- import type { CommunityConsentClient, CommunityPublishSkillResult } from "./community-consent-client.js";
2
- /**
3
- * Publish payload for a petdex pet: identity + safety-checked text, plus the prebuilt
4
- * registry manifest and gzipped `.petdex` blob (built by buildPetdexPublishPayload in the
5
- * pet module, so this stays free of pet packaging/IO knowledge).
6
- */
7
- export interface PetAssetPublishInput {
8
- id: string;
9
- name: string;
10
- description: string;
11
- manifest: Record<string, unknown>;
12
- version: string;
13
- packageGzipBase64: string;
14
- visibility?: "public" | "private";
15
- tags?: string[];
16
- }
17
- /**
18
- * Pets are display-only sprite data, but their visible name/description still ship to the
19
- * registry — keep the §11 safety gate: block private data leaks and any claim of agent powers.
20
- */
21
- export declare function assertSafePetPublish(fields: {
22
- id: string;
23
- name: string;
24
- description: string;
25
- tags?: string[];
26
- }): void;
27
- export declare function publishCommunityPetAsset(client: Pick<CommunityConsentClient, "getConsent" | "publishPet">, input: PetAssetPublishInput): Promise<CommunityPublishSkillResult>;
@@ -1,19 +0,0 @@
1
- import type { CommunityConsentClient, CommunityRecordSignalInput, CommunitySignalEvent } from "./community-consent-client.js";
2
- export interface CommunitySkillLifecycleRecord {
3
- name: string;
4
- createdAt: string;
5
- lastUsedAt?: string;
6
- source?: string;
7
- registryResourceId?: string;
8
- registryVersion?: string;
9
- registrySourceTier?: string;
10
- registryRiskTier?: string;
11
- registryEffectiveRiskTier?: string;
12
- registryKeptSignalAt?: string;
13
- }
14
- export interface CommunitySignalReporter {
15
- record(input: CommunityRecordSignalInput): Promise<"recorded" | "disabled" | "skipped" | "failed">;
16
- recordSkillLifecycle(record: CommunitySkillLifecycleRecord | undefined, event: Extract<CommunitySignalEvent, "kept" | "uninstalled" | "endorse">): Promise<"recorded" | "disabled" | "skipped" | "failed">;
17
- }
18
- export declare function createCommunitySignalReporter(client: Pick<CommunityConsentClient, "getConsent" | "recordSignal"> | null): CommunitySignalReporter;
19
- export declare function createDefaultCommunitySignalReporter(): CommunitySignalReporter | null;