atris 2.6.2 → 3.0.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/README.md +124 -34
- package/atris/CLAUDE.md +5 -1
- package/atris/atris.md +4 -0
- package/atris/features/README.md +24 -0
- package/atris/skills/autopilot/SKILL.md +74 -75
- package/atris/skills/endgame/SKILL.md +179 -0
- package/atris/skills/flow/SKILL.md +121 -0
- package/atris/skills/improve/SKILL.md +84 -0
- package/atris/skills/loop/SKILL.md +72 -0
- package/atris/skills/wiki/SKILL.md +61 -0
- package/atris/team/executor/MEMBER.md +10 -4
- package/atris/team/navigator/MEMBER.md +2 -0
- package/atris/team/validator/MEMBER.md +8 -5
- package/atris.md +33 -0
- package/bin/atris.js +210 -41
- package/commands/activate.js +28 -2
- package/commands/align.js +720 -0
- package/commands/auth.js +75 -2
- package/commands/autopilot.js +1213 -270
- package/commands/browse.js +100 -0
- package/commands/business.js +785 -12
- package/commands/clean.js +107 -2
- package/commands/computer.js +429 -0
- package/commands/context-sync.js +78 -8
- package/commands/experiments.js +351 -0
- package/commands/feedback.js +150 -0
- package/commands/fleet.js +395 -0
- package/commands/fork.js +127 -0
- package/commands/init.js +50 -1
- package/commands/learn.js +407 -0
- package/commands/lifecycle.js +94 -0
- package/commands/loop.js +114 -0
- package/commands/publish.js +129 -0
- package/commands/pull.js +434 -48
- package/commands/push.js +312 -164
- package/commands/review.js +149 -0
- package/commands/run.js +76 -43
- package/commands/serve.js +360 -0
- package/commands/setup.js +1 -1
- package/commands/soul.js +381 -0
- package/commands/status.js +119 -1
- package/commands/sync.js +147 -1
- package/commands/terminal.js +201 -0
- package/commands/wiki.js +376 -0
- package/commands/workflow.js +191 -74
- package/commands/workspace-clean.js +3 -3
- package/lib/endstate.js +259 -0
- package/lib/learnings.js +235 -0
- package/lib/manifest.js +1 -0
- package/lib/todo.js +9 -5
- package/lib/wiki.js +578 -0
- package/package.json +2 -2
- package/utils/api.js +48 -36
- package/utils/auth.js +1 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const { loadCredentials } = require('../utils/auth');
|
|
5
|
+
const { apiRequestJson } = require('../utils/api');
|
|
6
|
+
|
|
7
|
+
async function publishAtris() {
|
|
8
|
+
if (process.argv[3] === '--help') {
|
|
9
|
+
console.log('Usage: atris publish [--name <name>] [--description <desc>]');
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log(' atris publish Publish current workspace as a template');
|
|
12
|
+
console.log(' atris publish --name "CRM Starter" Publish with a specific name');
|
|
13
|
+
console.log(' atris publish --name crm --description "Sales CRM template"');
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const creds = loadCredentials();
|
|
18
|
+
if (!creds || !creds.token) {
|
|
19
|
+
console.error('Not logged in. Run: atris login');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Parse --name
|
|
24
|
+
let name = null;
|
|
25
|
+
const nameEq = process.argv.find(a => a.startsWith('--name='));
|
|
26
|
+
if (nameEq) { name = nameEq.slice(7); }
|
|
27
|
+
else {
|
|
28
|
+
const ni = process.argv.indexOf('--name');
|
|
29
|
+
if (ni !== -1 && process.argv[ni + 1] && !process.argv[ni + 1].startsWith('-')) name = process.argv[ni + 1];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Parse --description
|
|
33
|
+
let description = null;
|
|
34
|
+
const descEq = process.argv.find(a => a.startsWith('--description='));
|
|
35
|
+
if (descEq) { description = descEq.slice(14); }
|
|
36
|
+
else {
|
|
37
|
+
const di = process.argv.indexOf('--description');
|
|
38
|
+
if (di !== -1 && process.argv[di + 1] && !process.argv[di + 1].startsWith('-')) description = process.argv[di + 1];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Resolve name from .atris/business.json or directory name
|
|
42
|
+
if (!name) {
|
|
43
|
+
const bizFile = path.join(process.cwd(), '.atris', 'business.json');
|
|
44
|
+
if (fs.existsSync(bizFile)) {
|
|
45
|
+
try {
|
|
46
|
+
const biz = JSON.parse(fs.readFileSync(bizFile, 'utf8'));
|
|
47
|
+
name = biz.name || biz.slug;
|
|
48
|
+
} catch {}
|
|
49
|
+
}
|
|
50
|
+
if (!name) name = path.basename(process.cwd());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Collect files from atris/ directory
|
|
54
|
+
const atrisDir = path.join(process.cwd(), 'atris');
|
|
55
|
+
if (!fs.existsSync(atrisDir)) {
|
|
56
|
+
console.error('No atris/ directory found. Run from a workspace root.');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const EXCLUDE = ['logs', '.env', 'secrets'];
|
|
61
|
+
const files = [];
|
|
62
|
+
|
|
63
|
+
function collectFiles(dir, prefix) {
|
|
64
|
+
const entries = fs.readdirSync(dir);
|
|
65
|
+
for (const entry of entries) {
|
|
66
|
+
if (EXCLUDE.includes(entry)) continue;
|
|
67
|
+
if (entry.startsWith('.env') || entry === 'secrets') continue;
|
|
68
|
+
const full = path.join(dir, entry);
|
|
69
|
+
const rel = prefix ? `${prefix}/${entry}` : entry;
|
|
70
|
+
const stat = fs.statSync(full);
|
|
71
|
+
if (stat.isDirectory()) {
|
|
72
|
+
collectFiles(full, rel);
|
|
73
|
+
} else if (stat.isFile() && stat.size < 512 * 1024) {
|
|
74
|
+
try {
|
|
75
|
+
const content = fs.readFileSync(full, 'utf8');
|
|
76
|
+
files.push({ path: `/${rel}`, content });
|
|
77
|
+
} catch {}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
collectFiles(atrisDir, '');
|
|
83
|
+
|
|
84
|
+
if (files.length === 0) {
|
|
85
|
+
console.error('No publishable files found in atris/.');
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log('');
|
|
90
|
+
console.log(`Publishing "${name}" (${files.length} files)...`);
|
|
91
|
+
|
|
92
|
+
// POST to API
|
|
93
|
+
const body = { name, description: description || '', files };
|
|
94
|
+
const result = await apiRequestJson('/workspace/templates', {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
token: creds.token,
|
|
97
|
+
body,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
if (!result.ok) {
|
|
101
|
+
console.error(`\n Publish failed: ${result.errorMessage || result.error || result.status}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Save local copy
|
|
106
|
+
const localDir = path.join(os.homedir(), '.atris', 'templates', name.toLowerCase().replace(/[^a-z0-9-]/g, '-'));
|
|
107
|
+
fs.mkdirSync(localDir, { recursive: true });
|
|
108
|
+
|
|
109
|
+
for (const f of files) {
|
|
110
|
+
const filePath = path.join(localDir, f.path.replace(/^\//, ''));
|
|
111
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
112
|
+
fs.writeFileSync(filePath, f.content);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Save metadata
|
|
116
|
+
fs.writeFileSync(path.join(localDir, 'template.json'), JSON.stringify({
|
|
117
|
+
name,
|
|
118
|
+
description: description || '',
|
|
119
|
+
file_count: files.length,
|
|
120
|
+
published_at: new Date().toISOString(),
|
|
121
|
+
}, null, 2));
|
|
122
|
+
|
|
123
|
+
console.log('');
|
|
124
|
+
console.log(` Published as '${name}'. Others can fork with: atris fork ${name}`);
|
|
125
|
+
console.log(` Local copy saved to ${localDir}`);
|
|
126
|
+
console.log('');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = { publishAtris };
|