shieldcortex 3.4.27 → 3.4.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  2. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  3. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  4. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
  26. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  27. package/dist/api/routes/admin.js +14 -2
  28. package/dist/api/routes/memories.js +25 -5
  29. package/dist/api/routes/system.js +28 -0
  30. package/dist/database/init.js +45 -4
  31. package/dist/index.js +54 -1
  32. package/dist/license/cli.js +50 -22
  33. package/dist/license/index.d.ts +1 -1
  34. package/dist/license/index.js +1 -1
  35. package/dist/license/store.d.ts +4 -1
  36. package/dist/license/store.js +38 -15
  37. package/dist/license/trial.d.ts +48 -0
  38. package/dist/license/trial.js +128 -0
  39. package/dist/memory/store.js +17 -0
  40. package/dist/tools/remember.d.ts +2 -2
  41. package/dist/tools/remember.js +2 -0
  42. package/package.json +1 -1
  43. /package/dashboard/.next/standalone/dashboard/.next/static/{HmcjI_64kRaQVUrHxobIe → c51lWSauvNC0BT832gfq4}/_buildManifest.js +0 -0
  44. /package/dashboard/.next/standalone/dashboard/.next/static/{HmcjI_64kRaQVUrHxobIe → c51lWSauvNC0BT832gfq4}/_clientMiddlewareManifest.json +0 -0
  45. /package/dashboard/.next/standalone/dashboard/.next/static/{HmcjI_64kRaQVUrHxobIe → c51lWSauvNC0BT832gfq4}/_ssgManifest.js +0 -0
@@ -0,0 +1,128 @@
1
+ /**
2
+ * 14-day Pro trial — auto-granted on first install, no signup required.
3
+ *
4
+ * Trial state is stored in ~/.shieldcortex/trial.json.
5
+ * It is NEVER reset on reinstall (file persists across npm updates).
6
+ * An active paid license always takes priority over the trial.
7
+ */
8
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+ const TRIAL_DURATION_DAYS = 14;
12
+ // ── Cache ────────────────────────────────────────────────
13
+ let cachedTrial = undefined; // undefined = not loaded yet
14
+ function getConfigDir() {
15
+ return process.env.SHIELDCORTEX_CONFIG_DIR || join(homedir(), '.shieldcortex');
16
+ }
17
+ function getTrialFile() {
18
+ return join(getConfigDir(), 'trial.json');
19
+ }
20
+ /** Clear the in-memory trial cache (useful for testing). */
21
+ export function clearTrialCache() {
22
+ cachedTrial = undefined;
23
+ }
24
+ // ── Helpers ──────────────────────────────────────────────
25
+ function computeStatus(data, justCreated = false) {
26
+ const startMs = new Date(data.startedAt).getTime();
27
+ const expiryMs = startMs + data.durationDays * 24 * 60 * 60 * 1000;
28
+ const nowMs = Date.now();
29
+ const msRemaining = expiryMs - nowMs;
30
+ const daysRemaining = Math.max(0, Math.ceil(msRemaining / (24 * 60 * 60 * 1000)));
31
+ return {
32
+ active: nowMs < expiryMs,
33
+ daysRemaining,
34
+ startedAt: data.startedAt,
35
+ expiresAt: new Date(expiryMs).toISOString(),
36
+ justCreated,
37
+ };
38
+ }
39
+ // ── Public API ────────────────────────────────────────────
40
+ /**
41
+ * Read (and lazily create) the trial state.
42
+ *
43
+ * - If `trial.json` already exists: read and return its status.
44
+ * - If `trial.json` does NOT exist AND `license.json` does NOT exist: create it now (first install).
45
+ * - If `trial.json` does NOT exist AND `license.json` DOES exist: don't create — user already has a paid license.
46
+ * - Returns null if no trial applies.
47
+ *
48
+ * Pass `licenseFileExists` to avoid a second disk read inside store.ts.
49
+ */
50
+ export function getTrialStatus(licenseFileExists) {
51
+ // Skip trial if env var set (useful for tests and CI)
52
+ if (process.env.SHIELDCORTEX_SKIP_TRIAL === '1')
53
+ return null;
54
+ if (cachedTrial !== undefined)
55
+ return cachedTrial;
56
+ try {
57
+ const trialFile = getTrialFile();
58
+ if (existsSync(trialFile)) {
59
+ const data = JSON.parse(readFileSync(trialFile, 'utf-8'));
60
+ // Return full status whether active or expired — callers use status.active to distinguish.
61
+ // Only return null when no trial file exists at all.
62
+ const status = computeStatus(data, false);
63
+ cachedTrial = status;
64
+ return cachedTrial;
65
+ }
66
+ // No trial file — only create on first install (no license either)
67
+ if (licenseFileExists) {
68
+ cachedTrial = null;
69
+ return null;
70
+ }
71
+ // First run — create the trial file
72
+ mkdirSync(getConfigDir(), { recursive: true });
73
+ const now = new Date().toISOString();
74
+ const trialData = {
75
+ startedAt: now,
76
+ durationDays: TRIAL_DURATION_DAYS,
77
+ acknowledged: false,
78
+ };
79
+ writeFileSync(trialFile, JSON.stringify(trialData, null, 2) + '\n', { mode: 0o600 });
80
+ const status = computeStatus(trialData, true);
81
+ cachedTrial = status; // always active on creation
82
+ return cachedTrial;
83
+ }
84
+ catch {
85
+ cachedTrial = null;
86
+ return null;
87
+ }
88
+ }
89
+ /**
90
+ * Whether a trial is currently active (Pro features unlocked by trial).
91
+ * Only returns true when no paid license is in effect — callers should
92
+ * check the license first and only fall back to this.
93
+ */
94
+ export function isTrialActive(licenseFileExists) {
95
+ return getTrialStatus(licenseFileExists)?.active === true;
96
+ }
97
+ /**
98
+ * Days remaining in the trial (0 if expired or no trial).
99
+ */
100
+ export function getTrialDaysRemaining(licenseFileExists) {
101
+ return getTrialStatus(licenseFileExists)?.daysRemaining ?? 0;
102
+ }
103
+ /**
104
+ * Mark the welcome message as acknowledged (suppress on subsequent runs).
105
+ */
106
+ export function acknowledgeTrialWelcome() {
107
+ try {
108
+ const trialFile = getTrialFile();
109
+ if (!existsSync(trialFile))
110
+ return;
111
+ const data = JSON.parse(readFileSync(trialFile, 'utf-8'));
112
+ if (!data.acknowledged) {
113
+ data.acknowledged = true;
114
+ writeFileSync(trialFile, JSON.stringify(data, null, 2) + '\n', { mode: 0o600 });
115
+ }
116
+ // Update cache
117
+ if (cachedTrial) {
118
+ cachedTrial = { ...cachedTrial, justCreated: false };
119
+ }
120
+ }
121
+ catch {
122
+ // Best effort
123
+ }
124
+ }
125
+ /** Exposed for tests — returns the full trial file path */
126
+ export function getTrialFilePath() {
127
+ return getTrialFile();
128
+ }
@@ -124,6 +124,23 @@ function safeJsonParse(value, fallback) {
124
124
  }
