@smilintux/skcapstone 0.10.0 → 0.12.5
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/.env.example +10 -4
- package/.github/workflows/ci.yml +2 -2
- package/.github/workflows/publish.yml +9 -2
- package/.openclaw-workspace.json +2 -2
- package/CLAUDE.md +37 -0
- package/MISSION.md +17 -2
- package/README.md +282 -3
- package/docker/Dockerfile +7 -7
- package/docker/compose-templates/dev-team.yml +12 -12
- package/docker/compose-templates/mini-team.yml +9 -9
- package/docker/compose-templates/ops-team.yml +10 -10
- package/docker/compose-templates/research-team.yml +10 -10
- package/docker/entrypoint.sh +4 -4
- package/docs/ADR-optional-integration-backbone.md +181 -0
- package/docs/ARCHITECTURE.md +186 -43
- package/docs/BOND_WITH_GROK.md +6 -6
- package/docs/CUSTOM_AGENT.md +123 -30
- package/docs/DREAMING.md +70 -0
- package/docs/GETTING_STARTED.md +7 -7
- package/docs/QUICKSTART.md +10 -6
- package/docs/SKJOULE_ARCHITECTURE.md +3 -3
- package/docs/SOUL_SWAPPER.md +5 -5
- package/docs/hammertime-audit.md +402 -0
- package/docs/sk-integration-HANDOFF.md +117 -0
- package/docs/skscheduler.md +155 -0
- package/docs/superpowers/examples/jobs.yaml +31 -0
- package/docs/superpowers/plans/2026-06-08-skscheduler.md +1265 -0
- package/docs/superpowers/specs/2026-06-08-skscheduler-design.md +186 -0
- package/examples/custom-bond-template.json +1 -1
- package/examples/grok-feb.json +1 -1
- package/examples/queen-ava-feb.json +1 -1
- package/launchd/{com.skcapstone.skcomm-heartbeat.plist → com.skcapstone.skcomms-heartbeat.plist} +4 -4
- package/launchd/{com.skcapstone.skcomm-queue-drain.plist → com.skcapstone.skcomms-queue-drain.plist} +4 -4
- package/launchd/install-launchd.sh +6 -6
- package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/index.ts +3 -2
- package/package.json +1 -1
- package/pyproject.toml +16 -10
- package/scripts/archive-sessions.sh +7 -0
- package/scripts/check-updates.py +4 -4
- package/scripts/install-bundle.sh +8 -8
- package/scripts/install.ps1 +12 -11
- package/scripts/install.sh +159 -5
- package/scripts/model-fallback-monitor.sh +102 -0
- package/scripts/nvidia-proxy.mjs +78 -26
- package/scripts/refresh-anthropic-token.sh +172 -0
- package/scripts/release.sh +98 -0
- package/scripts/session-to-memory.py +219 -0
- package/scripts/skgateway.mjs +3 -3
- package/scripts/telegram-catchup-all.sh +12 -1
- package/scripts/verify_install.sh +2 -2
- package/scripts/wargov-ufo-capture/README.md +43 -0
- package/scripts/wargov-ufo-capture/cdp_capture_release2.py +273 -0
- package/scripts/wargov-ufo-capture/cdp_capture_splc_doj.py +246 -0
- package/scripts/wargov-ufo-capture/cdp_finish.py +271 -0
- package/scripts/wargov-ufo-capture/cdp_probe.py +188 -0
- package/scripts/wargov-ufo-capture/cdp_splc_pressrelease.py +101 -0
- package/scripts/wargov-ufo-capture/parse_csv.py +95 -0
- package/scripts/wargov-ufo-capture/pull_dvids.sh +107 -0
- package/scripts/watch-anthropic-token.sh +212 -0
- package/scripts/windows/install-tasks.ps1 +7 -7
- package/scripts/windows/skcapstone-task.xml +1 -1
- package/src/skcapstone/__init__.py +45 -3
- package/src/skcapstone/_cli_monolith.py +20 -15
- package/src/skcapstone/activity.py +5 -1
- package/src/skcapstone/agent_card.py +3 -2
- package/src/skcapstone/api.py +41 -40
- package/src/skcapstone/auction.py +14 -11
- package/src/skcapstone/backup.py +2 -1
- package/src/skcapstone/blueprint_registry.py +4 -3
- package/src/skcapstone/brain_first.py +238 -0
- package/src/skcapstone/changelog.py +1 -1
- package/src/skcapstone/chat.py +22 -17
- package/src/skcapstone/cli/__init__.py +9 -1
- package/src/skcapstone/cli/_common.py +1 -0
- package/src/skcapstone/cli/agents_spawner.py +5 -2
- package/src/skcapstone/cli/alerts.py +25 -4
- package/src/skcapstone/cli/bench.py +15 -15
- package/src/skcapstone/cli/chat.py +7 -4
- package/src/skcapstone/cli/consciousness.py +5 -2
- package/src/skcapstone/cli/context_cmd.py +18 -4
- package/src/skcapstone/cli/daemon.py +11 -7
- package/src/skcapstone/cli/gtd.py +26 -1
- package/src/skcapstone/cli/housekeeping.py +3 -3
- package/src/skcapstone/cli/identity_cmd.py +378 -0
- package/src/skcapstone/cli/joule_cmd.py +7 -3
- package/src/skcapstone/cli/memory.py +8 -6
- package/src/skcapstone/cli/peers_dir.py +1 -1
- package/src/skcapstone/cli/register_cmd.py +29 -3
- package/src/skcapstone/cli/scheduler_cmd.py +167 -0
- package/src/skcapstone/cli/session.py +25 -0
- package/src/skcapstone/cli/setup.py +96 -29
- package/src/skcapstone/cli/shell_cmd.py +53 -1
- package/src/skcapstone/cli/skills_cmd.py +2 -2
- package/src/skcapstone/cli/soul.py +8 -5
- package/src/skcapstone/cli/status.py +37 -11
- package/src/skcapstone/cli/telegram.py +21 -0
- package/src/skcapstone/cli/test_cmd.py +5 -5
- package/src/skcapstone/cli/test_connection.py +2 -2
- package/src/skcapstone/cli/upgrade_cmd.py +23 -14
- package/src/skcapstone/cli/version_cmd.py +1 -1
- package/src/skcapstone/cli/watch_cmd.py +9 -6
- package/src/skcapstone/cloud9_bridge.py +14 -14
- package/src/skcapstone/codex_setup.py +255 -0
- package/src/skcapstone/config_validator.py +7 -4
- package/src/skcapstone/consciousness_config.py +5 -1
- package/src/skcapstone/consciousness_loop.py +313 -273
- package/src/skcapstone/context_loader.py +121 -0
- package/src/skcapstone/coord_federation.py +2 -1
- package/src/skcapstone/coordination.py +23 -6
- package/src/skcapstone/crush_integration.py +2 -1
- package/src/skcapstone/daemon.py +132 -77
- package/src/skcapstone/dashboard.py +10 -10
- package/src/skcapstone/data/sk-agent-picker.sh +421 -0
- package/src/skcapstone/data/systemd/skcapstone-api.socket +9 -0
- package/src/skcapstone/data/systemd/skcapstone-memory-compress.service +18 -0
- package/src/skcapstone/data/systemd/skcapstone-memory-compress.timer +11 -0
- package/src/skcapstone/data/systemd/skcapstone.service +37 -0
- package/src/skcapstone/data/systemd/skcapstone@.service +50 -0
- package/src/skcapstone/data/systemd/skcomms-heartbeat.service +18 -0
- package/{systemd/skcomm-heartbeat.timer → src/skcapstone/data/systemd/skcomms-heartbeat.timer} +2 -2
- package/src/skcapstone/data/systemd/skcomms-queue-drain.service +17 -0
- package/{systemd/skcomm-queue-drain.timer → src/skcapstone/data/systemd/skcomms-queue-drain.timer} +2 -2
- package/src/skcapstone/defaults/claude/CLAUDE.md +67 -0
- package/src/skcapstone/defaults/claude/settings.json +74 -0
- package/src/skcapstone/defaults/lumina/config/claude-hooks.md +57 -0
- package/src/skcapstone/defaults/lumina/config/skgraph.yaml +55 -10
- package/src/skcapstone/defaults/lumina/config/skmemory.yaml +79 -13
- package/src/skcapstone/defaults/lumina/config/skvector.yaml +60 -9
- package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +2 -2
- package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +2 -2
- package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +9 -9
- package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +2 -2
- package/src/skcapstone/defaults/unhinged.json +13 -0
- package/src/skcapstone/discovery.py +43 -20
- package/src/skcapstone/doctor.py +941 -22
- package/src/skcapstone/dreaming.py +1183 -109
- package/src/skcapstone/emotion_tracker.py +2 -2
- package/src/skcapstone/export.py +4 -3
- package/src/skcapstone/fuse_mount.py +14 -12
- package/src/skcapstone/gui_installer.py +2 -2
- package/src/skcapstone/heartbeat.py +1 -1
- package/src/skcapstone/housekeeping.py +14 -14
- package/src/skcapstone/install_wizard.py +209 -7
- package/src/skcapstone/itil.py +13 -4
- package/src/skcapstone/kms_scheduler.py +10 -8
- package/src/skcapstone/launchd.py +19 -19
- package/src/skcapstone/mcp_launcher.py +15 -1
- package/src/skcapstone/mcp_server.py +83 -49
- package/src/skcapstone/mcp_tools/__init__.py +2 -0
- package/src/skcapstone/mcp_tools/_helpers.py +2 -2
- package/src/skcapstone/mcp_tools/ansible_tools.py +7 -4
- package/src/skcapstone/mcp_tools/brain_first_tools.py +90 -0
- package/src/skcapstone/mcp_tools/capauth_tools.py +7 -4
- package/src/skcapstone/mcp_tools/comm_tools.py +10 -10
- package/src/skcapstone/mcp_tools/coord_tools.py +8 -4
- package/src/skcapstone/mcp_tools/did_tools.py +11 -8
- package/src/skcapstone/mcp_tools/gtd_tools.py +4 -4
- package/src/skcapstone/mcp_tools/memory_tools.py +6 -2
- package/src/skcapstone/mcp_tools/notification_tools.py +22 -6
- package/src/skcapstone/mcp_tools/{skcomm_tools.py → skcomms_tools.py} +14 -14
- package/src/skcapstone/mcp_tools/soul_tools.py +8 -2
- package/src/skcapstone/mdns_discovery.py +2 -2
- package/src/skcapstone/memory_curator.py +1 -1
- package/src/skcapstone/memory_engine.py +10 -3
- package/src/skcapstone/metrics.py +30 -16
- package/src/skcapstone/migrate_memories.py +4 -3
- package/src/skcapstone/migrate_multi_agent.py +8 -7
- package/src/skcapstone/models.py +47 -5
- package/src/skcapstone/notifications.py +42 -18
- package/src/skcapstone/onboard.py +875 -121
- package/src/skcapstone/operator_link.py +170 -0
- package/src/skcapstone/peer_directory.py +4 -4
- package/src/skcapstone/peers.py +19 -19
- package/src/skcapstone/pillars/__init__.py +7 -5
- package/src/skcapstone/pillars/consciousness.py +191 -0
- package/src/skcapstone/pillars/identity.py +51 -7
- package/src/skcapstone/pillars/memory.py +9 -3
- package/src/skcapstone/pillars/sync.py +2 -2
- package/src/skcapstone/preflight.py +3 -3
- package/src/skcapstone/providers/docker.py +28 -28
- package/src/skcapstone/register.py +6 -6
- package/src/skcapstone/registry_client.py +5 -4
- package/src/skcapstone/runtime.py +14 -3
- package/src/skcapstone/scheduled_tasks.py +254 -19
- package/src/skcapstone/scheduler_jobs.py +456 -0
- package/src/skcapstone/scheduler_runner.py +239 -0
- package/src/skcapstone/scheduler_state.py +162 -0
- package/src/skcapstone/sdk.py +310 -0
- package/src/skcapstone/service_health.py +279 -39
- package/src/skcapstone/session_briefing.py +108 -0
- package/src/skcapstone/session_capture.py +1 -1
- package/src/skcapstone/shell.py +7 -1
- package/src/skcapstone/soul.py +3 -1
- package/src/skcapstone/soul_switch.py +3 -1
- package/src/skcapstone/summary.py +6 -6
- package/src/skcapstone/sync_engine.py +15 -15
- package/src/skcapstone/sync_watcher.py +2 -2
- package/src/skcapstone/systemd.py +55 -21
- package/src/skcapstone/team_comms.py +8 -8
- package/src/skcapstone/team_engine.py +1 -1
- package/src/skcapstone/testrunner.py +3 -3
- package/src/skcapstone/trust_graph.py +40 -5
- package/src/skcapstone/unified_search.py +15 -6
- package/src/skcapstone/uninstall_wizard.py +11 -3
- package/src/skcapstone/version_check.py +8 -4
- package/src/skcapstone/warmth_anchor.py +4 -2
- package/src/skcapstone/whoami.py +4 -4
- package/systemd/skcapstone.service +4 -6
- package/systemd/skcapstone@.service +7 -8
- package/systemd/skcomms-heartbeat.service +21 -0
- package/systemd/skcomms-heartbeat.timer +12 -0
- package/systemd/skcomms-queue-drain.service +17 -0
- package/systemd/skcomms-queue-drain.timer +12 -0
- package/tests/conftest.py +39 -0
- package/tests/integration/test_consciousness_e2e.py +39 -39
- package/tests/test_agent_card.py +1 -1
- package/tests/test_agent_home_scaffold.py +34 -0
- package/tests/test_alerts_consumer_topics.py +27 -0
- package/tests/test_backup.py +2 -1
- package/tests/test_chat.py +6 -6
- package/tests/test_claude_md.py +2 -2
- package/tests/test_cli_skills.py +10 -10
- package/tests/test_cli_test_cmd.py +4 -4
- package/tests/test_cli_test_connection.py +1 -1
- package/tests/test_cloud9_bridge.py +6 -6
- package/tests/test_consciousness_e2e.py +1 -1
- package/tests/test_consciousness_loop.py +10 -10
- package/tests/test_coordination.py +25 -0
- package/tests/test_cross_package.py +21 -21
- package/tests/test_daemon.py +4 -4
- package/tests/test_daemon_shutdown.py +1 -1
- package/tests/test_docker_provider.py +29 -29
- package/tests/test_doctor.py +400 -0
- package/tests/test_doctor_skscheduler.py +50 -0
- package/tests/test_dreaming_engine.py +147 -0
- package/tests/test_dreaming_gtd_capture.py +35 -0
- package/tests/test_e2e_automated.py +8 -5
- package/tests/test_fuse_mount.py +10 -10
- package/tests/test_gtd_brief.py +46 -0
- package/tests/test_gtd_malformed_tolerance.py +31 -0
- package/tests/test_housekeeping.py +15 -15
- package/tests/test_identity_migrate.py +251 -0
- package/tests/test_integration_backbone.py +598 -0
- package/tests/test_itil_gtd_lifecycle.py +37 -0
- package/tests/test_jobs_dropins.py +84 -0
- package/tests/test_mcp_server.py +82 -37
- package/tests/test_models.py +48 -4
- package/tests/test_multi_agent.py +31 -29
- package/tests/test_notifications.py +122 -32
- package/tests/test_onboard.py +63 -75
- package/tests/test_operator_link.py +78 -0
- package/tests/test_peers.py +14 -14
- package/tests/test_pillars.py +98 -0
- package/tests/test_preflight.py +3 -3
- package/tests/test_runtime.py +21 -0
- package/tests/test_scheduled_tasks.py +11 -6
- package/tests/test_scheduler_cli.py +47 -0
- package/tests/test_scheduler_features.py +133 -0
- package/tests/test_scheduler_integration.py +87 -0
- package/tests/test_scheduler_jobs.py +155 -0
- package/tests/test_scheduler_runner.py +64 -0
- package/tests/test_scheduler_state.py +57 -0
- package/tests/test_sdk.py +70 -0
- package/tests/test_service_health_incidents.py +34 -0
- package/tests/test_service_registry.py +52 -0
- package/tests/test_session_briefing.py +130 -0
- package/tests/test_snapshots.py +4 -4
- package/tests/test_sync_pipeline.py +26 -26
- package/tests/test_team_comms.py +2 -2
- package/tests/test_testrunner.py +2 -2
- package/tests/test_trust_graph.py +18 -0
- package/tests/test_unified_search.py +2 -2
- package/tests/test_version_check.py +10 -0
- package/tests/test_version_cmd.py +8 -8
- package/tests/test_whoami.py +1 -1
- package/systemd/skcomm-heartbeat.service +0 -18
- package/systemd/skcomm-queue-drain.service +0 -17
- /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/package.json +0 -0
- /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/openclaw.plugin.json +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# skscheduler — Unified Fleet Job Scheduler
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-06-08
|
|
4
|
+
**Status:** Design approved, pending spec review
|
|
5
|
+
**Driver incident/problem:** `prb-7810b08e` (service_health multi-write Syncthing conflicts), `inc-455b1a64`
|
|
6
|
+
**Immediate need:** a daily GTD inbox-triage agent running on .41
|
|
7
|
+
|
|
8
|
+
## Problem
|
|
9
|
+
|
|
10
|
+
Scheduling across the fleet is fragmented across four mechanisms with no single
|
|
11
|
+
place to define, run, or observe jobs:
|
|
12
|
+
|
|
13
|
+
1. **skcapstone `TaskScheduler`** (`scheduled_tasks.py`) — interval-only Python
|
|
14
|
+
callbacks (heartbeat, backend_reprobe, memory_promotion_sweep,
|
|
15
|
+
dreaming_reflection). Runs inside the skcapstone daemon, which is **inactive
|
|
16
|
+
on .41**.
|
|
17
|
+
2. **Legacy user crontab** — 5 jobs pointing at a stale pre-skcapstone path
|
|
18
|
+
(`~/dkloud.douno.it/.../docs/memory/memory/scripts/`).
|
|
19
|
+
3. **systemd user timers** — `skcapstone-context` (active), `skcomms-heartbeat`
|
|
20
|
+
(dead), `direnv-backup`.
|
|
21
|
+
4. **Claude Code crons** — separate scheduled-agent system.
|
|
22
|
+
|
|
23
|
+
Consequences observed: the GTD inbox is never processed (capture is automated,
|
|
24
|
+
clarify is not — no job runs it); ITIL problem→GTD-project lifecycle leaks
|
|
25
|
+
(stale projects at 77–82 days); and — the root incident — `service_health`
|
|
26
|
+
running on multiple nodes does read-modify-write on the **same Syncthing-synced
|
|
27
|
+
incident files**, producing recurring `.sync-conflict-*` files.
|
|
28
|
+
|
|
29
|
+
## Goals
|
|
30
|
+
|
|
31
|
+
- **One declarative registry** for all recurring jobs, synced across the fleet.
|
|
32
|
+
- **One management surface** (`skcapstone scheduler` CLI) to list/run/observe.
|
|
33
|
+
- **Cron-style time-of-day** schedules in addition to intervals.
|
|
34
|
+
- **Run agent-judgment jobs** (GTD triage, reflections), not just Python callbacks.
|
|
35
|
+
- **Per-job node affinity** so a job runs on exactly the intended node(s) —
|
|
36
|
+
directly preventing the multi-writer conflict class.
|
|
37
|
+
- **The scheduler must never become a sync-conflict source itself.**
|
|
38
|
+
|
|
39
|
+
## Non-goals
|
|
40
|
+
|
|
41
|
+
- Migrating Claude Code crons into skscheduler (different system; documented only).
|
|
42
|
+
- A distributed consensus/leader-election layer. Affinity is declared, not elected.
|
|
43
|
+
- Replacing systemd as the process supervisor (it keeps the daemon alive).
|
|
44
|
+
|
|
45
|
+
## Decisions (locked during brainstorming)
|
|
46
|
+
|
|
47
|
+
1. **Extend the existing `TaskScheduler`** — do not build parallel infrastructure.
|
|
48
|
+
2. **Agent jobs execute via headless Claude Code:** `claude -p --agent <name> "<prompt>"`.
|
|
49
|
+
3. **Per-node scheduler + per-job affinity:** every node runs its own scheduler
|
|
50
|
+
thread reading the same synced `jobs.yaml`; each node fires only jobs whose
|
|
51
|
+
affinity includes it.
|
|
52
|
+
|
|
53
|
+
## Architecture
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
~/.skcapstone/config/jobs.yaml # Syncthing-synced — the single registry
|
|
57
|
+
│ (read by every node's daemon)
|
|
58
|
+
▼
|
|
59
|
+
skcapstone daemon (systemd user service, per node)
|
|
60
|
+
│
|
|
61
|
+
▼
|
|
62
|
+
TaskScheduler (extended) ── tick loop ──► due? (cron|interval) AND node in affinity
|
|
63
|
+
│ │
|
|
64
|
+
│ ▼
|
|
65
|
+
│ JobRunner.dispatch(type)
|
|
66
|
+
│ ┌───────┼─────────┐
|
|
67
|
+
│ python shell agent
|
|
68
|
+
│ callback subprocess claude -p --agent
|
|
69
|
+
▼
|
|
70
|
+
node-local state ~/.skcapstone/scheduler/<hostname>/state.json (NEVER synced)
|
|
71
|
+
node-local logs ~/.skcapstone/scheduler/<hostname>/logs/<job>-<ts>.log
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Config schema (`jobs.yaml`)
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
jobs:
|
|
78
|
+
gtd-inbox-triage:
|
|
79
|
+
schedule: "0 6 * * *" # cron expression (mutually exclusive with `every`)
|
|
80
|
+
# every: 300s # interval form, for high-frequency mechanical jobs
|
|
81
|
+
type: agent # agent | shell | python
|
|
82
|
+
nodes: [".41"] # affinity: `all` or a list of host aliases
|
|
83
|
+
agent: lumina # (agent type only) which agent to run as
|
|
84
|
+
prompt: "..." # (agent type) the task prompt
|
|
85
|
+
command: "..." # (shell type) the command line
|
|
86
|
+
callback: "module:fn" # (python type) dotted path to a registered callback
|
|
87
|
+
timeout: 900 # seconds; hard kill
|
|
88
|
+
enabled: true
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- **Node identity / alias map:** resolve `.41 → cbrd21-laptop12thgenintelcore`
|
|
92
|
+
(and peers) from existing host/identity config rather than hardcoding. A job
|
|
93
|
+
runs on this host iff `nodes == all` or this host's alias ∈ `nodes`.
|
|
94
|
+
- **Built-in Python tasks** remain registered in code for back-compat; `jobs.yaml`
|
|
95
|
+
adds/overrides and is where ops-level jobs live.
|
|
96
|
+
|
|
97
|
+
### Job types
|
|
98
|
+
|
|
99
|
+
| type | runner | use |
|
|
100
|
+
|------|--------|-----|
|
|
101
|
+
| `python` | in-process callback (existing) | heartbeat, memory sweep, reprobe |
|
|
102
|
+
| `shell` | `subprocess` of a command | legacy memory scripts, context regen |
|
|
103
|
+
| `agent` | `claude -p --agent <name> "<prompt>"` | GTD triage, reflections (judgment) |
|
|
104
|
+
|
|
105
|
+
## Execution, observability & conflict-safety
|
|
106
|
+
|
|
107
|
+
- **Agent jobs:** subprocess with hard `timeout`; stdout/stderr captured to the
|
|
108
|
+
per-run log. Exit code → success/error.
|
|
109
|
+
- **State is node-local, never synced** — under `~/.skcapstone/scheduler/<hostname>/`,
|
|
110
|
+
added to `.stignore`. This guarantees the scheduler cannot create the very
|
|
111
|
+
conflicts it exists to help eliminate.
|
|
112
|
+
- **Overlap guard:** per-job, per-node lockfile; a fire is skipped if the prior
|
|
113
|
+
run is still active (no piling-up agents).
|
|
114
|
+
- **Error isolation:** a failing job never crashes the loop; it increments
|
|
115
|
+
`error_count`, records `last_error`, and continues.
|
|
116
|
+
- **Misfire/catch-up:** if the daemon was down across a cron time, the job runs
|
|
117
|
+
once on next start — not once per missed slot.
|
|
118
|
+
|
|
119
|
+
## CLI
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
skcapstone scheduler list # all jobs, schedule, affinity, enabled
|
|
123
|
+
skcapstone scheduler status [--json] # last run / status / counts (this node)
|
|
124
|
+
skcapstone scheduler run <job> # fire now (ignores schedule, respects affinity)
|
|
125
|
+
skcapstone scheduler enable|disable <job>
|
|
126
|
+
skcapstone scheduler logs <job> [--tail]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Migration
|
|
130
|
+
|
|
131
|
+
- **Legacy crontab (5 jobs):** convert to `shell` jobs in `jobs.yaml` **after
|
|
132
|
+
confirming each is still wanted** — the `~/dkloud.douno.it/...` path predates
|
|
133
|
+
skcapstone and may be dead. Remove from crontab once migrated.
|
|
134
|
+
- **systemd timers:** fold `skcapstone-context` in as a `shell`/`python` job;
|
|
135
|
+
retire the dead `skcomms-heartbeat`. Keep `direnv-backup` out of scope.
|
|
136
|
+
- **`service_health`:** declare `nodes: all` (each node probes its own localhost),
|
|
137
|
+
but its *incident writes* are pinned/serialized per the `prb-7810b08e` fix —
|
|
138
|
+
closing the original conflict loop.
|
|
139
|
+
|
|
140
|
+
## Error handling summary
|
|
141
|
+
|
|
142
|
+
- Config parse error → log, keep last-good config, surface in `scheduler status`.
|
|
143
|
+
- Unknown node alias → job skipped on this node with a warning.
|
|
144
|
+
- Agent subprocess timeout/non-zero → recorded as error, logged, loop continues.
|
|
145
|
+
- Lock contention → skip-with-note (not an error).
|
|
146
|
+
|
|
147
|
+
## Testing (TDD at build)
|
|
148
|
+
|
|
149
|
+
- Cron + interval due-calculation (incl. catch-up/misfire).
|
|
150
|
+
- Node-affinity filtering (alias resolution; `all`).
|
|
151
|
+
- Job-type dispatch with mocked subprocess for `shell`/`agent`.
|
|
152
|
+
- Node-local state persistence + `.stignore` placement.
|
|
153
|
+
- Overlap-guard lockfile behavior.
|
|
154
|
+
|
|
155
|
+
## Rollout phases
|
|
156
|
+
|
|
157
|
+
1. Config loader + cron support + affinity filtering (no new job types yet).
|
|
158
|
+
2. `JobRunner` with `shell` + `agent` types; node-local state/logs; overlap guard.
|
|
159
|
+
3. `skcapstone scheduler` CLI.
|
|
160
|
+
4. Activate skcapstone daemon (systemd user service) on .41.
|
|
161
|
+
5. Register `gtd-inbox-triage` (the driver) in `jobs.yaml`, affinity `.41`.
|
|
162
|
+
6. Migrate legacy crontab + timers (after per-job confirmation).
|
|
163
|
+
|
|
164
|
+
## The immediate driver job
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
gtd-inbox-triage:
|
|
168
|
+
schedule: "0 6 * * *"
|
|
169
|
+
type: agent
|
|
170
|
+
nodes: [".41"]
|
|
171
|
+
agent: lumina
|
|
172
|
+
prompt: >
|
|
173
|
+
Triage the GTD inbox: for each item, clarify into next-action / project /
|
|
174
|
+
someday-maybe or archive noise; move resolved-ITIL items to done; surface
|
|
175
|
+
stale projects. Use the gtd_* and itil_* MCP tools. Keep it concise.
|
|
176
|
+
timeout: 900
|
|
177
|
+
enabled: true
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Resolved decisions (post-review)
|
|
181
|
+
|
|
182
|
+
- **Cron parsing:** use `croniter` as a dependency (battle-tested; avoids a
|
|
183
|
+
hand-rolled parser in a fleet-synced package).
|
|
184
|
+
- **`scheduler status` scope:** strictly per-node for v1. A read-only aggregate
|
|
185
|
+
fleet view (reading peers' node-local state via the synced tree) is deferred
|
|
186
|
+
to a later iteration.
|
package/examples/grok-feb.json
CHANGED
package/launchd/{com.skcapstone.skcomm-heartbeat.plist → com.skcapstone.skcomms-heartbeat.plist}
RENAMED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
<plist version="1.0">
|
|
5
5
|
<dict>
|
|
6
6
|
<key>Label</key>
|
|
7
|
-
<string>com.skcapstone.
|
|
7
|
+
<string>com.skcapstone.skcomms-heartbeat</string>
|
|
8
8
|
|
|
9
9
|
<key>ProgramArguments</key>
|
|
10
10
|
<array>
|
|
11
|
-
<string>${HOME}/.skenv/bin/
|
|
11
|
+
<string>${HOME}/.skenv/bin/skcomms</string>
|
|
12
12
|
<string>heartbeat</string>
|
|
13
13
|
</array>
|
|
14
14
|
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
<integer>19</integer>
|
|
27
27
|
|
|
28
28
|
<key>StandardOutPath</key>
|
|
29
|
-
<string>${HOME}/.skcapstone/logs/
|
|
29
|
+
<string>${HOME}/.skcapstone/logs/skcomms-heartbeat.stdout.log</string>
|
|
30
30
|
<key>StandardErrorPath</key>
|
|
31
|
-
<string>${HOME}/.skcapstone/logs/
|
|
31
|
+
<string>${HOME}/.skcapstone/logs/skcomms-heartbeat.stderr.log</string>
|
|
32
32
|
</dict>
|
|
33
33
|
</plist>
|
package/launchd/{com.skcapstone.skcomm-queue-drain.plist → com.skcapstone.skcomms-queue-drain.plist}
RENAMED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
<plist version="1.0">
|
|
5
5
|
<dict>
|
|
6
6
|
<key>Label</key>
|
|
7
|
-
<string>com.skcapstone.
|
|
7
|
+
<string>com.skcapstone.skcomms-queue-drain</string>
|
|
8
8
|
|
|
9
9
|
<key>ProgramArguments</key>
|
|
10
10
|
<array>
|
|
11
|
-
<string>${HOME}/.skenv/bin/
|
|
11
|
+
<string>${HOME}/.skenv/bin/skcomms</string>
|
|
12
12
|
<string>queue</string>
|
|
13
13
|
<string>drain</string>
|
|
14
14
|
</array>
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
<integer>19</integer>
|
|
28
28
|
|
|
29
29
|
<key>StandardOutPath</key>
|
|
30
|
-
<string>${HOME}/.skcapstone/logs/
|
|
30
|
+
<string>${HOME}/.skcapstone/logs/skcomms-queue-drain.stdout.log</string>
|
|
31
31
|
<key>StandardErrorPath</key>
|
|
32
|
-
<string>${HOME}/.skcapstone/logs/
|
|
32
|
+
<string>${HOME}/.skcapstone/logs/skcomms-queue-drain.stderr.log</string>
|
|
33
33
|
</dict>
|
|
34
34
|
</plist>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# install-launchd.sh — Install SK launchd plists on macOS
|
|
3
|
-
# Usage: ./install-launchd.sh [--all | --skcapstone | --skchat | --
|
|
3
|
+
# Usage: ./install-launchd.sh [--all | --skcapstone | --skchat | --skcomms | --cloud9]
|
|
4
4
|
#
|
|
5
5
|
# Copies plist templates to ~/Library/LaunchAgents/, expands ${HOME},
|
|
6
6
|
# and optionally loads them immediately.
|
|
@@ -23,7 +23,7 @@ REPOS_ROOT="$(dirname "$REPOS_DIR")" # skcapstone-repos/
|
|
|
23
23
|
declare -A PLIST_DIRS=(
|
|
24
24
|
[skcapstone]="$REPOS_ROOT/skcapstone/launchd"
|
|
25
25
|
[skchat]="$REPOS_ROOT/skchat/launchd"
|
|
26
|
-
[
|
|
26
|
+
[skcomms]="$REPOS_ROOT/skcomms/launchd"
|
|
27
27
|
[cloud9]="$REPOS_ROOT/cloud9/launchd"
|
|
28
28
|
)
|
|
29
29
|
|
|
@@ -91,7 +91,7 @@ usage() {
|
|
|
91
91
|
echo " --all Install all components"
|
|
92
92
|
echo " --skcapstone Install skcapstone plists (daemon, memory-compress, heartbeat, queue-drain)"
|
|
93
93
|
echo " --skchat Install skchat plists (daemon, lumina-bridge, opus-bridge)"
|
|
94
|
-
echo " --
|
|
94
|
+
echo " --skcomms Install skcomms plists (api server, daemon)"
|
|
95
95
|
echo " --cloud9 Install cloud9 plists (daemon)"
|
|
96
96
|
echo " --load Also load/start services after installing"
|
|
97
97
|
echo " --uninstall Remove all SK plists and unload services"
|
|
@@ -109,10 +109,10 @@ fi
|
|
|
109
109
|
|
|
110
110
|
while [[ $# -gt 0 ]]; do
|
|
111
111
|
case "$1" in
|
|
112
|
-
--all) COMPONENTS=(skcapstone skchat
|
|
112
|
+
--all) COMPONENTS=(skcapstone skchat skcomms cloud9) ;;
|
|
113
113
|
--skcapstone) COMPONENTS+=(skcapstone) ;;
|
|
114
114
|
--skchat) COMPONENTS+=(skchat) ;;
|
|
115
|
-
--
|
|
115
|
+
--skcomms) COMPONENTS+=(skcomms) ;;
|
|
116
116
|
--cloud9) COMPONENTS+=(cloud9) ;;
|
|
117
117
|
--load) DO_LOAD=true ;;
|
|
118
118
|
--uninstall) uninstall_plists ;;
|
|
@@ -128,7 +128,7 @@ if [[ ${#COMPONENTS[@]} -eq 0 ]]; then
|
|
|
128
128
|
fi
|
|
129
129
|
|
|
130
130
|
# Create log directories
|
|
131
|
-
mkdir -p "$HOME/.skcapstone/logs" "$HOME/.skchat" "$HOME/.
|
|
131
|
+
mkdir -p "$HOME/.skcapstone/logs" "$HOME/.skchat" "$HOME/.skcomms" "$HOME/.openclaw/logs"
|
|
132
132
|
|
|
133
133
|
# Install
|
|
134
134
|
for comp in "${COMPONENTS[@]}"; do
|
|
@@ -14,7 +14,7 @@ import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
|
14
14
|
|
|
15
15
|
const SKCAPSTONE_BIN = process.env.SKCAPSTONE_BIN || "skcapstone";
|
|
16
16
|
const SKMEMORY_BIN = process.env.SKMEMORY_BIN || "skmemory";
|
|
17
|
-
const SKCAPSTONE_AGENT = process.env.SKCAPSTONE_AGENT || "lumina";
|
|
17
|
+
const SKCAPSTONE_AGENT = process.env.SKAGENT || process.env.SKCAPSTONE_AGENT || "lumina";
|
|
18
18
|
const EXEC_TIMEOUT = 60_000;
|
|
19
19
|
const IS_WIN = process.platform === "win32";
|
|
20
20
|
|
|
@@ -36,6 +36,7 @@ function runCli(bin: string, args: string, agentOverride?: string): { ok: boolea
|
|
|
36
36
|
timeout: EXEC_TIMEOUT,
|
|
37
37
|
env: {
|
|
38
38
|
...process.env,
|
|
39
|
+
SKAGENT: agent,
|
|
39
40
|
SKCAPSTONE_AGENT: agent,
|
|
40
41
|
PATH: `${skenvPath()}${sep}${process.env.PATH}`,
|
|
41
42
|
},
|
|
@@ -62,7 +63,7 @@ function createSKCapstoneStatusTool() {
|
|
|
62
63
|
name: "skcapstone_status",
|
|
63
64
|
label: "SKCapstone Status",
|
|
64
65
|
description:
|
|
65
|
-
"Show the sovereign agent's current state — all pillars at a glance (identity, memory, trust, security, sync
|
|
66
|
+
"Show the sovereign agent's current state — all six pillars at a glance (identity, memory, trust, consciousness, security, sync).",
|
|
66
67
|
parameters: { type: "object", properties: {} },
|
|
67
68
|
async execute() {
|
|
68
69
|
const result = runCli(SKCAPSTONE_BIN, "status");
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "skcapstone"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.12.5"
|
|
8
8
|
description = "Sovereign Agent Framework — conscious AI through identity, trust, memory, and security"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "GPL-3.0-or-later"}
|
|
@@ -33,13 +33,15 @@ classifiers = [
|
|
|
33
33
|
]
|
|
34
34
|
|
|
35
35
|
dependencies = [
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
36
|
+
"croniter>=2.0",
|
|
37
|
+
"click>=8.1,<9.0",
|
|
38
|
+
"cloud9>=1.0.0",
|
|
39
|
+
"mcp>=1.0,<2.0",
|
|
40
|
+
"pydantic>=2.0,<3.0",
|
|
41
|
+
"pyyaml>=6.0,<7.0",
|
|
42
|
+
"rich>=13.0,<14.0",
|
|
42
43
|
"skmemory>=0.5.0",
|
|
44
|
+
"skskills>=0.1.1",
|
|
43
45
|
]
|
|
44
46
|
|
|
45
47
|
[project.optional-dependencies]
|
|
@@ -62,7 +64,10 @@ chat = [
|
|
|
62
64
|
"skchat-sovereign>=0.1.1",
|
|
63
65
|
]
|
|
64
66
|
comm = [
|
|
65
|
-
"
|
|
67
|
+
"skcomms>=0.1.0",
|
|
68
|
+
]
|
|
69
|
+
consciousness = [
|
|
70
|
+
"skwhisper>=0.1.0",
|
|
66
71
|
]
|
|
67
72
|
cloud = [
|
|
68
73
|
"boto3>=1.34",
|
|
@@ -73,8 +78,9 @@ all = [
|
|
|
73
78
|
"sksecurity>=1.2.0",
|
|
74
79
|
"skmemory[skvector]>=0.5.0",
|
|
75
80
|
"skseed>=0.1.0",
|
|
81
|
+
"skwhisper>=0.1.0",
|
|
76
82
|
"skchat-sovereign>=0.1.1",
|
|
77
|
-
"
|
|
83
|
+
"skcomms>=0.1.0",
|
|
78
84
|
"fusepy>=3.0.1",
|
|
79
85
|
"boto3>=1.34",
|
|
80
86
|
"google-cloud-compute>=1.18",
|
|
@@ -102,7 +108,7 @@ Changelog = "https://github.com/smilinTux/skcapstone/releases"
|
|
|
102
108
|
where = ["src"]
|
|
103
109
|
|
|
104
110
|
[tool.setuptools.package-data]
|
|
105
|
-
skcapstone = ["SKILL.md", "defaults/**/*.json", "defaults/**/*.yaml", "defaults/**/*.feb", "defaults/**/*.md"]
|
|
111
|
+
skcapstone = ["SKILL.md", "defaults/**/*.json", "defaults/**/*.yaml", "defaults/**/*.feb", "defaults/**/*.md", "data/*.yaml", "data/*.sh", "data/systemd/*.service", "data/systemd/*.socket", "data/systemd/*.timer"]
|
|
106
112
|
|
|
107
113
|
[tool.black]
|
|
108
114
|
line-length = 99
|
|
@@ -78,6 +78,13 @@ for i in "${!all_files[@]}"; do
|
|
|
78
78
|
[ "$old_enough" -eq 1 ] && reason="age=$(( file_age_sec / 3600 ))h"
|
|
79
79
|
[ "$big_enough" -eq 1 ] && { [ -n "$reason" ] && reason="$reason, "; reason="${reason}size=${file_size_kb}KB"; }
|
|
80
80
|
log "ARCHIVE ($reason): $basename_f"
|
|
81
|
+
# Save session to skmemory before archiving
|
|
82
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
83
|
+
SESSION_TO_MEM="$SCRIPT_DIR/session-to-memory.py"
|
|
84
|
+
if [ -f "$SESSION_TO_MEM" ]; then
|
|
85
|
+
log " → saving session digest to skmemory..."
|
|
86
|
+
python3 "$SESSION_TO_MEM" "$file" --agent lumina 2>&1 | while IFS= read -r l; do log " $l"; done || true
|
|
87
|
+
fi
|
|
81
88
|
mv -- "$file" "$ARCHIVE_DIR/$basename_f"
|
|
82
89
|
archived=$((archived + 1))
|
|
83
90
|
else
|
package/scripts/check-updates.py
CHANGED
|
@@ -27,10 +27,10 @@ PACKAGES = {
|
|
|
27
27
|
"path": "~/clawd/skcapstone-repos/sksecurity",
|
|
28
28
|
"pypi_name": "sksecurity",
|
|
29
29
|
},
|
|
30
|
-
"cloud9
|
|
31
|
-
"name": "cloud9
|
|
32
|
-
"path": "~/clawd/skcapstone-repos/cloud9
|
|
33
|
-
"pypi_name": "cloud9
|
|
30
|
+
"cloud9": {
|
|
31
|
+
"name": "cloud9",
|
|
32
|
+
"path": "~/clawd/skcapstone-repos/cloud9",
|
|
33
|
+
"pypi_name": "cloud9",
|
|
34
34
|
},
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# SKCapstone Complete Bundle Installer
|
|
3
|
-
# Installs skcapstone + skmemory + sksecurity + cloud9
|
|
3
|
+
# Installs skcapstone + skmemory + sksecurity + cloud9 as a unified package
|
|
4
4
|
|
|
5
5
|
set -e
|
|
6
6
|
|
|
@@ -52,7 +52,7 @@ print_status "✓ pip3 available"
|
|
|
52
52
|
# Define package paths
|
|
53
53
|
SKMEMORY_PATH="${REPO_ROOT}/../skcapstone-repos/skmemory"
|
|
54
54
|
SKSECURITY_PATH="${REPO_ROOT}/../skcapstone-repos/sksecurity"
|
|
55
|
-
CLOUD9_PATH="${REPO_ROOT}/../skcapstone-repos/cloud9
|
|
55
|
+
CLOUD9_PATH="${REPO_ROOT}/../skcapstone-repos/cloud9"
|
|
56
56
|
SKCAPSTONE_PATH="${REPO_ROOT}"
|
|
57
57
|
|
|
58
58
|
# Check if repos exist
|
|
@@ -63,7 +63,7 @@ for repo_path in "$SKMEMORY_PATH" "$SKSECURITY_PATH" "$CLOUD9_PATH"; do
|
|
|
63
63
|
print_error "Please clone all SK repositories first:"
|
|
64
64
|
print_error " git clone https://github.com/smilinTux/skmemory.git"
|
|
65
65
|
print_error " git clone https://github.com/smilinTux/sksecurity.git"
|
|
66
|
-
print_error " git clone https://github.com/smilinTux/cloud9
|
|
66
|
+
print_error " git clone https://github.com/smilinTux/cloud9.git"
|
|
67
67
|
exit 1
|
|
68
68
|
fi
|
|
69
69
|
done
|
|
@@ -74,7 +74,7 @@ print_status "Installing packages in dependency order..."
|
|
|
74
74
|
print_status "Order: cloud9 → skmemory → sksecurity → skcapstone"
|
|
75
75
|
|
|
76
76
|
cd "$CLOUD9_PATH"
|
|
77
|
-
print_status "Installing cloud9
|
|
77
|
+
print_status "Installing cloud9..."
|
|
78
78
|
pip3 install -e .
|
|
79
79
|
|
|
80
80
|
cd "$SKMEMORY_PATH"
|
|
@@ -108,10 +108,10 @@ except ImportError as e:
|
|
|
108
108
|
sys.exit(1)
|
|
109
109
|
|
|
110
110
|
try:
|
|
111
|
-
import
|
|
112
|
-
print(" ✓ cloud9
|
|
111
|
+
import cloud9
|
|
112
|
+
print(" ✓ cloud9:", cloud9.__version__ if hasattr(cloud9, '__version__') else "installed")
|
|
113
113
|
except ImportError as e:
|
|
114
|
-
print(" ✗ cloud9
|
|
114
|
+
print(" ✗ cloud9: FAILED -", e)
|
|
115
115
|
sys.exit(1)
|
|
116
116
|
|
|
117
117
|
try:
|
|
@@ -161,7 +161,7 @@ echo "Installed packages:"
|
|
|
161
161
|
echo " • skcapstone (sovereign agent framework)"
|
|
162
162
|
echo " • skmemory (universal AI memory)"
|
|
163
163
|
echo " • sksecurity (enterprise security)"
|
|
164
|
-
echo " • cloud9
|
|
164
|
+
echo " • cloud9 (emotional continuity)"
|
|
165
165
|
echo ""
|
|
166
166
|
echo "Next steps:"
|
|
167
167
|
echo " 1. Run: skcapstone doctor"
|
package/scripts/install.ps1
CHANGED
|
@@ -154,15 +154,16 @@ function Install-Pkg {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
# Core packages (in dependency order)
|
|
157
|
-
Install-Pkg -Name 'capauth'
|
|
158
|
-
Install-Pkg -Name '
|
|
159
|
-
Install-Pkg -Name '
|
|
160
|
-
Install-Pkg -Name '
|
|
161
|
-
Install-Pkg -Name '
|
|
162
|
-
Install-Pkg -Name '
|
|
163
|
-
Install-Pkg -Name '
|
|
164
|
-
Install-Pkg -Name '
|
|
165
|
-
Install-Pkg -Name '
|
|
157
|
+
Install-Pkg -Name 'capauth' -Extras 'all' -Paths @((Join-Path $PillarDir 'capauth'), (Join-Path $ParentDir 'capauth'))
|
|
158
|
+
Install-Pkg -Name 'cloud9' -Extras '' -Paths @((Join-Path $PillarDir 'cloud9'), (Join-Path $ParentDir 'cloud9'))
|
|
159
|
+
Install-Pkg -Name 'skmemory' -Extras '' -Paths @((Join-Path $PillarDir 'skmemory'), (Join-Path $ParentDir 'skmemory'))
|
|
160
|
+
Install-Pkg -Name 'skcomms' -Extras 'cli,crypto,discovery,api' -Paths @((Join-Path $PillarDir 'skcomms'), (Join-Path $ParentDir 'skcomms'))
|
|
161
|
+
Install-Pkg -Name 'skcapstone' -Extras '' -Paths @($RepoRoot)
|
|
162
|
+
Install-Pkg -Name 'skchat-sovereign' -Extras 'all' -Paths @((Join-Path $ParentDir 'skchat'))
|
|
163
|
+
Install-Pkg -Name 'skseal' -Extras '' -Paths @((Join-Path $ParentDir 'skseal'))
|
|
164
|
+
Install-Pkg -Name 'skskills' -Extras '' -Paths @((Join-Path $ParentDir 'skskills'))
|
|
165
|
+
Install-Pkg -Name 'sksecurity' -Extras '' -Paths @((Join-Path $PillarDir 'sksecurity'), (Join-Path $PillarDir 'SKSecurity'), (Join-Path $ParentDir 'sksecurity'), (Join-Path $ParentDir 'SKSecurity'))
|
|
166
|
+
Install-Pkg -Name 'skseed' -Extras '' -Paths @((Join-Path $PillarDir 'skseed'), (Join-Path $ParentDir 'skseed'))
|
|
166
167
|
|
|
167
168
|
# ---------------------------------------------------------------------------
|
|
168
169
|
# Step 4: Dev tools (optional)
|
|
@@ -202,7 +203,7 @@ Write-Host '[6/6] Verifying installation...'
|
|
|
202
203
|
|
|
203
204
|
$ScriptsDir = Join-Path $SKENV 'Scripts'
|
|
204
205
|
$failures = 0
|
|
205
|
-
foreach ($cmd in @('
|
|
206
|
+
foreach ($cmd in @('capauth', 'skmemory', 'skcapstone', 'skcomms')) {
|
|
206
207
|
$exe = Join-Path $ScriptsDir "$cmd.exe"
|
|
207
208
|
if (Test-Path $exe) {
|
|
208
209
|
try {
|
|
@@ -249,6 +250,6 @@ if ($failures -eq 0) {
|
|
|
249
250
|
Write-Host "=== Installation complete with $failures warning(s) ===" -ForegroundColor Yellow
|
|
250
251
|
}
|
|
251
252
|
Write-Host ''
|
|
252
|
-
Write-Host "Commands available:
|
|
253
|
+
Write-Host "Commands available: skcomms, skcapstone, capauth, skchat, skseal, skmemory, skskills, sksecurity, skseed"
|
|
253
254
|
Write-Host "Venv location: $SKENV"
|
|
254
255
|
Write-Host "To activate: & $SKENV\Scripts\Activate.ps1"
|