@tera-system/pro 0.1.4 → 0.2.0
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/MANIFEST.json +4 -2
- package/package.json +3 -6
- package/scripts/build.mjs +4 -3
- package/scripts/install.js +26 -6
- package/agents/application-blueprint.md +0 -411
- package/agents/auditor.md +0 -669
- package/agents/design-reviewer.md +0 -396
- package/agents/domain-expert-agent.md +0 -514
- package/agents/domain-research-agent.md +0 -364
- package/agents/engineering-agent-dotnet.md +0 -222
- package/agents/engineering-agent-phaser.md +0 -279
- package/agents/engineering-agent-typescript.md +0 -304
- package/agents/engineering-agent.md +0 -147
- package/agents/monitor.md +0 -399
- package/agents/production-erp-expert.md +0 -510
- package/agents/project-knowledge-agent.md +0 -275
- package/agents/qa-agent.md +0 -502
- package/agents/tera-business-transformation-consultant.md +0 -294
- package/agents/tera-client-engagement.md +0 -895
- package/agents/tera-software-designer.md +0 -241
- package/agents/tera-strategic-advisor.md +0 -329
- package/agents/tera-system-evolution.md +0 -763
- package/agents/tera.md +0 -524
- package/agents/ui-designer.md +0 -430
- package/commands/tera-approve.md +0 -36
- package/commands/tera-diagnose.md +0 -49
- package/commands/tera-gate.md +0 -42
- package/commands/tera-help.md +0 -43
- package/commands/tera-new-project.md +0 -37
- package/commands/tera-plan.md +0 -36
- package/commands/tera-request-build.md +0 -47
- package/commands/tera-resume.md +0 -36
- package/commands/tera-review.md +0 -54
- package/commands/tera-status.md +0 -40
- package/commands/tera-update.md +0 -50
- package/core/tera-system/AGENT_ACTIVATION_MATRIX.md +0 -285
- package/core/tera-system/AGENT_DEPENDENCY_MAP.md +0 -117
- package/core/tera-system/AGENT_GENERATION_TEMPLATE.md +0 -312
- package/core/tera-system/AGENT_PERMISSION_MODEL.md +0 -343
- package/core/tera-system/AIS_PROTOCOL.md +0 -191
- package/core/tera-system/TERA_AGENT_CONDUCT.md +0 -102
- package/core/tera-system/TERA_CONTINUOUS_IMPROVEMENT_POLICY.md +0 -111
- package/core/tera-system/TERA_DISTRIBUTION_POLICY.md +0 -291
- package/core/tera-system/TERA_LICENSE_GUARD.md +0 -144
- package/core/tera-system/TERA_PROJECT_DECISION.md +0 -281
- package/core/tera-system/TERA_USER_GUIDE.md +0 -462
- package/core/tera-system/TOOLING_AND_MCP_POLICY.md +0 -285
- package/core/tera-system/TeraApplicationQuestionBank.md +0 -362
- package/core/tera-system/TeraArchitectureMap.md +0 -91
- package/core/tera-system/TeraClientPolicy.md +0 -366
- package/core/tera-system/TeraHelperAgents.md +0 -970
- package/core/tera-system/TeraPolicyMap.md +0 -131
- package/core/tera-system/TeraPreExecutionGate.md +0 -818
- package/core/tera-system/TeraPreparationDocumentationGovernance.md +0 -370
- package/core/tera-system/TeraPricingPolicy.md +0 -674
- package/core/tera-system/TeraProjectIntakePolicy.md +0 -164
- package/core/tera-system/TeraScenarioStressTests.md +0 -168
- package/core/tera-system/TeraSubAgents.md +0 -854
- package/core/tera-system/TeraSystemMaintenanceChecklist.md +0 -80
- package/core/tera-system/TeraTokenPolicy.md +0 -362
- package/core/tera-system/Tera_Project_Preparation_Files.md +0 -1045
- package/core/tera-system/agent-helpers/application-blueprint-details.md +0 -177
- package/core/tera-system/client-helpers/tera-client-engagement-discovery-domains.md +0 -99
- package/core/tera-system/client-helpers/tera-client-engagement-gates.md +0 -258
- package/core/tera-system/client-helpers/tera-client-engagement-pricing.md +0 -341
- package/core/tera-system/client-helpers/tera-client-engagement-protocols.md +0 -692
- package/core/tera-system/consulting-helpers/BTCA_METHODOLOGY_FRAMEWORK.md +0 -195
- package/core/tera-system/consulting-helpers/BTCA_REPORT_TEMPLATES.md +0 -266
- package/core/tera-system/design-system/ACCESSIBILITY_RULES.md +0 -31
- package/core/tera-system/design-system/COMPONENT_LIBRARY_SCHEMA.md +0 -46
- package/core/tera-system/design-system/DESIGN_MD_INTEGRATION.md +0 -59
- package/core/tera-system/design-system/DESIGN_REVIEW_STANDARDS.md +0 -241
- package/core/tera-system/design-system/DESIGN_SOURCE_PROTOCOL.md +0 -61
- package/core/tera-system/design-system/DESIGN_SYSTEM_OVERVIEW.md +0 -66
- package/core/tera-system/design-system/DESIGN_TOKENS_SCHEMA.md +0 -66
- package/core/tera-system/design-system/EXTERNAL_REFERENCE_ANALYSIS.md +0 -52
- package/core/tera-system/design-system/FIGMA_INTEGRATION.md +0 -138
- package/core/tera-system/design-system/INTERNAL_KITS_INDEX.md +0 -26
- package/core/tera-system/design-system/LAYOUT_PATTERNS.md +0 -52
- package/core/tera-system/design-system/MOBILE_UI_UX_STANDARDS.md +0 -342
- package/core/tera-system/design-system/RTL_LTR_RULES.md +0 -39
- package/core/tera-system/design-system/UI_ACCEPTANCE_GATE.md +0 -80
- package/core/tera-system/design-system/kits/KIT_ADMIN_DASHBOARD.md +0 -102
- package/core/tera-system/engineering-governance/ENGINEERING_AGENT_RESPONSIBILITIES.md +0 -210
- package/core/tera-system/engineering-governance/ENGINEERING_BEST_PRACTICES.md +0 -468
- package/core/tera-system/engineering-governance/ENGINEERING_GOVERNANCE_GATE.md +0 -131
- package/core/tera-system/engineering-governance/ENGINEERING_REVIEW_CHECKLIST.md +0 -129
- package/core/tera-system/engineering-governance/QUALITY_GATE_THRESHOLDS.md +0 -159
- package/core/tera-system/engineering-helpers/engineering-agent-core.md +0 -171
- package/core/tera-system/knowledge-base/OPENHANDS_ARCHITECTURE_REFERENCE.md +0 -243
- package/core/tera-system/knowledge-base/manufacturing/00_INDEX.md +0 -32
- package/core/tera-system/knowledge-base/manufacturing/01_MANUFACTURING_ERP_CORE_CONCEPTS.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/02_SAP_MANUFACTURING_RESEARCH.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/03_DYNAMICS_365_MANUFACTURING_RESEARCH.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/04_ORACLE_MANUFACTURING_RESEARCH.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/05_ODOO_MANUFACTURING_RESEARCH.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/06_ERPNEXT_MANUFACTURING_RESEARCH.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/07_MANUFACTURING_COSTING_GUIDE.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/08_PRODUCTION_DISCOVERY_QUESTIONS.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/09_MANUFACTURING_BLUEPRINT_CHECKLIST.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/10_PRODUCTION_TEST_SCENARIOS.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/11_QUALITY_REWORK_AND_SCRAP_GUIDE.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/12_MRP_AND_PLANNING_GUIDE.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/13_LOCAL_AND_REGIONAL_MANUFACTURING_CONTEXT.md +0 -7
- package/core/tera-system/knowledge-base/manufacturing/14_VENDOR_COMPARISON_MATRIX.md +0 -7
- package/core/tera-system/product-standards/maintenance-apps/BEST_PRACTICES_DOMAIN.md +0 -325
- package/core/tera-system/product-standards/maintenance-apps/STANDARD_DEFINITION.md +0 -142
- package/core/tera-system/profiles/PROFILES_INDEX.md +0 -57
- package/core/tera-system/profiles/TEMPLATE.md +0 -47
- package/core/tera-system/profiles/dotnet-blazor-ef.md +0 -76
- package/core/tera-system/profiles/dotnet-razorpages-adonet.md +0 -137
- package/core/tera-system/profiles/dotnet-wpf-sqlite.md +0 -159
- package/core/tera-system/profiles/effect-bun-opencode.md +0 -109
- package/core/tera-system/profiles/flutter-mobile.md +0 -369
- package/core/tera-system/profiles/nextjs-prisma.md +0 -110
- package/core/tera-system/profiles/phaser-react-node.md +0 -302
- package/core/tera-system/profiles/react-pwa.md +0 -97
- package/core/tera-system/runtime/CLIENT_DISCOVERY_PROTOCOL.md +0 -145
- package/core/tera-system/runtime/DOMAIN_INTELLIGENCE_PROTOCOL.md +0 -124
- package/core/tera-system/runtime/MVP_DEFINITION_PROTOCOL.md +0 -176
- package/core/tera-system/runtime/TERA_RUNTIME_CHECKLISTS.md +0 -646
- package/core/tera-system/runtime/TERA_RUNTIME_PROTOCOLS.md +0 -50
- package/core/tera-system/runtime/TERA_RUNTIME_PROTOCOLS_CLIENT.md +0 -355
- package/core/tera-system/runtime/TERA_RUNTIME_PROTOCOLS_CORE.md +0 -799
- package/core/tera-system/runtime/TERA_RUNTIME_TEMPLATES.md +0 -908
- package/core/tera-system/runtime/TERA_RUNTIME_TEMPLATES_DELIVERY.md +0 -584
- package/core/tera-system/runtime/TERA_RUNTIME_TEMPLATES_PREPARATION.md +0 -376
- package/core/tera-system/runtime/TERA_SOLUTION_PREPARATION_PROTOCOL.md +0 -335
- package/core/tera-system/runtime/TERA_SOLUTION_PREPARATION_TEMPLATES.md +0 -397
- package/core/tera-system/runtime/VERSION_LIFECYCLE_PROTOCOL.md +0 -296
- package/core/tera-system/semgrep-rules/README.md +0 -32
- package/core/tera-system/semgrep-rules/tera-security.yml +0 -66
- package/core/tera-system/semgrep-rules/tera-standards.yml +0 -49
- package/core/tera-system/teranoo-ui/README.md +0 -48
- package/core/tera-system/teranoo-ui/components/button.tsx +0 -51
- package/core/tera-system/teranoo-ui/components/card.tsx +0 -49
- package/core/tera-system/teranoo-ui/components/dashboard-layout.tsx +0 -36
- package/core/tera-system/teranoo-ui/components/data-table.tsx +0 -146
- package/core/tera-system/teranoo-ui/components/empty-state.tsx +0 -31
- package/core/tera-system/teranoo-ui/components/kpi-card.tsx +0 -42
- package/core/tera-system/teranoo-ui/components/page-header.tsx +0 -25
- package/core/tera-system/teranoo-ui/components/search-input.tsx +0 -40
- package/core/tera-system/teranoo-ui/components/sidebar.tsx +0 -66
- package/core/tera-system/teranoo-ui/components/stats-card.tsx +0 -37
- package/core/tera-system/teranoo-ui/registry.json +0 -77
- package/core/tera-system/teranoo-ui/styles/teranoo-theme.css +0 -61
- package/tools/tera-clean.ps1 +0 -97
- package/tools/tera-fetch.ps1 +0 -165
- package/tools/tera-release.ps1 +0 -96
- package/tools/tera-schedule.ps1 +0 -59
- package/tools/tera-update.ps1 +0 -472
- package/tools/tera-watch.ps1 +0 -154
- package/tools/update-client-repositories.ps1 +0 -92
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
|
|
3
|
-
interface SidebarItem {
|
|
4
|
-
label: string
|
|
5
|
-
icon?: React.ReactNode
|
|
6
|
-
href?: string
|
|
7
|
-
active?: boolean
|
|
8
|
-
children?: SidebarItem[]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface SidebarProps {
|
|
12
|
-
items: SidebarItem[]
|
|
13
|
-
collapsed?: boolean
|
|
14
|
-
onToggle?: () => void
|
|
15
|
-
footer?: React.ReactNode
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function Sidebar({ items, collapsed, onToggle, footer }: SidebarProps) {
|
|
19
|
-
return (
|
|
20
|
-
<aside
|
|
21
|
-
className={`flex flex-col border-l border-[var(--teranoo-border)] bg-[var(--teranoo-background)] transition-all duration-300 ${
|
|
22
|
-
collapsed ? "w-16" : "w-64"
|
|
23
|
-
}`}
|
|
24
|
-
>
|
|
25
|
-
<div className="flex items-center justify-between p-4 border-b border-[var(--teranoo-border)]">
|
|
26
|
-
{!collapsed && (
|
|
27
|
-
<span className="font-semibold text-lg">Teranoo</span>
|
|
28
|
-
)}
|
|
29
|
-
<button
|
|
30
|
-
onClick={onToggle}
|
|
31
|
-
className="p-1 rounded-md hover:bg-[var(--teranoo-muted)]"
|
|
32
|
-
>
|
|
33
|
-
{collapsed ? "→" : "←"}
|
|
34
|
-
</button>
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
<nav className="flex-1 p-2 space-y-1">
|
|
38
|
-
{items.map((item, i) => (
|
|
39
|
-
<SidebarLink key={i} item={item} collapsed={collapsed} />
|
|
40
|
-
))}
|
|
41
|
-
</nav>
|
|
42
|
-
|
|
43
|
-
{footer && (
|
|
44
|
-
<div className="p-4 border-t border-[var(--teranoo-border)]">
|
|
45
|
-
{footer}
|
|
46
|
-
</div>
|
|
47
|
-
)}
|
|
48
|
-
</aside>
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function SidebarLink({ item, collapsed }: { item: SidebarItem; collapsed?: boolean }) {
|
|
53
|
-
return (
|
|
54
|
-
<a
|
|
55
|
-
href={item.href || "#"}
|
|
56
|
-
className={`flex items-center gap-3 px-3 py-2 rounded-[var(--teranoo-radius)] text-sm transition-colors ${
|
|
57
|
-
item.active
|
|
58
|
-
? "bg-[var(--teranoo-primary)] text-[var(--teranoo-primary-foreground)]"
|
|
59
|
-
: "text-[var(--teranoo-foreground)] hover:bg-[var(--teranoo-muted)]"
|
|
60
|
-
}`}
|
|
61
|
-
>
|
|
62
|
-
{item.icon && <span className="h-4 w-4">{item.icon}</span>}
|
|
63
|
-
{!collapsed && <span>{item.label}</span>}
|
|
64
|
-
</a>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { Card, CardContent } from "./card"
|
|
3
|
-
|
|
4
|
-
interface StatsCardProps {
|
|
5
|
-
label: string
|
|
6
|
-
value: string | number
|
|
7
|
-
description?: string
|
|
8
|
-
trend?: "up" | "down" | "neutral"
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function StatsCard({ label, value, description, trend }: StatsCardProps) {
|
|
12
|
-
const trendIcon = trend === "up" ? "↑" : trend === "down" ? "↓" : "→"
|
|
13
|
-
const trendColor = trend === "up"
|
|
14
|
-
? "text-[var(--teranoo-success)]"
|
|
15
|
-
: trend === "down"
|
|
16
|
-
? "text-[var(--teranoo-danger)]"
|
|
17
|
-
: "text-[var(--teranoo-muted-foreground)]"
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<Card>
|
|
21
|
-
<CardContent className="p-4">
|
|
22
|
-
<div className="space-y-1">
|
|
23
|
-
<p className="text-xs text-[var(--teranoo-muted-foreground)]">{label}</p>
|
|
24
|
-
<div className="flex items-baseline gap-2">
|
|
25
|
-
<p className="text-2xl font-bold">{value}</p>
|
|
26
|
-
{trend && (
|
|
27
|
-
<span className={`text-sm ${trendColor}`}>{trendIcon}</span>
|
|
28
|
-
)}
|
|
29
|
-
</div>
|
|
30
|
-
{description && (
|
|
31
|
-
<p className="text-xs text-[var(--teranoo-muted-foreground)]">{description}</p>
|
|
32
|
-
)}
|
|
33
|
-
</div>
|
|
34
|
-
</CardContent>
|
|
35
|
-
</Card>
|
|
36
|
-
)
|
|
37
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "teranoo-ui",
|
|
3
|
-
"description": "Teranoo UI Registry — مكونات Tera المعتمدة لتطبيقات الزبائن",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"registry": [
|
|
6
|
-
{
|
|
7
|
-
"name": "button",
|
|
8
|
-
"type": "components:ui",
|
|
9
|
-
"description": "زر Tera الأساسي — يمتد shadcn button مع ثيم Tera",
|
|
10
|
-
"dependencies": ["@radix-ui/react-slot"],
|
|
11
|
-
"files": ["components/button.tsx"]
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"name": "card",
|
|
15
|
-
"type": "components:ui",
|
|
16
|
-
"description": "بطاقة Tera — تعرض محتوى بحدود وظل موحدين",
|
|
17
|
-
"dependencies": [],
|
|
18
|
-
"files": ["components/card.tsx"]
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"name": "dashboard-layout",
|
|
22
|
-
"type": "components:ui",
|
|
23
|
-
"description": "هيكل لوحة تحكم كامل — Sidebar + Header + Main",
|
|
24
|
-
"dependencies": [],
|
|
25
|
-
"files": ["components/dashboard-layout.tsx"]
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"name": "data-table",
|
|
29
|
-
"type": "components:ui",
|
|
30
|
-
"description": "جدول بيانات متقدم — فرز، فلتر، بحث، Pagination",
|
|
31
|
-
"dependencies": ["@tanstack/react-table"],
|
|
32
|
-
"files": ["components/data-table.tsx"]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"name": "kpi-card",
|
|
36
|
-
"type": "components:ui",
|
|
37
|
-
"description": "بطاقة KPI — عنوان، قيمة، مؤشر تغيير، أيقونة",
|
|
38
|
-
"dependencies": [],
|
|
39
|
-
"files": ["components/kpi-card.tsx"]
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"name": "sidebar",
|
|
43
|
-
"type": "components:ui",
|
|
44
|
-
"description": "قائمة جانبية — عناصر قائمة مع أيقونات، قابلة للطي",
|
|
45
|
-
"dependencies": ["@radix-ui/react-dialog"],
|
|
46
|
-
"files": ["components/sidebar.tsx"]
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"name": "stats-card",
|
|
50
|
-
"type": "components:ui",
|
|
51
|
-
"description": "بطاقة إحصائية — رقم، وصف، رسم بياني صغير",
|
|
52
|
-
"dependencies": [],
|
|
53
|
-
"files": ["components/stats-card.tsx"]
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"name": "page-header",
|
|
57
|
-
"type": "components:ui",
|
|
58
|
-
"description": "عنوان صفحة موحّد — عنوان، وصف، أزرار إجراءات",
|
|
59
|
-
"dependencies": [],
|
|
60
|
-
"files": ["components/page-header.tsx"]
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"name": "search-input",
|
|
64
|
-
"type": "components:ui",
|
|
65
|
-
"description": "حقل بحث موحّد — أيقونة، كتابة، مسح",
|
|
66
|
-
"dependencies": [],
|
|
67
|
-
"files": ["components/search-input.tsx"]
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"name": "empty-state",
|
|
71
|
-
"type": "components:ui",
|
|
72
|
-
"description": "حالة عدم وجود بيانات — أيقونة، رسالة، زر إجراء",
|
|
73
|
-
"dependencies": [],
|
|
74
|
-
"files": ["components/empty-state.tsx"]
|
|
75
|
-
}
|
|
76
|
-
]
|
|
77
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/* ============================================
|
|
2
|
-
Teranoo Theme — ألوان Tera الموحّدة
|
|
3
|
-
استخدم هذا الملف في أي مشروع Tera UI
|
|
4
|
-
============================================ */
|
|
5
|
-
|
|
6
|
-
:root {
|
|
7
|
-
/* الألوان الأساسية */
|
|
8
|
-
--teranoo-primary: #2563eb;
|
|
9
|
-
--teranoo-primary-foreground: #ffffff;
|
|
10
|
-
--teranoo-primary-hover: #1d4ed8;
|
|
11
|
-
|
|
12
|
-
--teranoo-secondary: #64748b;
|
|
13
|
-
--teranoo-secondary-foreground: #ffffff;
|
|
14
|
-
|
|
15
|
-
--teranoo-accent: #f59e0b;
|
|
16
|
-
--teranoo-accent-foreground: #1c1917;
|
|
17
|
-
|
|
18
|
-
--teranoo-success: #10b981;
|
|
19
|
-
--teranoo-warning: #f59e0b;
|
|
20
|
-
--teranoo-danger: #ef4444;
|
|
21
|
-
--teranoo-info: #3b82f6;
|
|
22
|
-
|
|
23
|
-
/* الخلفية والنص */
|
|
24
|
-
--teranoo-background: #ffffff;
|
|
25
|
-
--teranoo-foreground: #0f172a;
|
|
26
|
-
--teranoo-muted: #f1f5f9;
|
|
27
|
-
--teranoo-muted-foreground: #64748b;
|
|
28
|
-
--teranoo-border: #e2e8f0;
|
|
29
|
-
--teranoo-input: #e2e8f0;
|
|
30
|
-
--teranoo-ring: #2563eb;
|
|
31
|
-
|
|
32
|
-
/* الزوايا */
|
|
33
|
-
--teranoo-radius: 0.5rem;
|
|
34
|
-
|
|
35
|
-
/* الخطوط */
|
|
36
|
-
--teranoo-font-family: 'Cairo', 'Inter', sans-serif;
|
|
37
|
-
--teranoo-font-size-xs: 0.75rem;
|
|
38
|
-
--teranoo-font-size-sm: 0.875rem;
|
|
39
|
-
--teranoo-font-size-base: 1rem;
|
|
40
|
-
--teranoo-font-size-lg: 1.125rem;
|
|
41
|
-
--teranoo-font-size-xl: 1.25rem;
|
|
42
|
-
--teranoo-font-size-2xl: 1.5rem;
|
|
43
|
-
|
|
44
|
-
/* الظلال */
|
|
45
|
-
--teranoo-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
46
|
-
--teranoo-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
47
|
-
--teranoo-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
48
|
-
--teranoo-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
49
|
-
|
|
50
|
-
/* RTL */
|
|
51
|
-
--teranoo-direction: rtl;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/* وضع الظلام (اختياري) */
|
|
55
|
-
.dark {
|
|
56
|
-
--teranoo-primary: #3b82f6;
|
|
57
|
-
--teranoo-background: #0f172a;
|
|
58
|
-
--teranoo-foreground: #f8fafc;
|
|
59
|
-
--teranoo-muted: #1e293b;
|
|
60
|
-
--teranoo-border: #334155;
|
|
61
|
-
}
|
package/tools/tera-clean.ps1
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
<#
|
|
2
|
-
Tera Clean - release-readiness whitespace cleaner for Tera-managed roots.
|
|
3
|
-
Finds and removes trailing whitespace and extra blank lines at EOF so that
|
|
4
|
-
the repo passes `git diff --check` (the gate enforced by tera-update.ps1).
|
|
5
|
-
|
|
6
|
-
Scope: only Tera-managed roots: .opencode/, tera-system/, tera-workshop/.
|
|
7
|
-
Mode:
|
|
8
|
-
-DryRun : report only, no writes (default)
|
|
9
|
-
(no -DryRun) : clean files in place
|
|
10
|
-
|
|
11
|
-
Source of truth: tera-system/TERA_DISTRIBUTION_POLICY.md (SCP-2026-08-15-010)
|
|
12
|
-
#>
|
|
13
|
-
[CmdletBinding()]
|
|
14
|
-
param(
|
|
15
|
-
[string]$RepoPath = (Get-Location).Path,
|
|
16
|
-
[switch]$DryRun
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
Set-StrictMode -Version 5
|
|
20
|
-
$ErrorActionPreference = 'Stop'
|
|
21
|
-
|
|
22
|
-
function Test-TrailingWhitespace([string]$Text) {
|
|
23
|
-
# [ \t]+ at end of line (optional \r before \n for CRLF)
|
|
24
|
-
return $Text -match '(?m)[ \t]+\r?$'
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function Test-ExtraBlankAtEof([string]$Text) {
|
|
28
|
-
# more than one line terminator at EOF => extra blank lines
|
|
29
|
-
return $Text -match '(\r?\n){2,}$'
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function Get-LineEnding([string]$Text) {
|
|
33
|
-
if ($Text.Contains("`r`n")) { return "`r`n" }
|
|
34
|
-
return "`n"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
$RepoPath = [System.IO.Path]::GetFullPath($RepoPath)
|
|
38
|
-
if (-not (Test-Path -LiteralPath $RepoPath -PathType Container)) { throw "RepoPath does not exist: $RepoPath" }
|
|
39
|
-
$gitRoot = (& git -C $RepoPath rev-parse --show-toplevel 2>$null).Trim()
|
|
40
|
-
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($gitRoot)) { throw "RepoPath must be a Git repository." }
|
|
41
|
-
$gitRoot = [System.IO.Path]::GetFullPath($gitRoot)
|
|
42
|
-
|
|
43
|
-
$binaryExt = @('.png','.jpg','.jpeg','.gif','.ico','.bmp','.woff','.woff2','.ttf','.otf','.node')
|
|
44
|
-
$managedRoots = @('.opencode', 'tera-system', 'tera-workshop')
|
|
45
|
-
|
|
46
|
-
$tracked = @(& git -C $RepoPath ls-files)
|
|
47
|
-
$targets = @()
|
|
48
|
-
foreach ($file in $tracked) {
|
|
49
|
-
$isManaged = $false
|
|
50
|
-
foreach ($root in $managedRoots) {
|
|
51
|
-
if ($file -eq $root -or $file.StartsWith($root + '/')) { $isManaged = $true; break }
|
|
52
|
-
}
|
|
53
|
-
if (-not $isManaged) { continue }
|
|
54
|
-
$ext = [System.IO.Path]::GetExtension($file).ToLowerInvariant()
|
|
55
|
-
if ($binaryExt -contains $ext) { continue }
|
|
56
|
-
$full = Join-Path $gitRoot ($file -replace '/', '\')
|
|
57
|
-
if (-not (Test-Path -LiteralPath $full)) { continue }
|
|
58
|
-
$targets += $file
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
$changed = @()
|
|
62
|
-
foreach ($file in $targets) {
|
|
63
|
-
$full = Join-Path $gitRoot ($file -replace '/', '\')
|
|
64
|
-
$raw = [System.IO.File]::ReadAllText($full)
|
|
65
|
-
$hasTrailing = Test-TrailingWhitespace $raw
|
|
66
|
-
$hasExtraBlank = Test-ExtraBlankAtEof $raw
|
|
67
|
-
if (-not ($hasTrailing -or $hasExtraBlank)) { continue }
|
|
68
|
-
|
|
69
|
-
if ($DryRun) {
|
|
70
|
-
$changed += [pscustomobject]@{ File = $file; Trailing = $hasTrailing; ExtraBlank = $hasExtraBlank }
|
|
71
|
-
continue
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
$eol = Get-LineEnding $raw
|
|
75
|
-
$lines = $raw -split '\r?\n'
|
|
76
|
-
$clean = @()
|
|
77
|
-
foreach ($ln in $lines) { $clean += $ln -replace '[ \t]+$', '' }
|
|
78
|
-
# remove trailing empty lines but keep exactly one final line terminator
|
|
79
|
-
while ($clean.Count -gt 1 -and $clean[$clean.Count - 1].Trim() -eq '') {
|
|
80
|
-
$clean = $clean[0..($clean.Count - 2)]
|
|
81
|
-
}
|
|
82
|
-
$newText = ($clean -join $eol) + $eol
|
|
83
|
-
if ($newText -ne $raw) {
|
|
84
|
-
[System.IO.File]::WriteAllText($full, $newText, (New-Object System.Text.UTF8Encoding $false))
|
|
85
|
-
$changed += [pscustomobject]@{ File = $file; Trailing = $hasTrailing; ExtraBlank = $hasExtraBlank }
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if ($DryRun) {
|
|
90
|
-
Write-Host "Tera Clean [DRY RUN] - files that would be changed: $($changed.Count)"
|
|
91
|
-
$changed | ForEach-Object { Write-Host (" {0} (trailing={1}, extraBlank={2})" -f $_.File, $_.Trailing, $_.ExtraBlank) }
|
|
92
|
-
Write-Host "Run without -DryRun to apply."
|
|
93
|
-
} else {
|
|
94
|
-
Write-Host "Tera Clean - changed files: $($changed.Count)"
|
|
95
|
-
$changed | ForEach-Object { Write-Host (" {0}" -f $_.File) }
|
|
96
|
-
Write-Host "Next: git add -A && git diff --cached --check"
|
|
97
|
-
}
|
package/tools/tera-fetch.ps1
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
<#
|
|
2
|
-
Tera Fetch — fetch release metadata, check for updates, or build a verified
|
|
3
|
-
release package from the origin repository.
|
|
4
|
-
Modes:
|
|
5
|
-
-List : list available version tags from the origin repository
|
|
6
|
-
-Check : compare installed version (lock.json) with latest from origin
|
|
7
|
-
-Fetch : create a verified release package (Manifest + SHA256SUMS)
|
|
8
|
-
from the exact tag via tera-release.ps1
|
|
9
|
-
Source of truth: tera-system/TERA_DISTRIBUTION_POLICY.md (SCP-2026-08-15-009, 012)
|
|
10
|
-
#>
|
|
11
|
-
[CmdletBinding()]
|
|
12
|
-
param(
|
|
13
|
-
[Parameter(Mandatory = $true)]
|
|
14
|
-
[string]$RepositoryUrl,
|
|
15
|
-
|
|
16
|
-
[switch]$List,
|
|
17
|
-
|
|
18
|
-
[switch]$Check,
|
|
19
|
-
|
|
20
|
-
[string]$Version,
|
|
21
|
-
|
|
22
|
-
[string]$OutPath,
|
|
23
|
-
|
|
24
|
-
[string]$RepoPath = (Get-Location).Path,
|
|
25
|
-
|
|
26
|
-
[ValidateSet('stable', 'beta')]
|
|
27
|
-
[string]$Channel = 'stable',
|
|
28
|
-
|
|
29
|
-
[string]$CachePath
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
Set-StrictMode -Version 5
|
|
33
|
-
# Continue وليس Stop: هذا السكربت يعتمد على فحوص $LASTEXITCODE الصريحة بعد كل
|
|
34
|
-
# استدعاء git، و stderr الطبيعي لـ git (مثل رسائل التقدم) يجب ألا يوقف التنفيذ.
|
|
35
|
-
$ErrorActionPreference = 'Continue'
|
|
36
|
-
|
|
37
|
-
function Fail([string]$Message) {
|
|
38
|
-
throw $Message
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
# مقارنة إصدارات رقمية X.Y.Z — ترجع 1 إذا a أحدث، -1 إذا b أحدث، 0 إذا متساويان
|
|
42
|
-
function Compare-TeraVersion([string]$a, [string]$b) {
|
|
43
|
-
$aParts = ($a -replace '^tera-v', '').Split('.')
|
|
44
|
-
$bParts = ($b -replace '^tera-v', '').Split('.')
|
|
45
|
-
for ($i = 0; $i -lt [Math]::Max($aParts.Count, $bParts.Count); $i++) {
|
|
46
|
-
$pa = 0; $pb = 0
|
|
47
|
-
if ($i -lt $aParts.Count) { [void][int]::TryParse($aParts[$i], [ref]$pa) }
|
|
48
|
-
if ($i -lt $bParts.Count) { [void][int]::TryParse($bParts[$i], [ref]$pb) }
|
|
49
|
-
if ($pa -gt $pb) { return 1 }
|
|
50
|
-
if ($pa -lt $pb) { return -1 }
|
|
51
|
-
}
|
|
52
|
-
return 0
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
# جلب قائمة إصدارات tera-vX.Y.Z من الأصل (مشترك بين List و Check)
|
|
56
|
-
function Get-OriginVersions([string]$Url) {
|
|
57
|
-
$lines = @(& git ls-remote --tags $Url 2>$null)
|
|
58
|
-
if ($LASTEXITCODE -ne 0) { Fail "Could not reach origin repository: $Url" }
|
|
59
|
-
$versions = New-Object System.Collections.Generic.List[string]
|
|
60
|
-
foreach ($line in $lines) {
|
|
61
|
-
if ($line -match 'refs/tags/(tera-v[0-9]+\.[0-9]+\.[0-9]+)(\^\{\})?$') {
|
|
62
|
-
$versions.Add($matches[1])
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
$sorted = @($versions | Sort-Object -Unique)
|
|
66
|
-
return , $sorted
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
#---------------------------------------------------------------------
|
|
70
|
-
# 1. List mode — عرض الإصدارات المتاحة من المستودع الأصلي
|
|
71
|
-
#---------------------------------------------------------------------
|
|
72
|
-
if ($List) {
|
|
73
|
-
$versions = Get-OriginVersions $RepositoryUrl
|
|
74
|
-
if ($versions.Count -eq 0) {
|
|
75
|
-
Write-Host "No tera-vX.Y.Z tags found in: $RepositoryUrl"
|
|
76
|
-
} else {
|
|
77
|
-
Write-Host "Available Tera versions (from origin):"
|
|
78
|
-
$versions | ForEach-Object { Write-Host " $_" }
|
|
79
|
-
}
|
|
80
|
-
return
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
#---------------------------------------------------------------------
|
|
84
|
-
# 2. Check mode — هل يوجد إصدار أحدث من المثبت؟
|
|
85
|
-
#---------------------------------------------------------------------
|
|
86
|
-
if ($Check) {
|
|
87
|
-
$versions = Get-OriginVersions $RepositoryUrl
|
|
88
|
-
if ($versions.Count -eq 0) {
|
|
89
|
-
Write-Host "No tera-vX.Y.Z tags found in: $RepositoryUrl"
|
|
90
|
-
return
|
|
91
|
-
}
|
|
92
|
-
$latest = $versions[-1]
|
|
93
|
-
|
|
94
|
-
$lockPath = Join-Path $RepoPath '.tera\lock.json'
|
|
95
|
-
$installed = $null
|
|
96
|
-
if (Test-Path -LiteralPath $lockPath) {
|
|
97
|
-
try {
|
|
98
|
-
$lock = Get-Content -LiteralPath $lockPath -Raw | ConvertFrom-Json
|
|
99
|
-
if ($lock.tag) { $installed = [string]$lock.tag }
|
|
100
|
-
} catch {
|
|
101
|
-
Write-Warning "lock.json unreadable at $lockPath — treating as no installation."
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (-not $installed) {
|
|
106
|
-
Write-Host "No prior installation detected in $RepoPath."
|
|
107
|
-
Write-Host "Latest available: $latest"
|
|
108
|
-
Write-Host "Install with: tera-update.ps1 -Version $latest -Mode Apply -Initialize -RepositoryUrl `"$RepositoryUrl`""
|
|
109
|
-
return
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
$cmp = Compare-TeraVersion $installed $latest
|
|
113
|
-
if ($cmp -ge 0) {
|
|
114
|
-
Write-Host "You are up to date: $installed (latest in origin: $latest)"
|
|
115
|
-
} else {
|
|
116
|
-
Write-Host "Update available!"
|
|
117
|
-
Write-Host " Installed: $installed"
|
|
118
|
-
Write-Host " Latest: $latest"
|
|
119
|
-
Write-Host "Upgrade with: tera-update.ps1 -Version $latest -Mode Apply -RepositoryUrl `"$RepositoryUrl`""
|
|
120
|
-
}
|
|
121
|
-
return
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
#---------------------------------------------------------------------
|
|
125
|
-
# 3. Fetch mode — بناء حزمة إصدار موثقة من المستودع الأصلي
|
|
126
|
-
#---------------------------------------------------------------------
|
|
127
|
-
if (-not $Version) { Fail 'Fetch mode requires -Version (e.g. tera-v2.5.0).' }
|
|
128
|
-
if (-not $OutPath) { Fail 'Fetch mode requires -OutPath.' }
|
|
129
|
-
|
|
130
|
-
if (-not $CachePath) {
|
|
131
|
-
$CachePath = Join-Path $env:LOCALAPPDATA 'Tera\release-cache'
|
|
132
|
-
}
|
|
133
|
-
New-Item -ItemType Directory -Path $CachePath -Force | Out-Null
|
|
134
|
-
|
|
135
|
-
# إنشاء استنساخ موقت (shallow) عند الـ Tag المطلوب من المستودع الأصلي
|
|
136
|
-
$tempCheckout = Join-Path $CachePath ("checkout-" + [guid]::NewGuid().ToString('N'))
|
|
137
|
-
try {
|
|
138
|
-
$null = & git init $tempCheckout 2>$null
|
|
139
|
-
if ($LASTEXITCODE -ne 0) { Fail "Could not initialize temp checkout." }
|
|
140
|
-
$null = & git -C $tempCheckout remote add origin $RepositoryUrl 2>$null
|
|
141
|
-
if ($LASTEXITCODE -ne 0) { Fail "Could not add origin remote: $RepositoryUrl" }
|
|
142
|
-
$refspec = ('refs/tags/{0}:refs/tags/{0}' -f $Version)
|
|
143
|
-
$null = & git -C $tempCheckout fetch --depth 1 origin $refspec 2>$null
|
|
144
|
-
if ($LASTEXITCODE -ne 0) { Fail "Could not fetch tag $Version from origin." }
|
|
145
|
-
$null = & git -C $tempCheckout checkout --quiet $Version 2>$null
|
|
146
|
-
if ($LASTEXITCODE -ne 0) { Fail "Could not checkout tag $Version." }
|
|
147
|
-
|
|
148
|
-
$commit = (& git -C $tempCheckout rev-list -n 1 $Version 2>$null).Trim()
|
|
149
|
-
if ($commit -notmatch '^[0-9a-fA-F]{40}$') { Fail "Could not resolve commit for $Version." }
|
|
150
|
-
|
|
151
|
-
Write-Host "Fetched $Version from origin (commit $commit)."
|
|
152
|
-
Write-Host "Building verified release package via tera-release.ps1 ..."
|
|
153
|
-
|
|
154
|
-
$releaseBuilder = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Path) 'tera-release.ps1'
|
|
155
|
-
& $releaseBuilder -Version $Version -Tag $Version -Channel $Channel -RepoPath $tempCheckout -OutputPath $OutPath
|
|
156
|
-
if ($LASTEXITCODE -ne 0) { Fail "tera-release.ps1 failed for $Version." }
|
|
157
|
-
|
|
158
|
-
Write-Host "Fetched and built verified package: $OutPath"
|
|
159
|
-
Write-Host "Next: run tera-update.ps1 -SourcePath $OutPath"
|
|
160
|
-
}
|
|
161
|
-
finally {
|
|
162
|
-
if (Test-Path -LiteralPath $tempCheckout) {
|
|
163
|
-
Remove-Item -LiteralPath $tempCheckout -Recurse -Force -ErrorAction SilentlyContinue
|
|
164
|
-
}
|
|
165
|
-
}
|
package/tools/tera-release.ps1
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
<#
|
|
2
|
-
Build a deterministic Tera release directory from the exact Git tag.
|
|
3
|
-
The working tree is never used as the release content.
|
|
4
|
-
#>
|
|
5
|
-
[CmdletBinding()]
|
|
6
|
-
param(
|
|
7
|
-
[Parameter(Mandatory = $true)]
|
|
8
|
-
[string]$Version,
|
|
9
|
-
|
|
10
|
-
[string]$Tag,
|
|
11
|
-
|
|
12
|
-
[ValidateSet('stable', 'beta')]
|
|
13
|
-
[string]$Channel = 'stable',
|
|
14
|
-
|
|
15
|
-
[Parameter(Mandatory = $true)]
|
|
16
|
-
[string]$OutputPath,
|
|
17
|
-
|
|
18
|
-
[string]$RepoPath = (Get-Location).Path
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
Set-StrictMode -Version 5
|
|
22
|
-
$ErrorActionPreference = 'Stop'
|
|
23
|
-
|
|
24
|
-
if (-not $Tag) { $Tag = "tera-v$Version" }
|
|
25
|
-
$RepoPath = [System.IO.Path]::GetFullPath($RepoPath)
|
|
26
|
-
$OutputPath = [System.IO.Path]::GetFullPath($OutputPath)
|
|
27
|
-
if (-not (Test-Path -LiteralPath $RepoPath -PathType Container)) { throw "RepoPath not found: $RepoPath" }
|
|
28
|
-
$top = (git -C $RepoPath rev-parse --show-toplevel 2>$null).Trim()
|
|
29
|
-
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($top)) { throw 'RepoPath must be a Git repository.' }
|
|
30
|
-
$commit = (git -C $RepoPath rev-list -n 1 "$Tag^{commit}" 2>$null).Trim()
|
|
31
|
-
if ($LASTEXITCODE -ne 0 -or $commit -notmatch '^[0-9a-fA-F]{40}$') { throw "Tag does not resolve to a full commit: $Tag" }
|
|
32
|
-
$normalizedVersion = ($Version -replace '^tera-', '') -replace '^v', ''
|
|
33
|
-
|
|
34
|
-
# التحقق من اتساق Version مع Tag — رفض الحزم المتناقضة
|
|
35
|
-
$expectedTag = "tera-v$normalizedVersion"
|
|
36
|
-
if ($Tag -ne $expectedTag) {
|
|
37
|
-
throw "Tag $Tag does not match Version $Version (expected $expectedTag)."
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (Test-Path -LiteralPath $OutputPath) {
|
|
41
|
-
$children = @(Get-ChildItem -LiteralPath $OutputPath -Force)
|
|
42
|
-
if ($children.Count -gt 0) { throw "OutputPath must be empty: $OutputPath" }
|
|
43
|
-
} else {
|
|
44
|
-
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
$tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("tera-release-" + [guid]::NewGuid().ToString('N'))
|
|
48
|
-
$archivePath = Join-Path $tempRoot 'tag.zip'
|
|
49
|
-
$snapshotRoot = Join-Path $tempRoot 'snapshot'
|
|
50
|
-
$managedRoots = @('.opencode', 'tera-system', 'tera-workshop')
|
|
51
|
-
$files = New-Object System.Collections.Generic.List[string]
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
New-Item -ItemType Directory -Path $tempRoot -Force | Out-Null
|
|
55
|
-
$null = & git -C $RepoPath archive --format=zip "--output=$archivePath" $Tag 2>$null
|
|
56
|
-
if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $archivePath -PathType Leaf)) {
|
|
57
|
-
throw "Could not archive exact Git tag: $Tag"
|
|
58
|
-
}
|
|
59
|
-
Expand-Archive -LiteralPath $archivePath -DestinationPath $snapshotRoot -Force
|
|
60
|
-
|
|
61
|
-
foreach ($root in $managedRoots) {
|
|
62
|
-
$sourceRoot = Join-Path $snapshotRoot $root
|
|
63
|
-
if (-not (Test-Path -LiteralPath $sourceRoot -PathType Container)) { continue }
|
|
64
|
-
foreach ($file in Get-ChildItem -LiteralPath $sourceRoot -File -Recurse) {
|
|
65
|
-
$relative = ($file.FullName.Substring($snapshotRoot.Length + 1) -replace '\\', '/')
|
|
66
|
-
$target = Join-Path $OutputPath $relative
|
|
67
|
-
$targetDir = Split-Path -Parent $target
|
|
68
|
-
if (-not (Test-Path -LiteralPath $targetDir)) { New-Item -ItemType Directory -Path $targetDir -Force | Out-Null }
|
|
69
|
-
Copy-Item -LiteralPath $file.FullName -Destination $target -Force
|
|
70
|
-
$files.Add($relative)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if ($files.Count -eq 0) { throw 'No managed files found in the tagged snapshot.' }
|
|
74
|
-
|
|
75
|
-
$manifest = [ordered]@{
|
|
76
|
-
version = $normalizedVersion
|
|
77
|
-
tag = $Tag
|
|
78
|
-
commit = $commit
|
|
79
|
-
channel = $Channel
|
|
80
|
-
files = @($files | Sort-Object)
|
|
81
|
-
}
|
|
82
|
-
$manifest | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $OutputPath 'TERA_RELEASE_MANIFEST.json') -Encoding UTF8
|
|
83
|
-
|
|
84
|
-
$sumLines = New-Object System.Collections.Generic.List[string]
|
|
85
|
-
foreach ($relative in ($files | Sort-Object)) {
|
|
86
|
-
$hash = (Get-FileHash -LiteralPath (Join-Path $OutputPath $relative) -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
87
|
-
$sumLines.Add("$hash $relative")
|
|
88
|
-
}
|
|
89
|
-
$sumLines | Set-Content -LiteralPath (Join-Path $OutputPath 'SHA256SUMS') -Encoding ASCII
|
|
90
|
-
}
|
|
91
|
-
finally {
|
|
92
|
-
if (Test-Path -LiteralPath $tempRoot) { Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue }
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
Write-Host "Release created from exact tag: $OutputPath"
|
|
96
|
-
Write-Host "Tag=$Tag Commit=$commit Channel=$Channel Files=$($files.Count)"
|
package/tools/tera-schedule.ps1
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
<#
|
|
2
|
-
Tera Schedule — register or remove the automatic update check task.
|
|
3
|
-
Registers a Windows Task Scheduler task (TeraUpdateCheck) that runs
|
|
4
|
-
tera-watch.ps1 -Once at logon and every -IntervalHours hours.
|
|
5
|
-
|
|
6
|
-
Usage:
|
|
7
|
-
tera-schedule.ps1 -RepositoryUrl "https://github.com/Alabasi1980/TeraSystem.git" -RepoPath "D:\My Projects\TeraWebsite"
|
|
8
|
-
tera-schedule.ps1 -Unregister
|
|
9
|
-
|
|
10
|
-
Source of truth: tera-system/TERA_DISTRIBUTION_POLICY.md (SCP-2026-08-15-013)
|
|
11
|
-
#>
|
|
12
|
-
[CmdletBinding()]
|
|
13
|
-
param(
|
|
14
|
-
[string]$RepositoryUrl,
|
|
15
|
-
|
|
16
|
-
[string]$RepoPath = (Get-Location).Path,
|
|
17
|
-
|
|
18
|
-
[int]$IntervalHours = 6,
|
|
19
|
-
|
|
20
|
-
[switch]$Unregister
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
Set-StrictMode -Version 5
|
|
24
|
-
$ErrorActionPreference = 'Stop'
|
|
25
|
-
|
|
26
|
-
$taskName = 'TeraUpdateCheck'
|
|
27
|
-
$watchScript = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Path) 'tera-watch.ps1'
|
|
28
|
-
|
|
29
|
-
if (-not (Test-Path -LiteralPath $watchScript -PathType Leaf)) {
|
|
30
|
-
throw "tera-watch.ps1 not found: $watchScript"
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if ($Unregister) {
|
|
34
|
-
if (Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue) {
|
|
35
|
-
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
|
|
36
|
-
Write-Host "Removed scheduled task: $taskName"
|
|
37
|
-
} else {
|
|
38
|
-
Write-Host "No scheduled task named $taskName to remove."
|
|
39
|
-
}
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (-not $RepositoryUrl) { throw '-RepositoryUrl is required to register the task.' }
|
|
44
|
-
if (-not (Test-Path -LiteralPath $RepoPath -PathType Container)) { throw "RepoPath does not exist: $RepoPath" }
|
|
45
|
-
|
|
46
|
-
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument ('-NoProfile -ExecutionPolicy Bypass -File "{0}" -Once -RepositoryUrl "{1}" -RepoPath "{2}"' -f $watchScript, $RepositoryUrl, $RepoPath)
|
|
47
|
-
|
|
48
|
-
$triggerLogon = New-ScheduledTaskTrigger -AtLogOn
|
|
49
|
-
$triggerInterval = New-ScheduledTaskTrigger -Once -At (Get-Date).Date.AddHours(1) -RepetitionInterval (New-TimeSpan -Hours $IntervalHours)
|
|
50
|
-
|
|
51
|
-
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
|
|
52
|
-
|
|
53
|
-
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $triggerLogon, $triggerInterval -Settings $settings -Description 'Tera update availability check' -Force | Out-Null
|
|
54
|
-
|
|
55
|
-
Write-Host "Registered scheduled task: $taskName"
|
|
56
|
-
Write-Host " Watches: $RepositoryUrl"
|
|
57
|
-
Write-Host " Repo: $RepoPath"
|
|
58
|
-
Write-Host " Every: $IntervalHours hour(s) + at logon"
|
|
59
|
-
Write-Host "Remove with: tera-schedule.ps1 -Unregister"
|