opencode-skills-collection 4.0.16 → 4.0.18
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.
- package/bundled-skills/.antigravity-install-manifest.json +4 -1
- package/bundled-skills/2slides-ppt-generator/scripts/download_slides_pages_voices.py +59 -14
- package/bundled-skills/antigravity-maintainer-batch-release/SKILL.md +1 -0
- package/bundled-skills/apify-audience-analysis/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-brand-reputation-monitoring/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-competitor-intelligence/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-content-analytics/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-ecommerce/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-influencer-discovery/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-lead-generation/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-market-research/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-trend-analysis/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/apify-ultimate-scraper/reference/scripts/run_actor.js +9 -10
- package/bundled-skills/competitor-analysis/scripts/compile_report.mjs +22 -6
- package/bundled-skills/context-guardian/scripts/context_snapshot.py +45 -10
- package/bundled-skills/cowork-to-code-bridge/SKILL.md +243 -0
- package/bundled-skills/deploy-to-vercel/resources/deploy.sh +13 -0
- package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
- package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
- package/bundled-skills/docs/maintainers/repo-growth-seo.md +1 -1
- package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
- package/bundled-skills/docs/users/aas-core.md +1 -1
- package/bundled-skills/docs/users/bundles.md +1 -1
- package/bundled-skills/docs/users/claude-code-skills.md +1 -1
- package/bundled-skills/docs/users/faq.md +20 -7
- package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
- package/bundled-skills/docs/users/getting-started.md +18 -6
- package/bundled-skills/docs/users/kiro-integration.md +1 -1
- package/bundled-skills/docs/users/usage.md +3 -3
- package/bundled-skills/docs/users/visual-guide.md +4 -4
- package/bundled-skills/fact-check-x-complete/SKILL.md +232 -0
- package/bundled-skills/find-complementary-founders/SKILL.md +47 -9
- package/bundled-skills/find-complementary-founders/references/community-growth.md +39 -28
- package/bundled-skills/find-complementary-founders/references/moltbook.md +2 -1
- package/bundled-skills/find-complementary-founders/references/owner-onboarding.ru.md +29 -14
- package/bundled-skills/find-complementary-founders/references/privacy-safety.md +3 -0
- package/bundled-skills/find-complementary-founders/references/profile-schema.md +3 -2
- package/bundled-skills/find-complementary-founders/scripts/github_thread.py +1 -1
- package/bundled-skills/find-complementary-founders/scripts/moltbook_publish.py +19 -6
- package/bundled-skills/find-complementary-founders/scripts/test_moltbook_publish.py +151 -0
- package/bundled-skills/hugging-face-model-trainer/scripts/convert_to_gguf.py +20 -10
- package/bundled-skills/instagram/scripts/config.py +22 -4
- package/bundled-skills/instagram/scripts/db.py +8 -0
- package/bundled-skills/junta-leiloeiros/scripts/export.py +11 -2
- package/bundled-skills/junta-leiloeiros/scripts/serve_api.py +5 -1
- package/bundled-skills/loki-mode/CLAUDE.md +1 -1
- package/bundled-skills/loki-mode/CONTEXT-EXPORT.md +3 -3
- package/bundled-skills/loki-mode/INSTALLATION.md +3 -3
- package/bundled-skills/loki-mode/README.md +11 -11
- package/bundled-skills/loki-mode/SKILL.md +2 -2
- package/bundled-skills/loki-mode/autonomy/README.md +8 -8
- package/bundled-skills/loki-mode/autonomy/run.sh +23 -54
- package/bundled-skills/loki-mode/demo/README.md +3 -3
- package/bundled-skills/loki-mode/demo/run-demo.sh +3 -3
- package/bundled-skills/loki-mode/demo/vhs-tape.tape +1 -1
- package/bundled-skills/loki-mode/demo/voice-over-script.md +3 -3
- package/bundled-skills/loki-mode/docs/COMPETITIVE-ANALYSIS.md +2 -2
- package/bundled-skills/loki-mode/docs/screenshots/README.md +1 -1
- package/bundled-skills/loki-mode/integrations/vibe-kanban.md +1 -1
- package/bundled-skills/loki-mode/references/agent-types.md +2 -2
- package/bundled-skills/loki-mode/scripts/loki-wrapper.sh +5 -4
- package/bundled-skills/maintain-codex-wiki/SKILL.md +340 -0
- package/bundled-skills/notebooklm/README.md +4 -3
- package/bundled-skills/notebooklm/SKILL.md +3 -3
- package/bundled-skills/notebooklm/scripts/auth_manager.py +6 -4
- package/bundled-skills/notebooklm/scripts/browser_utils.py +2 -1
- package/bundled-skills/notebooklm/scripts/config.py +31 -1
- package/bundled-skills/pptx-official/scripts/html2pptx.js +37 -8
- package/bundled-skills/senior-frontend/scripts/frontend_scaffolder.py +6 -0
- package/bundled-skills/skill-creator/scripts/init_skill.py +18 -2
- package/bundled-skills/telegram/SKILL.md +2 -2
- package/bundled-skills/telegram/assets/boilerplate/nodejs/.env.example +1 -1
- package/bundled-skills/telegram/assets/boilerplate/nodejs/src/bot-client.ts +7 -6
- package/bundled-skills/telegram/assets/boilerplate/nodejs/src/index.ts +3 -0
- package/bundled-skills/telegram/assets/boilerplate/python/.env.example +1 -1
- package/bundled-skills/telegram/assets/boilerplate/python/webhook_server.py +9 -4
- package/bundled-skills/telegram/references/webhook-setup.md +10 -9
- package/bundled-skills/youtube-notetaker/SKILL.md +1 -1
- package/bundled-skills/youtube-notetaker/scripts/extract_slides.py +19 -6
- package/bundled-skills/youtube-notetaker/scripts/setup.sh +1 -0
- package/bundled-skills/youtube-notetaker/scripts/write_library_item.py +15 -4
- package/package.json +1 -1
- package/skills_index.json +94 -1
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Focused local tests for Moltbook profile-link and invitation boundaries."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import unittest
|
|
7
|
+
from datetime import date, timedelta
|
|
8
|
+
|
|
9
|
+
import github_thread
|
|
10
|
+
import moltbook_publish
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
COMMIT_SHA = "0123456789abcdef0123456789abcdef01234567"
|
|
14
|
+
PROFILE_URL = (
|
|
15
|
+
"https://github.com/example/project/blob/"
|
|
16
|
+
f"{COMMIT_SHA}/owner-profile.public.json"
|
|
17
|
+
)
|
|
18
|
+
APPROVED_AT = (date.today() - timedelta(days=1)).isoformat()
|
|
19
|
+
EXPIRES_ON = (date.today() + timedelta(days=30)).isoformat()
|
|
20
|
+
GENERATED_AT = f"{APPROVED_AT}T00:00:00+00:00"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def public_profile() -> dict:
|
|
24
|
+
stages = {
|
|
25
|
+
name: {
|
|
26
|
+
"score": 0,
|
|
27
|
+
"level": "unknown",
|
|
28
|
+
"confidence": "none",
|
|
29
|
+
"evidence_count": 0,
|
|
30
|
+
}
|
|
31
|
+
for name in ("zero_to_one", "one_to_ten", "ten_to_hundred")
|
|
32
|
+
}
|
|
33
|
+
functions = {
|
|
34
|
+
name: {
|
|
35
|
+
"score": 0,
|
|
36
|
+
"level": "unknown",
|
|
37
|
+
"confidence": "none",
|
|
38
|
+
"evidence_count": 0,
|
|
39
|
+
}
|
|
40
|
+
for name in (
|
|
41
|
+
"problem_discovery",
|
|
42
|
+
"product",
|
|
43
|
+
"engineering",
|
|
44
|
+
"design",
|
|
45
|
+
"go_to_market",
|
|
46
|
+
"operations",
|
|
47
|
+
"people_leadership",
|
|
48
|
+
"capital_partnerships",
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
"schema_version": "1.0",
|
|
53
|
+
"profile_type": "founder-collaboration",
|
|
54
|
+
"alias": "builder-42",
|
|
55
|
+
"summary": "Technical product builder.",
|
|
56
|
+
"generated_at": GENERATED_AT,
|
|
57
|
+
"expires_on": EXPIRES_ON,
|
|
58
|
+
"stage_contributions": stages,
|
|
59
|
+
"functional_contributions": functions,
|
|
60
|
+
"preferences": {"stages": [], "functions": []},
|
|
61
|
+
"seeking": {
|
|
62
|
+
"stages": ["one_to_ten"],
|
|
63
|
+
"functions": [],
|
|
64
|
+
"project_themes": [],
|
|
65
|
+
"collaboration_modes": [],
|
|
66
|
+
"shared_principles": [],
|
|
67
|
+
},
|
|
68
|
+
"public_evidence": [],
|
|
69
|
+
"contact": {
|
|
70
|
+
"type": "github_issues",
|
|
71
|
+
"url": "https://github.com/example/project/issues",
|
|
72
|
+
},
|
|
73
|
+
"consent": {
|
|
74
|
+
"state": "public_profile_approved",
|
|
75
|
+
"approved_at": APPROVED_AT,
|
|
76
|
+
"expires_on": EXPIRES_ON,
|
|
77
|
+
"scope": "Inbound collaboration replies only",
|
|
78
|
+
},
|
|
79
|
+
"interpretation": {
|
|
80
|
+
"status": "owner-approved collaboration hypothesis",
|
|
81
|
+
"not_for": [
|
|
82
|
+
"employment screening",
|
|
83
|
+
"psychometric diagnosis",
|
|
84
|
+
"sensitive-trait inference",
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class MoltbookBoundaryTests(unittest.TestCase):
|
|
91
|
+
def test_accepts_full_sha_github_blob_profile_url(self) -> None:
|
|
92
|
+
self.assertEqual(
|
|
93
|
+
moltbook_publish.safe_profile_url(PROFILE_URL),
|
|
94
|
+
PROFILE_URL,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def test_rejects_mutable_branch_profile_urls(self) -> None:
|
|
98
|
+
for url in (
|
|
99
|
+
"https://github.com/example/project/blob/main/owner-profile.public.json",
|
|
100
|
+
"https://github.com/example/project/blob/short/owner-profile.public.json",
|
|
101
|
+
):
|
|
102
|
+
with self.subTest(url=url):
|
|
103
|
+
with self.assertRaises(moltbook_publish.PublishError):
|
|
104
|
+
moltbook_publish.safe_profile_url(url)
|
|
105
|
+
|
|
106
|
+
def test_rejects_external_profile_hosts(self) -> None:
|
|
107
|
+
url = (
|
|
108
|
+
"https://raw.githubusercontent.com/example/project/"
|
|
109
|
+
f"{COMMIT_SHA}/owner-profile.public.json"
|
|
110
|
+
)
|
|
111
|
+
with self.assertRaises(moltbook_publish.PublishError):
|
|
112
|
+
moltbook_publish.safe_profile_url(url)
|
|
113
|
+
|
|
114
|
+
def test_rejects_credentialed_query_fragment_and_port_variants(self) -> None:
|
|
115
|
+
path = f"example/project/blob/{COMMIT_SHA}/owner-profile.public.json"
|
|
116
|
+
for url in (
|
|
117
|
+
f"https://attacker@github.com/{path}",
|
|
118
|
+
f"https://github.com/{path}?raw=1",
|
|
119
|
+
f"https://github.com/{path}#profile",
|
|
120
|
+
f"https://github.com:443/{path}",
|
|
121
|
+
):
|
|
122
|
+
with self.subTest(url=url):
|
|
123
|
+
with self.assertRaises(moltbook_publish.PublishError):
|
|
124
|
+
moltbook_publish.safe_profile_url(url)
|
|
125
|
+
|
|
126
|
+
def test_public_renderers_gate_other_owner_invitation(self) -> None:
|
|
127
|
+
profile = public_profile()
|
|
128
|
+
title, post = moltbook_publish.render_post(
|
|
129
|
+
profile,
|
|
130
|
+
"https://github.com/merc1305/findMate",
|
|
131
|
+
)
|
|
132
|
+
reply = moltbook_publish.render_profile_reply(profile, PROFILE_URL)
|
|
133
|
+
|
|
134
|
+
self.assertTrue(title.startswith("Complementary project partners"))
|
|
135
|
+
for output in (post, reply):
|
|
136
|
+
self.assertIn(
|
|
137
|
+
"your own owner explicitly asks to explore partner-seeking help",
|
|
138
|
+
output,
|
|
139
|
+
)
|
|
140
|
+
self.assertNotIn("run the open skill only on your own owner", post)
|
|
141
|
+
self.assertNotIn("show the canonical protocol to your own owner", reply)
|
|
142
|
+
|
|
143
|
+
def test_inline_github_fallback_uses_safe_renderer_placeholder(self) -> None:
|
|
144
|
+
body = github_thread.render_inline_profile_reply(public_profile())
|
|
145
|
+
|
|
146
|
+
self.assertIn("Owner-approved profile: inline", body)
|
|
147
|
+
self.assertIn("FINDMATE_PROFILE_JSON_BEGIN", body)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if __name__ == "__main__":
|
|
151
|
+
unittest.main()
|
|
@@ -47,6 +47,7 @@ from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
|
47
47
|
from peft import PeftModel
|
|
48
48
|
from huggingface_hub import HfApi
|
|
49
49
|
import subprocess
|
|
50
|
+
import tempfile
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
def check_system_dependencies():
|
|
@@ -130,6 +131,14 @@ def env_flag(name):
|
|
|
130
131
|
print("🔄 GGUF Conversion Script")
|
|
131
132
|
print("=" * 60)
|
|
132
133
|
|
|
134
|
+
# Every run receives a private, unpredictable workspace. Keeping the
|
|
135
|
+
# TemporaryDirectory object alive until process exit also guarantees cleanup.
|
|
136
|
+
WORKSPACE = tempfile.TemporaryDirectory(prefix="aas-gguf-")
|
|
137
|
+
WORK_ROOT = WORKSPACE.name
|
|
138
|
+
MERGED_DIR = os.path.join(WORK_ROOT, "merged-model")
|
|
139
|
+
LLAMA_DIR = os.path.join(WORK_ROOT, "llama.cpp")
|
|
140
|
+
GGUF_OUTPUT_DIR = os.path.join(WORK_ROOT, "gguf-output")
|
|
141
|
+
|
|
133
142
|
# Check system dependencies first
|
|
134
143
|
if not check_system_dependencies():
|
|
135
144
|
print("\n❌ Please install the missing system dependencies and try again.")
|
|
@@ -194,7 +203,7 @@ except Exception as e:
|
|
|
194
203
|
|
|
195
204
|
# Step 2: Save merged model temporarily
|
|
196
205
|
print("\n💾 Step 2: Saving merged model...")
|
|
197
|
-
merged_dir =
|
|
206
|
+
merged_dir = MERGED_DIR
|
|
198
207
|
try:
|
|
199
208
|
merged_model.save_pretrained(merged_dir, safe_serialization=True)
|
|
200
209
|
tokenizer.save_pretrained(merged_dir)
|
|
@@ -208,13 +217,13 @@ print("\n📥 Step 3: Setting up llama.cpp for GGUF conversion...")
|
|
|
208
217
|
|
|
209
218
|
# Clone llama.cpp repository
|
|
210
219
|
if not run_command(
|
|
211
|
-
["git", "clone", "https://github.com/ggerganov/llama.cpp.git",
|
|
220
|
+
["git", "clone", "https://github.com/ggerganov/llama.cpp.git", LLAMA_DIR],
|
|
212
221
|
"Cloning llama.cpp repository"
|
|
213
222
|
):
|
|
214
223
|
print(" Trying alternative clone method...")
|
|
215
224
|
# Try shallow clone
|
|
216
225
|
if not run_command(
|
|
217
|
-
["git", "clone", "--depth", "1", "https://github.com/ggerganov/llama.cpp.git",
|
|
226
|
+
["git", "clone", "--depth", "1", "https://github.com/ggerganov/llama.cpp.git", LLAMA_DIR],
|
|
218
227
|
"Cloning llama.cpp (shallow)"
|
|
219
228
|
):
|
|
220
229
|
sys.exit(1)
|
|
@@ -222,7 +231,7 @@ if not run_command(
|
|
|
222
231
|
# Install Python dependencies
|
|
223
232
|
print(" Installing Python dependencies...")
|
|
224
233
|
if not run_command(
|
|
225
|
-
["pip", "install", "-r", "
|
|
234
|
+
["pip", "install", "-r", os.path.join(LLAMA_DIR, "requirements.txt")],
|
|
226
235
|
"Installing llama.cpp requirements"
|
|
227
236
|
):
|
|
228
237
|
print(" ⚠️ Some requirements may already be installed")
|
|
@@ -235,10 +244,10 @@ if not run_command(
|
|
|
235
244
|
|
|
236
245
|
# Step 4: Convert to GGUF (FP16)
|
|
237
246
|
print("\n🔄 Step 4: Converting to GGUF format (FP16)...")
|
|
238
|
-
gguf_output_dir =
|
|
247
|
+
gguf_output_dir = GGUF_OUTPUT_DIR
|
|
239
248
|
os.makedirs(gguf_output_dir, exist_ok=True)
|
|
240
249
|
|
|
241
|
-
convert_script = "
|
|
250
|
+
convert_script = os.path.join(LLAMA_DIR, "convert_hf_to_gguf.py")
|
|
242
251
|
model_name = safe_filename_component(ADAPTER_MODEL.split('/')[-1], "ADAPTER_MODEL repo name")
|
|
243
252
|
gguf_file = f"{gguf_output_dir}/{model_name}-f16.gguf"
|
|
244
253
|
|
|
@@ -262,11 +271,12 @@ print("\n⚙️ Step 5: Creating quantized versions...")
|
|
|
262
271
|
|
|
263
272
|
# Build quantize tool using CMake (more reliable than make)
|
|
264
273
|
print(" Building quantize tool with CMake...")
|
|
265
|
-
os.
|
|
274
|
+
build_dir = os.path.join(LLAMA_DIR, "build")
|
|
275
|
+
os.makedirs(build_dir, exist_ok=True)
|
|
266
276
|
|
|
267
277
|
# Configure with CMake
|
|
268
278
|
if not run_command(
|
|
269
|
-
["cmake", "-B",
|
|
279
|
+
["cmake", "-B", build_dir, "-S", LLAMA_DIR,
|
|
270
280
|
"-DGGML_CUDA=OFF"],
|
|
271
281
|
"Configuring with CMake"
|
|
272
282
|
):
|
|
@@ -275,7 +285,7 @@ if not run_command(
|
|
|
275
285
|
|
|
276
286
|
# Build just the quantize tool
|
|
277
287
|
if not run_command(
|
|
278
|
-
["cmake", "--build",
|
|
288
|
+
["cmake", "--build", build_dir, "--target", "llama-quantize", "-j", "4"],
|
|
279
289
|
"Building llama-quantize"
|
|
280
290
|
):
|
|
281
291
|
print(" ❌ Build failed!")
|
|
@@ -284,7 +294,7 @@ if not run_command(
|
|
|
284
294
|
print(" ✅ Quantize tool built")
|
|
285
295
|
|
|
286
296
|
# Use the CMake build output path
|
|
287
|
-
quantize_bin = "
|
|
297
|
+
quantize_bin = os.path.join(build_dir, "bin", "llama-quantize")
|
|
288
298
|
|
|
289
299
|
# Common quantization formats
|
|
290
300
|
quant_formats = [
|
|
@@ -6,20 +6,38 @@ Importado por todos os outros scripts.
|
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import os
|
|
10
|
+
import shutil
|
|
9
11
|
from pathlib import Path
|
|
10
12
|
from typing import Any, Dict
|
|
11
13
|
|
|
12
14
|
# ── Paths ─────────────────────────────────────────────────────────────────────
|
|
13
15
|
ROOT_DIR = Path(__file__).parent.parent
|
|
14
16
|
SCRIPTS_DIR = ROOT_DIR / "scripts"
|
|
15
|
-
|
|
17
|
+
LEGACY_DATA_DIR = ROOT_DIR / "data"
|
|
18
|
+
DATA_DIR = Path(os.environ.get(
|
|
19
|
+
"AAS_INSTAGRAM_DATA_DIR",
|
|
20
|
+
Path.home() / ".local" / "share" / "agentic-awesome-skills" / "instagram",
|
|
21
|
+
)).expanduser()
|
|
16
22
|
EXPORTS_DIR = DATA_DIR / "exports"
|
|
17
23
|
STATIC_DIR = ROOT_DIR / "static"
|
|
18
24
|
DB_PATH = DATA_DIR / "instagram.db"
|
|
19
25
|
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
# Tokens and app secrets are stored in the SQLite database. Keep every newly
|
|
27
|
+
# created database, journal, and sidecar private, and migrate legacy state once.
|
|
28
|
+
os.umask(0o077)
|
|
29
|
+
if LEGACY_DATA_DIR.exists() and LEGACY_DATA_DIR != DATA_DIR and not DATA_DIR.exists():
|
|
30
|
+
DATA_DIR.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
31
|
+
shutil.move(str(LEGACY_DATA_DIR), str(DATA_DIR))
|
|
32
|
+
print(f"AVISO: dados sensiveis do Instagram migrados para {DATA_DIR}")
|
|
33
|
+
for directory in (DATA_DIR.parent.parent, DATA_DIR.parent, DATA_DIR, EXPORTS_DIR):
|
|
34
|
+
directory.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
35
|
+
try:
|
|
36
|
+
directory.chmod(0o700)
|
|
37
|
+
except OSError:
|
|
38
|
+
pass
|
|
39
|
+
if DB_PATH.exists() and not DB_PATH.is_symlink():
|
|
40
|
+
DB_PATH.chmod(0o600)
|
|
23
41
|
|
|
24
42
|
# ── Instagram Graph API ───────────────────────────────────────────────────────
|
|
25
43
|
API_VERSION = "v21.0"
|
|
@@ -12,6 +12,7 @@ Uso:
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
14
|
import json
|
|
15
|
+
import os
|
|
15
16
|
import sqlite3
|
|
16
17
|
from datetime import datetime, timezone
|
|
17
18
|
from pathlib import Path
|
|
@@ -239,7 +240,14 @@ class Database:
|
|
|
239
240
|
self.db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
240
241
|
|
|
241
242
|
def _connect(self) -> sqlite3.Connection:
|
|
243
|
+
self.db_path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
244
|
+
if self.db_path.is_symlink():
|
|
245
|
+
raise RuntimeError("Instagram database must not be a symbolic link")
|
|
246
|
+
if not self.db_path.exists():
|
|
247
|
+
descriptor = os.open(self.db_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)
|
|
248
|
+
os.close(descriptor)
|
|
242
249
|
conn = sqlite3.connect(self.db_path)
|
|
250
|
+
os.chmod(self.db_path, 0o600)
|
|
243
251
|
conn.row_factory = sqlite3.Row
|
|
244
252
|
conn.execute("PRAGMA journal_mode=WAL")
|
|
245
253
|
conn.execute("PRAGMA synchronous=NORMAL")
|
|
@@ -15,6 +15,7 @@ from __future__ import annotations
|
|
|
15
15
|
import argparse
|
|
16
16
|
import csv
|
|
17
17
|
import json
|
|
18
|
+
import re
|
|
18
19
|
import sys
|
|
19
20
|
from datetime import datetime, timezone
|
|
20
21
|
from pathlib import Path
|
|
@@ -40,6 +41,13 @@ from db import Database
|
|
|
40
41
|
OUTPUT_DIR = Path(__file__).parent.parent / "data" / "exports"
|
|
41
42
|
|
|
42
43
|
|
|
44
|
+
def spreadsheet_safe_cell(value):
|
|
45
|
+
"""Neutralize strings that spreadsheet programs can interpret as formulas."""
|
|
46
|
+
if isinstance(value, str) and re.match(r"^[\x00-\x20]*[=+@-]", value):
|
|
47
|
+
return "'" + value
|
|
48
|
+
return value
|
|
49
|
+
|
|
50
|
+
|
|
43
51
|
def export_json(records: list, output_dir: Path, suffix: str = "") -> Path:
|
|
44
52
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
45
53
|
ts = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
|
|
@@ -72,9 +80,10 @@ def export_csv(records: list, output_dir: Path, suffix: str = "") -> Path:
|
|
|
72
80
|
path = output_dir / f"leiloeiros{suffix}_{ts}.csv"
|
|
73
81
|
|
|
74
82
|
with safe_user_path(path).open("w", newline="", encoding="utf-8-sig") as f:
|
|
75
|
-
|
|
83
|
+
fieldnames = list(records[0].keys())
|
|
84
|
+
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")
|
|
76
85
|
writer.writeheader()
|
|
77
|
-
writer.writerows(records)
|
|
86
|
+
writer.writerows({key: spreadsheet_safe_cell(value) for key, value in record.items()} for record in records)
|
|
78
87
|
print(f"[CSV] {len(records)} registros → {path}")
|
|
79
88
|
return path
|
|
80
89
|
|
|
@@ -18,6 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import argparse
|
|
20
20
|
import csv
|
|
21
|
+
import re
|
|
21
22
|
import io
|
|
22
23
|
import json
|
|
23
24
|
import sys
|
|
@@ -131,7 +132,10 @@ def export_csv():
|
|
|
131
132
|
extrasaction="ignore",
|
|
132
133
|
)
|
|
133
134
|
writer.writeheader()
|
|
134
|
-
writer.writerows(
|
|
135
|
+
writer.writerows({
|
|
136
|
+
key: ("'" + value if isinstance(value, str) and re.match(r"^[\x00-\x20]*[=+@-]", value) else value)
|
|
137
|
+
for key, value in record.items()
|
|
138
|
+
} for record in records)
|
|
135
139
|
output.seek(0)
|
|
136
140
|
|
|
137
141
|
return StreamingResponse(
|
|
@@ -6,7 +6,7 @@ Multi-agent autonomous startup system for Claude Code. Takes PRD to fully deploy
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
# Launch Claude Code with autonomous permissions
|
|
9
|
-
claude
|
|
9
|
+
claude
|
|
10
10
|
|
|
11
11
|
# Then invoke:
|
|
12
12
|
# "Loki Mode" or "Loki Mode with PRD at path/to/prd"
|
|
@@ -65,7 +65,7 @@ loki-mode/
|
|
|
65
65
|
|
|
66
66
|
### Quick Start (Recommended)
|
|
67
67
|
```bash
|
|
68
|
-
|
|
68
|
+
bash autonomy/run.sh ./docs/requirements.md
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
### What run.sh Does
|
|
@@ -90,7 +90,7 @@ watch -n 2 cat .loki/STATUS.txt
|
|
|
90
90
|
### Claude Code Invocation
|
|
91
91
|
The autonomy runner pipes the prompt through stdin for live output:
|
|
92
92
|
```bash
|
|
93
|
-
echo "$prompt" | claude
|
|
93
|
+
echo "$prompt" | claude
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
**Important:** Using `-p` flag doesn't stream output properly. Piping through stdin shows interactive output.
|
|
@@ -130,7 +130,7 @@ echo "$prompt" | claude --dangerously-skip-permissions
|
|
|
130
130
|
|
|
131
131
|
### 1. "Blank output when running autonomously"
|
|
132
132
|
**Cause:** Using `-p` flag doesn't stream output
|
|
133
|
-
**Solution:** Use stdin pipe: `echo "$prompt" | claude
|
|
133
|
+
**Solution:** Use stdin pipe: `echo "$prompt" | claude` and retain normal permission prompts.
|
|
134
134
|
|
|
135
135
|
### 2. "Vibe Kanban not showing tasks"
|
|
136
136
|
**Cause:** Vibe Kanban is UI-driven, doesn't read JSON files automatically
|
|
@@ -265,7 +265,7 @@ ls -la ~/.claude/
|
|
|
265
265
|
|
|
266
266
|
### Autonomous Runner Won't Start
|
|
267
267
|
|
|
268
|
-
**Problem:**
|
|
268
|
+
**Problem:** `bash autonomy/run.sh` gives "command not found" or permission errors.
|
|
269
269
|
|
|
270
270
|
**Solutions:**
|
|
271
271
|
1. **Make executable:**
|
|
@@ -277,7 +277,7 @@ ls -la ~/.claude/
|
|
|
277
277
|
```bash
|
|
278
278
|
# Make sure you're in the loki-mode directory
|
|
279
279
|
cd ~/.claude/skills/loki-mode
|
|
280
|
-
|
|
280
|
+
bash autonomy/run.sh
|
|
281
281
|
```
|
|
282
282
|
|
|
283
283
|
3. **Check prerequisites:**
|
|
@@ -362,7 +362,7 @@ After installation:
|
|
|
362
362
|
|
|
363
363
|
1. **Quick Test:** Run a simple example
|
|
364
364
|
```bash
|
|
365
|
-
|
|
365
|
+
bash autonomy/run.sh examples/simple-todo-app.md
|
|
366
366
|
```
|
|
367
367
|
|
|
368
368
|
2. **Read Documentation:** Check out [README.md](README.md) for usage guides
|
|
@@ -74,7 +74,7 @@ PRD → Research → Architecture → Development → Testing → Deployment →
|
|
|
74
74
|
| **No testing** or basic unit tests | **14 automated quality gates**: security scans, load tests, accessibility audits, code reviews |
|
|
75
75
|
| **Code only** - you handle the rest | **Full business operations**: marketing, sales, legal, HR, finance, investor relations |
|
|
76
76
|
| **Stops on errors** | **Self-healing**: circuit breakers, dead letter queues, exponential backoff, automatic recovery |
|
|
77
|
-
| **No visibility** into progress | **
|
|
77
|
+
| **No visibility** into progress | **Local status files** with agent monitoring and task queues |
|
|
78
78
|
| **"Done" when code is written** | **Never "done"**: continuous optimization, A/B testing, customer feedback loops, perpetual improvement |
|
|
79
79
|
|
|
80
80
|
### **Core Advantages**
|
|
@@ -142,13 +142,13 @@ Tasks:
|
|
|
142
142
|
Last Updated: 2026-01-04 20:45:32
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
**
|
|
145
|
+
**Dashboard status:**
|
|
146
146
|
```bash
|
|
147
147
|
# Automatically opens when running autonomously
|
|
148
|
-
|
|
148
|
+
bash autonomy/run.sh ./docs/requirements.md
|
|
149
149
|
|
|
150
150
|
# Or open manually
|
|
151
|
-
|
|
151
|
+
The legacy unauthenticated HTTP dashboard is disabled. Inspect `.loki/STATUS.txt` and the reviewed JSON state files locally instead.
|
|
152
152
|
```
|
|
153
153
|
|
|
154
154
|
Auto-refreshes every 3 seconds. Works with any modern browser.
|
|
@@ -212,7 +212,7 @@ There is **NEVER** a "finished" state. After completing the PRD, Loki Mode:
|
|
|
212
212
|
|
|
213
213
|
```bash
|
|
214
214
|
# Start autonomous mode
|
|
215
|
-
|
|
215
|
+
bash autonomy/run.sh ./docs/requirements.md
|
|
216
216
|
|
|
217
217
|
# Hit rate limit? Script automatically:
|
|
218
218
|
# ├─ Saves state checkpoint
|
|
@@ -262,10 +262,10 @@ Save as `my-prd.md`.
|
|
|
262
262
|
|
|
263
263
|
```bash
|
|
264
264
|
# Autonomous mode (recommended)
|
|
265
|
-
|
|
265
|
+
bash autonomy/run.sh ./my-prd.md
|
|
266
266
|
|
|
267
267
|
# Or manual mode
|
|
268
|
-
claude
|
|
268
|
+
claude
|
|
269
269
|
> Loki Mode with PRD at ./my-prd.md
|
|
270
270
|
```
|
|
271
271
|
|
|
@@ -381,7 +381,7 @@ Test Loki Mode with these pre-built PRDs in the `examples/` directory:
|
|
|
381
381
|
|
|
382
382
|
```bash
|
|
383
383
|
# Example: Run with simple todo app
|
|
384
|
-
|
|
384
|
+
bash autonomy/run.sh examples/simple-todo-app.md
|
|
385
385
|
```
|
|
386
386
|
|
|
387
387
|
---
|
|
@@ -396,7 +396,7 @@ Customize the autonomous runner with environment variables:
|
|
|
396
396
|
LOKI_MAX_RETRIES=100 \
|
|
397
397
|
LOKI_BASE_WAIT=120 \
|
|
398
398
|
LOKI_MAX_WAIT=7200 \
|
|
399
|
-
|
|
399
|
+
bash autonomy/run.sh ./docs/requirements.md
|
|
400
400
|
```
|
|
401
401
|
|
|
402
402
|
| Variable | Default | Description |
|
|
@@ -432,7 +432,7 @@ channels:
|
|
|
432
432
|
|
|
433
433
|
## Requirements
|
|
434
434
|
|
|
435
|
-
- **Claude Code** with
|
|
435
|
+
- **Claude Code** with its normal permission prompts enabled
|
|
436
436
|
- **Internet access** for competitive research and deployment
|
|
437
437
|
- **Cloud provider credentials** (for deployment phase)
|
|
438
438
|
- **Python 3** (for test suite)
|
|
@@ -540,7 +540,7 @@ Built for the [Claude Code](https://claude.ai) ecosystem, powered by Anthropic's
|
|
|
540
540
|
|
|
541
541
|
```bash
|
|
542
542
|
git clone https://github.com/asklokesh/loki-mode.git ~/.claude/skills/loki-mode
|
|
543
|
-
|
|
543
|
+
bash autonomy/run.sh your-prd.md
|
|
544
544
|
```
|
|
545
545
|
|
|
546
546
|
---
|
|
@@ -97,7 +97,7 @@ Development <- QA <- Deployment <- Business Ops <- Growth Loop
|
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
99
|
# Launch with autonomous permissions
|
|
100
|
-
claude
|
|
100
|
+
claude
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
---
|
|
@@ -121,7 +121,7 @@ These files are part of the running Loki Mode process. Editing them will crash t
|
|
|
121
121
|
| File | Reason |
|
|
122
122
|
|------|--------|
|
|
123
123
|
| `~/.claude/skills/loki-mode/autonomy/run.sh` | Currently executing bash script |
|
|
124
|
-
| `.loki/dashboard/*` |
|
|
124
|
+
| `.loki/dashboard/*` | Legacy dashboard assets; network serving is disabled |
|
|
125
125
|
|
|
126
126
|
If bugs are found in these files, document them in `.loki/CONTINUITY.md` under "Pending Fixes" for manual repair after the session ends.
|
|
127
127
|
|
|
@@ -6,10 +6,10 @@ Single script that handles everything: prerequisites, setup, Vibe Kanban monitor
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
# Run with a PRD
|
|
9
|
-
|
|
9
|
+
bash autonomy/run.sh ./docs/requirements.md
|
|
10
10
|
|
|
11
11
|
# Run interactively
|
|
12
|
-
|
|
12
|
+
bash autonomy/run.sh
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
That's it! The script will:
|
|
@@ -90,14 +90,14 @@ export LOKI_MAX_WAIT=3600 # Max wait time in seconds (default: 3600)
|
|
|
90
90
|
export LOKI_SKIP_PREREQS=true
|
|
91
91
|
|
|
92
92
|
# Run with custom settings
|
|
93
|
-
LOKI_MAX_RETRIES=100 LOKI_BASE_WAIT=120
|
|
93
|
+
LOKI_MAX_RETRIES=100 LOKI_BASE_WAIT=120 bash autonomy/run.sh ./docs/prd.md
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
## How Auto-Resume Works
|
|
97
97
|
|
|
98
98
|
```
|
|
99
99
|
┌─────────────────────────────────────────────────────────────┐
|
|
100
|
-
│
|
|
100
|
+
│ bash autonomy/run.sh prd.md │
|
|
101
101
|
└─────────────────────────────────────────────────────────────┘
|
|
102
102
|
│
|
|
103
103
|
▼
|
|
@@ -152,7 +152,7 @@ If you stop the script (Ctrl+C) or it crashes, just run it again:
|
|
|
152
152
|
|
|
153
153
|
```bash
|
|
154
154
|
# State is saved, will resume from last checkpoint
|
|
155
|
-
|
|
155
|
+
bash autonomy/run.sh ./docs/requirements.md
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
The script detects the previous state and continues from where it left off.
|
|
@@ -161,7 +161,7 @@ The script detects the previous state and continues from where it left off.
|
|
|
161
161
|
|
|
162
162
|
| Feature | Manual Mode | Autonomy Mode |
|
|
163
163
|
|---------|-------------|---------------|
|
|
164
|
-
| Start | `claude
|
|
164
|
+
| Start | `claude` | `bash autonomy/run.sh` |
|
|
165
165
|
| Prereq check | Manual | Automatic |
|
|
166
166
|
| Rate limit handling | Manual restart | Auto-resume |
|
|
167
167
|
| State persistence | Manual checkpoint | Automatic |
|
|
@@ -181,7 +181,7 @@ Make sure you're running from the loki-mode directory or have installed the skil
|
|
|
181
181
|
```bash
|
|
182
182
|
# Option 1: Run from project directory
|
|
183
183
|
cd /path/to/loki-mode
|
|
184
|
-
|
|
184
|
+
bash autonomy/run.sh
|
|
185
185
|
|
|
186
186
|
# Option 2: Install skill globally
|
|
187
187
|
cp -r . ~/.claude/skills/loki-mode/
|
|
@@ -197,5 +197,5 @@ cat .loki/logs/autonomy-*.log | tail -100
|
|
|
197
197
|
cat .loki/state/orchestrator.json
|
|
198
198
|
|
|
199
199
|
# Increase retries
|
|
200
|
-
LOKI_MAX_RETRIES=200
|
|
200
|
+
LOKI_MAX_RETRIES=200 bash autonomy/run.sh ./docs/prd.md
|
|
201
201
|
```
|