125
125
  function inferSourceDetails(input, source) {
126
126
  const tags = (input.tags ?? []).map((tag) => tag.toLowerCase());
127
+ const metadata = input.metadata ?? {};
128
+ const metadataSourceType = typeof metadata.sourceType === 'string' ? metadata.sourceType : null;
129
+ const metadataSourceIdentifier = typeof metadata.sourceIdentifier === 'string' ? metadata.sourceIdentifier : null;
130
+ if ((tags.includes('session-end') || tags.includes('session-stop') || tags.includes('keyword-trigger')) && metadataSourceType === 'hook') {
131
+ return {
132
+ sourceKind: 'hook',
133
+ captureMethod: tags.includes('auto-extracted') ? 'auto' : 'hook',
134
+ sourceValue: `hook:${metadataSourceIdentifier ?? 'openclaw'}`,
135
+ };
136
+ }
137
+ if ((tags.includes('realtime-plugin') || tags.includes('llm-output')) && metadataSourceType === 'agent') {
138
+ return {
139
+ sourceKind: 'agent',
140
+ captureMethod: tags.includes('auto-extracted') ? 'auto' : 'plugin',
141
+ sourceValue: `agent:${metadataSourceIdentifier ?? 'openclaw-plugin'}`,
142
+ };
143
+ }
127
144
  if (tags.includes('openclaw-hook')) {
128
145
  return { sourceKind: 'hook', captureMethod: tags.includes('auto-extracted') ? 'auto' : 'hook', sourceValue: 'hook:openclaw' };
129
146
  }
@@ -45,8 +45,8 @@ export declare const rememberSchema: z.ZodObject<{
45
45
  tags?: string[] | undefined;
46
46
  sourceIdentifier?: string | undefined;
47
47
  sessionId?: string | undefined;
48
- importance?: "critical" | "low" | "high" | "normal" | undefined;
49
48
  sourceType?: "user" | "cli" | "hook" | "agent" | "api" | "email" | "web" | "file" | "tool_response" | undefined;
49
+ importance?: "critical" | "low" | "high" | "normal" | undefined;
50
50
  agentId?: string | undefined;
51
51
  workspaceDir?: string | undefined;
52
52
  }, {
@@ -64,8 +64,8 @@ export declare const rememberSchema: z.ZodObject<{
64
64
  tags?: string[] | undefined;
65
65
  sourceIdentifier?: string | undefined;
66
66
  sessionId?: string | undefined;
67
- importance?: "critical" | "low" | "high" | "normal" | undefined;
68
67
  sourceType?: "user" | "cli" | "hook" | "agent" | "api" | "email" | "web" | "file" | "tool_response" | undefined;
68
+ importance?: "critical" | "low" | "high" | "normal" | undefined;
69
69
  agentId?: string | undefined;
70
70
  workspaceDir?: string | undefined;
71
71
  }>;
@@ -67,6 +67,8 @@ export async function executeRemember(input) {
67
67
  ...(input.sessionId ? { sessionId: input.sessionId } : {}),
68
68
  ...(input.agentId ? { agentId: input.agentId } : {}),
69
69
  ...(input.workspaceDir ? { workspaceDir: input.workspaceDir } : {}),
70
+ ...(derivedSource?.type ? { sourceType: derivedSource.type } : {}),
71
+ ...(derivedSource?.identifier ? { sourceIdentifier: derivedSource.identifier } : {}),
70
72
  };
71
73
  // Map importance to salience override
72
74
  let salienceOverride;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shieldcortex",
3
- "version": "3.4.27",
3
+ "version": "3.4.29",
4
4
  "description": "Trustworthy memory and security for AI agents. Recall debugging, review queue, OpenClaw session capture, and memory poisoning defence for Claude Code, Codex, OpenClaw, LangChain, and MCP agents.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",