@causyne/agent 0.0.0-stage → 1.10.1
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/LICENSE +102 -0
- package/README.md +31 -2
- package/SECURITY.md +24 -0
- package/bin/causyne.js +13 -0
- package/docs/ARCHITECTURE.md +63 -0
- package/docs/PROVENANCE.md +29 -0
- package/docs/SECURITY_REVIEW.md +89 -0
- package/docs/THIRD_PARTY_NOTICES.md +49 -0
- package/native-skills/ai-engineering/context-window-management/SKILL.md +43 -0
- package/native-skills/ai-engineering/llm-evaluation/SKILL.md +46 -0
- package/native-skills/ai-engineering/model-cost-and-latency/SKILL.md +46 -0
- package/native-skills/ai-engineering/prompt-construction/SKILL.md +42 -0
- package/native-skills/ai-engineering/retrieval-augmented-generation/SKILL.md +42 -0
- package/native-skills/ai-engineering/structured-output-and-schemas/SKILL.md +45 -0
- package/native-skills/ai-engineering/tool-calling-agents/SKILL.md +43 -0
- package/native-skills/android/app-performance-profiling/SKILL.md +42 -0
- package/native-skills/android/background-work-scheduling/SKILL.md +47 -0
- package/native-skills/android/compose-state-and-recomposition/SKILL.md +43 -0
- package/native-skills/android/gradle-build-configuration/SKILL.md +41 -0
- package/native-skills/android/lifecycle-and-leaks/SKILL.md +46 -0
- package/native-skills/android/play-store-release/SKILL.md +43 -0
- package/native-skills/android/room-and-persistence/SKILL.md +40 -0
- package/native-skills/backend/authentication-and-sessions/SKILL.md +45 -0
- package/native-skills/backend/background-jobs-and-queues/SKILL.md +42 -0
- package/native-skills/backend/caching-strategy/SKILL.md +44 -0
- package/native-skills/backend/graceful-shutdown/SKILL.md +42 -0
- package/native-skills/backend/rate-limiting-and-quotas/SKILL.md +40 -0
- package/native-skills/backend/rest-api-design/SKILL.md +40 -0
- package/native-skills/backend/webhook-delivery-and-receipt/SKILL.md +43 -0
- package/native-skills/cloud/cost-optimisation/SKILL.md +46 -0
- package/native-skills/cloud/iam-least-privilege/SKILL.md +43 -0
- package/native-skills/cloud/infrastructure-as-code/SKILL.md +43 -0
- package/native-skills/cloud/multi-region-and-failover/SKILL.md +43 -0
- package/native-skills/cloud/serverless-patterns/SKILL.md +47 -0
- package/native-skills/data/data-quality-monitoring/SKILL.md +51 -0
- package/native-skills/data/etl-pipeline-reliability/SKILL.md +43 -0
- package/native-skills/data/exploratory-analysis/SKILL.md +43 -0
- package/native-skills/data/metric-definition/SKILL.md +42 -0
- package/native-skills/data/notebook-to-production/SKILL.md +43 -0
- package/native-skills/database/backup-and-recovery/SKILL.md +43 -0
- package/native-skills/database/connection-pooling/SKILL.md +42 -0
- package/native-skills/database/data-integrity-and-constraints/SKILL.md +42 -0
- package/native-skills/database/query-optimisation/SKILL.md +38 -0
- package/native-skills/database/safe-migrations/SKILL.md +47 -0
- package/native-skills/database/schema-design/SKILL.md +38 -0
- package/native-skills/database/transactions-and-isolation/SKILL.md +41 -0
- package/native-skills/design/colour-system-construction/SKILL.md +38 -0
- package/native-skills/design/design-direction-brief/SKILL.md +41 -0
- package/native-skills/design/motion-and-transitions/SKILL.md +38 -0
- package/native-skills/design/responsive-strategy/SKILL.md +39 -0
- package/native-skills/design/spacing-and-rhythm/SKILL.md +38 -0
- package/native-skills/design/type-scale-and-hierarchy/SKILL.md +39 -0
- package/native-skills/design/visual-qa-loop/SKILL.md +42 -0
- package/native-skills/devops/docker-multi-stage-builds/SKILL.md +60 -0
- package/native-skills/devops/github-actions-ci/SKILL.md +60 -0
- package/native-skills/devops/incident-triage/SKILL.md +38 -0
- package/native-skills/devops/kubernetes-deployment-hardening/SKILL.md +64 -0
- package/native-skills/devops/observability-baseline/SKILL.md +38 -0
- package/native-skills/devops/secret-management/SKILL.md +40 -0
- package/native-skills/devops/terraform-state-and-modules/SKILL.md +36 -0
- package/native-skills/devops/zero-downtime-deploys/SKILL.md +40 -0
- package/native-skills/git/bisect-regression-hunt/SKILL.md +43 -0
- package/native-skills/git/branch-strategy/SKILL.md +39 -0
- package/native-skills/git/commit-hygiene/SKILL.md +41 -0
- package/native-skills/git/history-recovery/SKILL.md +44 -0
- package/native-skills/git/large-repository-surgery/SKILL.md +46 -0
- package/native-skills/git/merge-conflict-resolution/SKILL.md +42 -0
- package/native-skills/media/cinematic-3d-shot/SKILL.md +104 -0
- package/native-skills/mobile/app-startup-optimisation/SKILL.md +41 -0
- package/native-skills/mobile/cross-platform-tradeoffs/SKILL.md +42 -0
- package/native-skills/mobile/deep-linking/SKILL.md +39 -0
- package/native-skills/mobile/mobile-storage-security/SKILL.md +45 -0
- package/native-skills/mobile/offline-first-sync/SKILL.md +42 -0
- package/native-skills/mobile/push-notifications/SKILL.md +38 -0
- package/native-skills/performance/algorithmic-complexity/SKILL.md +43 -0
- package/native-skills/performance/concurrency-and-parallelism/SKILL.md +42 -0
- package/native-skills/performance/load-testing/SKILL.md +42 -0
- package/native-skills/performance/memory-and-leak-hunting/SKILL.md +41 -0
- package/native-skills/performance/network-and-payload-efficiency/SKILL.md +42 -0
- package/native-skills/performance/profiling-methodology/SKILL.md +46 -0
- package/native-skills/python/async-correctness/SKILL.md +40 -0
- package/native-skills/python/cli-tool-construction/SKILL.md +44 -0
- package/native-skills/python/data-processing-pipelines/SKILL.md +38 -0
- package/native-skills/python/environment-isolation/SKILL.md +41 -0
- package/native-skills/python/packaging-and-distribution/SKILL.md +56 -0
- package/native-skills/python/pytest-suite-design/SKILL.md +39 -0
- package/native-skills/python/type-hints-and-static-checking/SKILL.md +42 -0
- package/native-skills/security/authorization-model/SKILL.md +42 -0
- package/native-skills/security/crypto-usage/SKILL.md +48 -0
- package/native-skills/security/dependency-supply-chain/SKILL.md +42 -0
- package/native-skills/security/input-validation-and-injection/SKILL.md +44 -0
- package/native-skills/security/secure-file-uploads/SKILL.md +46 -0
- package/native-skills/security/security-headers-and-csp/SKILL.md +44 -0
- package/native-skills/security/threat-modelling/SKILL.md +46 -0
- package/native-skills/testing/end-to-end-test-stability/SKILL.md +42 -0
- package/native-skills/testing/property-based-testing/SKILL.md +46 -0
- package/native-skills/testing/regression-test-from-a-bug/SKILL.md +41 -0
- package/native-skills/testing/snapshot-and-visual-regression/SKILL.md +42 -0
- package/native-skills/testing/test-doubles-and-mocking/SKILL.md +43 -0
- package/native-skills/testing/test-strategy-and-pyramid/SKILL.md +39 -0
- package/native-skills/testing/writing-good-assertions/SKILL.md +42 -0
- package/native-skills/web/accessible-components/SKILL.md +45 -0
- package/native-skills/web/api-client-resilience/SKILL.md +39 -0
- package/native-skills/web/bundle-size-reduction/SKILL.md +38 -0
- package/native-skills/web/core-web-vitals/SKILL.md +40 -0
- package/native-skills/web/css-layout-systems/SKILL.md +41 -0
- package/native-skills/web/form-validation-ux/SKILL.md +39 -0
- package/native-skills/web/react-state-architecture/SKILL.md +41 -0
- package/native-skills/web/ssr-hydration-correctness/SKILL.md +45 -0
- package/package.json +68 -4
- package/src/agentLoop.js +2458 -0
- package/src/appChannel.js +109 -0
- package/src/approvalGrants.js +66 -0
- package/src/auditLog.js +52 -0
- package/src/autoUpdate.js +12 -0
- package/src/capabilities.js +36 -0
- package/src/checkpoints.js +1199 -0
- package/src/cliMode.js +638 -0
- package/src/commands.js +805 -0
- package/src/compiledSkills.js +540 -0
- package/src/config.js +130 -0
- package/src/contextManager.js +498 -0
- package/src/cortex/autoCondenser.js +192 -0
- package/src/cortex/provisioner.js +27 -0
- package/src/cortex/vectorDb.js +447 -0
- package/src/designPalettes.js +99 -0
- package/src/devMode.js +6 -0
- package/src/embodimentSession.js +180 -0
- package/src/entrypoint.js +194 -0
- package/src/execSafe.js +21 -0
- package/src/gitSnapshot.js +378 -0
- package/src/mcp/jsonRpc.js +165 -0
- package/src/mcp/mcpClient.js +136 -0
- package/src/mcp/mcpRegistry.js +207 -0
- package/src/memory.js +62 -0
- package/src/memoryManager.js +124 -0
- package/src/modelCatalogue.js +132 -0
- package/src/modelIds.js +42 -0
- package/src/modelRouter.js +145 -0
- package/src/outputStore.js +246 -0
- package/src/perception.js +124 -0
- package/src/planCache.js +437 -0
- package/src/procSignal.js +32 -0
- package/src/providers/anthropic.js +408 -0
- package/src/providers/base.js +328 -0
- package/src/providers/dashscope-byok.js +86 -0
- package/src/providers/deepseek.js +80 -0
- package/src/providers/factory.js +37 -0
- package/src/providers/gemini.js +346 -0
- package/src/providers/moonshot.js +73 -0
- package/src/providers/muse.js +169 -0
- package/src/providers/ollama.js +104 -0
- package/src/providers/openai-compatible.js +84 -0
- package/src/providers/openai.js +20 -0
- package/src/providers/qwen-byok.js +76 -0
- package/src/providers/xai.js +73 -0
- package/src/provisioning/capabilityConsent.js +24 -0
- package/src/provisioning/capabilityProvisioner.js +271 -0
- package/src/provisioning/capabilityTools.js +29 -0
- package/src/reporting.js +373 -0
- package/src/sandbox.js +529 -0
- package/src/sessionStore.js +279 -0
- package/src/skillsManager.js +288 -0
- package/src/slopDetector.js +307 -0
- package/src/taskBuffer.js +45 -0
- package/src/taskShape.js +241 -0
- package/src/textDiff.js +150 -0
- package/src/tokenTracker.js +560 -0
- package/src/tool-scripts/ax_snapshot.applescript +39 -0
- package/src/tool-scripts/ax_snapshot.ps1 +10 -0
- package/src/tool-scripts/desktop_act.applescript +58 -0
- package/src/tool-scripts/resolve_automator.py +119 -0
- package/src/toolPacks.js +524 -0
- package/src/tools/archive.js +63 -0
- package/src/tools/astryxOracle.js +78 -0
- package/src/tools/axSnapshot.js +165 -0
- package/src/tools/blenderAutomator.js +349 -0
- package/src/tools/browserAutomator.js +252 -0
- package/src/tools/checkSystemSpecs.js +64 -0
- package/src/tools/clipboard.js +36 -0
- package/src/tools/codeSearchAst.js +101 -0
- package/src/tools/codeSearcher.js +230 -0
- package/src/tools/codeTools.js +262 -0
- package/src/tools/codebaseSearch.js +75 -0
- package/src/tools/createSkill.js +129 -0
- package/src/tools/deferredMcpSearch.js +246 -0
- package/src/tools/desktopAct.js +208 -0
- package/src/tools/desktopOpen.js +34 -0
- package/src/tools/dynamicLoader.js +44 -0
- package/src/tools/executeProceduralMedia.js +93 -0
- package/src/tools/fsDelete.js +51 -0
- package/src/tools/fsEdit.js +105 -0
- package/src/tools/fsFind.js +128 -0
- package/src/tools/fsList.js +77 -0
- package/src/tools/fsMove.js +57 -0
- package/src/tools/fsRead.js +87 -0
- package/src/tools/fsSearch.js +198 -0
- package/src/tools/fsWrite.js +41 -0
- package/src/tools/gameAiBehaviorTree.js +208 -0
- package/src/tools/gameAnimationRig.js +194 -0
- package/src/tools/gameAssetFetcher.js +372 -0
- package/src/tools/gameAssetHarvester.js +210 -0
- package/src/tools/gameAudioSynth.js +267 -0
- package/src/tools/gameBuilder.js +886 -0
- package/src/tools/gameCanvasAudit.js +101 -0
- package/src/tools/gameCinematicSequencer.js +151 -0
- package/src/tools/gameDataForge.js +124 -0
- package/src/tools/gameDialogueTreeGen.js +166 -0
- package/src/tools/gameEconomyBalancer.js +161 -0
- package/src/tools/gameEntitySpawner.js +207 -0
- package/src/tools/gameLoreForge.js +153 -0
- package/src/tools/gameQuestArcBuilder.js +152 -0
- package/src/tools/gameSceneBuilder.js +158 -0
- package/src/tools/gameShaderForge.js +181 -0
- package/src/tools/gameTilemapGenerator.js +164 -0
- package/src/tools/gameUiHudBuilder.js +292 -0
- package/src/tools/gameVfxEmitterGen.js +108 -0
- package/src/tools/gameWebRuntimeInspector.js +91 -0
- package/src/tools/generateMediaViaApi.js +358 -0
- package/src/tools/gitExec.js +54 -0
- package/src/tools/godotAutomator.js +437 -0
- package/src/tools/manageLocalAiDependencies.js +220 -0
- package/src/tools/memoryWrite.js +99 -0
- package/src/tools/multiEdit.js +107 -0
- package/src/tools/palmierAutomator.js +104 -0
- package/src/tools/pdfReader.js +112 -0
- package/src/tools/persistentShell.js +148 -0
- package/src/tools/printer.js +316 -0
- package/src/tools/procTerm.js +91 -0
- package/src/tools/processList.js +52 -0
- package/src/tools/readNativeSkill.js +39 -0
- package/src/tools/registry.js +277 -0
- package/src/tools/resolveAutomator.js +102 -0
- package/src/tools/screenshot.js +75 -0
- package/src/tools/subagentOrchestrator.js +305 -0
- package/src/tools/sysRun.js +125 -0
- package/src/tools/todoWrite.js +75 -0
- package/src/tools/toolDispatch.js +127 -0
- package/src/tools/toolForge.js +124 -0
- package/src/tools/updatePlan.js +88 -0
- package/src/tools/viewImage.js +82 -0
- package/src/tools/visionInspector.js +154 -0
- package/src/tools/webFetch.js +74 -0
- package/src/tools/webSearch.js +82 -0
- package/src/tui/ask.js +164 -0
- package/src/tui/banner.js +158 -0
- package/src/tui/block.js +152 -0
- package/src/tui/chatRenderer.js +953 -0
- package/src/tui/completion.js +424 -0
- package/src/tui/dialogs.js +606 -0
- package/src/tui/diff.js +296 -0
- package/src/tui/history.js +135 -0
- package/src/tui/home.js +217 -0
- package/src/tui/invocation.js +105 -0
- package/src/tui/keys.js +443 -0
- package/src/tui/lineEditor.js +256 -0
- package/src/tui/overlay.js +256 -0
- package/src/tui/prompt.js +1258 -0
- package/src/tui/selectList.js +335 -0
- package/src/tui/stage.js +330 -0
- package/src/tui/stageSurface.js +609 -0
- package/src/tui/statusLine.js +254 -0
- package/src/tui/text.js +345 -0
- package/src/tui/theme.js +393 -0
- package/src/tui/toolDisplay.js +176 -0
- package/src/tui/transcript.js +235 -0
- package/src/tui/viewport.js +337 -0
- package/src/uncertainty.js +271 -0
- package/src/userSkills.js +265 -0
- package/src/utils/cli_ui.js +0 -0
- package/src/utils/inquirer.js +12 -0
- package/src/utils/paths.js +37 -0
- package/src/version.js +38 -0
- package/src/vfeTracker.js +220 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// The Three-Channel Doctrine, made executable.
|
|
2
|
+
//
|
|
3
|
+
// Channel A — the app's own API / plugin / CLI ~50-200 tok exact
|
|
4
|
+
// Channel B — the accessibility tree ~200-800 tok structured
|
|
5
|
+
// Channel C — pixels: screenshot + OCR + click ~1,500-2,500 universal, brittle
|
|
6
|
+
//
|
|
7
|
+
// Channel C costs 10-50x Channel A per observation. An agent that reaches for
|
|
8
|
+
// pixels first is not more capable — it is more expensive AND less reliable.
|
|
9
|
+
//
|
|
10
|
+
// THIS MODULE IS A GUARD, NOT ADVICE. A doctrine that lives only in a system
|
|
11
|
+
// prompt is a suggestion the model may ignore on any given turn, and the turn
|
|
12
|
+
// it ignores it is the turn it clicks blindly through Blender instead of
|
|
13
|
+
// calling `blender_act`. So the router is consulted by `desktop_act` BEFORE any
|
|
14
|
+
// actuation, and it refuses the pixel path for an app that has a native one.
|
|
15
|
+
//
|
|
16
|
+
// It is deliberately NOT a tool the model calls. Another tool schema is another
|
|
17
|
+
// ~200 tokens on every request to describe a decision the runtime can make on
|
|
18
|
+
// its own, and a decision the model is allowed to skip is not a guard.
|
|
19
|
+
//
|
|
20
|
+
// EXTENDING IT: a Higgsfield-style plugin (Photoshop UXP, a Blender add-on) is
|
|
21
|
+
// one more CHANNEL_A row, not a parallel architecture. That is the whole point
|
|
22
|
+
// of the table — the lesson from Higgsfield is "a native app API beats pixels",
|
|
23
|
+
// not "build our own Higgsfield".
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Apps that already have a Channel A tool, keyed by matcher.
|
|
27
|
+
*
|
|
28
|
+
* `match` is tested against a lowercased app name, so "Blender", "blender" and
|
|
29
|
+
* "Blender 4.2" all resolve. Order matters only for readability; the first hit
|
|
30
|
+
* wins.
|
|
31
|
+
*/
|
|
32
|
+
const CHANNEL_A = [
|
|
33
|
+
{ match: /\bblender\b/, tool: 'blender_act', app: 'Blender' },
|
|
34
|
+
{ match: /\b(davinci|resolve)\b/, tool: 'resolve_act', app: 'DaVinci Resolve' },
|
|
35
|
+
{ match: /\bgodot\b/, tool: 'godot_act', app: 'Godot' },
|
|
36
|
+
{ match: /\bpalmier\b/, tool: 'palmier_act', app: 'Palmier Pro' },
|
|
37
|
+
{
|
|
38
|
+
match: /\b(chrome|chromium|safari|firefox|edge|brave|arc)\b/,
|
|
39
|
+
tool: 'browser_act',
|
|
40
|
+
app: 'a web browser'
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Apps a GUI actuator must never drive, because a text interface already
|
|
46
|
+
* exists and driving it by pixels is strictly worse in every dimension —
|
|
47
|
+
* slower, costlier, and unable to read its own output reliably.
|
|
48
|
+
*/
|
|
49
|
+
const NEVER_BY_PIXEL = [
|
|
50
|
+
{ match: /\b(terminal|iterm|iterm2|konsole|gnome-terminal|powershell|cmd|wezterm|alacritty|kitty)\b/,
|
|
51
|
+
tool: 'sysRun',
|
|
52
|
+
reason: 'a shell is a text interface; clicking one is slower and cannot read its output reliably' }
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
/** @typedef {{channel:'A'|'B'|'C', tool:string|null, reason:string, blocked:boolean}} ChannelChoice */
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Decide the cheapest channel that can drive `appName`.
|
|
59
|
+
*
|
|
60
|
+
* Pure and total — an empty or unknown app name resolves to Channel C, which
|
|
61
|
+
* is correct: "I do not recognise this app" is exactly when the universal
|
|
62
|
+
* fallback is the right answer.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} appName Application name, as the user or the OS reports it.
|
|
65
|
+
* @returns {ChannelChoice}
|
|
66
|
+
*/
|
|
67
|
+
export function resolveChannel(appName) {
|
|
68
|
+
const name = String(appName || '').toLowerCase().trim();
|
|
69
|
+
|
|
70
|
+
if (name !== '') {
|
|
71
|
+
for (const entry of NEVER_BY_PIXEL) {
|
|
72
|
+
if (entry.match.test(name)) {
|
|
73
|
+
return {
|
|
74
|
+
channel: 'A',
|
|
75
|
+
tool: entry.tool,
|
|
76
|
+
reason: `${appName} must not be driven by pixels — ${entry.reason}. Use ${entry.tool}.`,
|
|
77
|
+
blocked: true
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (const entry of CHANNEL_A) {
|
|
83
|
+
if (entry.match.test(name)) {
|
|
84
|
+
return {
|
|
85
|
+
channel: 'A',
|
|
86
|
+
tool: entry.tool,
|
|
87
|
+
reason: `${entry.app} has a native automation API. ${entry.tool} is exact, roughly 10x cheaper `
|
|
88
|
+
+ `per observation, and does not break when the window moves. Use it instead of clicking.`,
|
|
89
|
+
blocked: true
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
channel: 'C',
|
|
97
|
+
tool: null,
|
|
98
|
+
reason: name === ''
|
|
99
|
+
? 'No application named, so no native channel can be selected; the pixel path applies.'
|
|
100
|
+
: `No native automation channel is registered for "${appName}". Read it with ax_snapshot first `
|
|
101
|
+
+ `(Channel B, structured and ~5x cheaper than a screenshot), and act by element name where possible.`,
|
|
102
|
+
blocked: false
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Every app name pattern with a Channel A tool. For tests and diagnostics. */
|
|
107
|
+
export function channelATools() {
|
|
108
|
+
return [...CHANNEL_A.map(e => e.tool), ...NEVER_BY_PIXEL.map(e => e.tool)];
|
|
109
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// "Allow always" — standing approvals, for the length of this process only.
|
|
2
|
+
//
|
|
3
|
+
// WHY THIS EXISTS. Being asked to approve the same tool for the twentieth time
|
|
4
|
+
// in one task does not make anyone safer; it makes them stop reading and start
|
|
5
|
+
// hammering the approve key, which is the exact failure the gate exists to
|
|
6
|
+
// prevent. A gate people are numb to is not a gate. So the honest answer is to
|
|
7
|
+
// let someone who has decided a tool is fine say so once, deliberately.
|
|
8
|
+
//
|
|
9
|
+
// THE SCOPE IS THE PROCESS, AND THAT IS THE WHOLE SAFETY MODEL.
|
|
10
|
+
// This is a module-level Set. It is never written to config.json, never
|
|
11
|
+
|
|
12
|
+
// approval is gone — the same contract opencode states to the user in its own
|
|
13
|
+
// words: "This will allow … until OpenCode is restarted."
|
|
14
|
+
//
|
|
15
|
+
// Persisting these to disk would be a different feature with a different risk
|
|
16
|
+
// profile: a permission granted in a hurry six weeks ago, silently applying to
|
|
17
|
+
// a session the user has forgotten they configured. If that is ever wanted it
|
|
18
|
+
// should be an explicit, listed, revocable config entry — not a quiet
|
|
19
|
+
// side-effect of a keypress in a modal.
|
|
20
|
+
|
|
21
|
+
/** Tool names approved for the rest of this process. Deliberately in memory. */
|
|
22
|
+
const standingApprovals = new Set();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Record a standing approval for one tool.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} toolName Canonical tool name, e.g. 'sysRun'.
|
|
28
|
+
*/
|
|
29
|
+
export function grantAlways(toolName) {
|
|
30
|
+
const name = String(toolName || '').trim();
|
|
31
|
+
if (name) standingApprovals.add(name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* True when this tool may run without asking again.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} toolName
|
|
38
|
+
* @returns {boolean}
|
|
39
|
+
*/
|
|
40
|
+
export function isAlwaysAllowed(toolName) {
|
|
41
|
+
return standingApprovals.has(String(toolName || '').trim());
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Every standing approval, for `/approvals` and for the audit trail. */
|
|
45
|
+
export function listAlwaysAllowed() {
|
|
46
|
+
return [...standingApprovals].sort();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Take them all back.
|
|
51
|
+
*
|
|
52
|
+
* A grant with no way out is a trap, so this is reachable from `/approvals
|
|
53
|
+
* clear` as well as from a restart.
|
|
54
|
+
*
|
|
55
|
+
* @returns {number} how many were revoked
|
|
56
|
+
*/
|
|
57
|
+
export function revokeAllAlways() {
|
|
58
|
+
const count = standingApprovals.size;
|
|
59
|
+
standingApprovals.clear();
|
|
60
|
+
return count;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Revoke one. @returns {boolean} true when there was something to revoke. */
|
|
64
|
+
export function revokeAlways(toolName) {
|
|
65
|
+
return standingApprovals.delete(String(toolName || '').trim());
|
|
66
|
+
}
|
package/src/auditLog.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import { causyneHome } from './utils/paths.js';
|
|
5
|
+
|
|
6
|
+
const LOG_DIR = path.join(causyneHome(), 'logs');
|
|
7
|
+
|
|
8
|
+
export class AuditLog {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.ensureLogDir();
|
|
11
|
+
const date = new Date().toISOString().split('T')[0];
|
|
12
|
+
this.logFile = path.join(LOG_DIR, `audit-${date}.jsonl`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
ensureLogDir() {
|
|
16
|
+
if (!fs.existsSync(LOG_DIR)) {
|
|
17
|
+
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
log(eventData) {
|
|
22
|
+
const entry = {
|
|
23
|
+
ts: new Date().toISOString(),
|
|
24
|
+
...eventData
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Append to file synchronously to ensure it writes before any potential crash
|
|
28
|
+
try {
|
|
29
|
+
fs.appendFileSync(this.logFile, JSON.stringify(entry) + '\n');
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.error('Failed to write audit log:', e);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getRecentLogs(limit = 100) {
|
|
36
|
+
if (!fs.existsSync(this.logFile)) return [];
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const content = fs.readFileSync(this.logFile, 'utf8');
|
|
40
|
+
const lines = content.split('\n').filter(l => l.trim().length > 0);
|
|
41
|
+
|
|
42
|
+
return lines.slice(-limit).map(l => {
|
|
43
|
+
try { return JSON.parse(l); } catch(e) { return null; }
|
|
44
|
+
}).filter(Boolean);
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error('Failed to read audit log:', e);
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const auditLog = new AuditLog();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UI } from './utils/cli_ui.js';
|
|
2
|
+
|
|
3
|
+
// No registry polling or self-modifying installation. A release channel has
|
|
4
|
+
// not been selected or published for the independent Causyne project yet.
|
|
5
|
+
export async function runSelfUpdate(verbose = false) {
|
|
6
|
+
if (verbose) UI.printInfo('Automatic updates are disabled. Review and update your Causyne source checkout explicitly. No public package is configured yet.');
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function startUpdateChecker() {
|
|
11
|
+
// Compatibility with the local CLI caller; deliberately no timer or I/O.
|
|
12
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Capability gating (monetization Move 1) — DORMANT scaffolding.
|
|
2
|
+
//
|
|
3
|
+
// The agent is BYOK, so inference costs the owner nothing; the value a
|
|
4
|
+
// subscription buys is a *better body*, not more tokens. This module maps local
|
|
5
|
+
// capabilities to the minimum tier that unlocks them.
|
|
6
|
+
//
|
|
7
|
+
// It is deliberately INERT until launch: while CAPABILITY_GATING_ENABLED is
|
|
8
|
+
// false, isCapabilityAllowed() returns true for everyone, so pre-release
|
|
9
|
+
// development behaves exactly as before. At launch, flip the flag and call
|
|
10
|
+
// isCapabilityAllowed(tier, cap) at each local feature entry point.
|
|
11
|
+
|
|
12
|
+
export const CAPABILITY_GATING_ENABLED = false;
|
|
13
|
+
|
|
14
|
+
// Tiers rank so a higher plan is a superset of a lower one.
|
|
15
|
+
export const TIER_RANK = {
|
|
16
|
+
starter: 0, free: 0, fast: 1,
|
|
17
|
+
premium: 2, premium_annual: 2,
|
|
18
|
+
max: 3, super_max: 4,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Minimum tier rank required for each gated capability.
|
|
22
|
+
export const CAPABILITY_MIN_RANK = {
|
|
23
|
+
cortex_memory: TIER_RANK.premium, // V5 persistent memory across sessions
|
|
24
|
+
tool_forge: TIER_RANK.max, // self-evolving runtime tool creation
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Whether `tier` unlocks `capability`. Returns true for everything while the
|
|
29
|
+
* gate is dormant, and for any capability not present in the matrix.
|
|
30
|
+
*/
|
|
31
|
+
export function isCapabilityAllowed(tier, capability) {
|
|
32
|
+
if (!CAPABILITY_GATING_ENABLED) return true;
|
|
33
|
+
const need = CAPABILITY_MIN_RANK[capability];
|
|
34
|
+
if (need == null) return true;
|
|
35
|
+
return (TIER_RANK[tier] ?? 0) >= need;
|
|
36
|
+
}
|