atris 3.74.0 → 3.74.2
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/bin/atris.js +85 -82
- package/commands/aeo.js +2 -2
- package/commands/align.js +10 -19
- package/commands/auth.js +1 -1
- package/commands/autopilot.js +9 -10
- package/commands/avail.js +36 -7
- package/commands/clean.js +2 -1
- package/commands/close.js +7 -4
- package/commands/computer.js +3 -1
- package/commands/console.js +1 -1
- package/commands/context-sync.js +1 -60
- package/commands/experiments.js +4 -1
- package/commands/fleet.js +0 -1
- package/commands/improve.js +3 -1
- package/commands/interview.js +13 -5
- package/commands/land.js +5 -1
- package/commands/lifecycle.js +17 -6
- package/commands/log-sync.js +1 -1
- package/commands/loops.js +5 -2
- package/commands/member.js +17 -11
- package/commands/mission.js +1 -4
- package/commands/now.js +0 -7
- package/commands/play.js +3 -1
- package/commands/plugin.js +1 -1
- package/commands/pull.js +5 -3
- package/commands/push.js +0 -1
- package/commands/radar.js +0 -4
- package/commands/recap.js +25 -1
- package/commands/report.js +0 -4
- package/commands/review.js +1 -1
- package/commands/security-review.js +4 -1
- package/commands/setup.js +6 -2
- package/commands/soul.js +2 -1
- package/commands/sync.js +8 -2
- package/commands/task.js +0 -522
- package/commands/terminal.js +1 -1
- package/commands/x-search.js +5 -3
- package/commands/youtube.js +9 -7
- package/commands/zen.js +4 -4
- package/lib/agent-today.js +412 -0
- package/lib/apply-gate.js +5 -3
- package/lib/autoland.js +0 -8
- package/lib/bench/runner.js +0 -4
- package/lib/chat-log-scan.js +0 -28
- package/lib/cli-scope.js +4 -2
- package/lib/engine-registry.js +0 -4
- package/lib/experiments/daily.js +2 -1
- package/lib/file-ops.js +6 -1
- package/lib/first-minute.js +2 -0
- package/lib/gm-bet.js +73 -9
- package/lib/gm-phone-page.js +42 -5
- package/lib/gm-phone.js +3 -0
- package/lib/local-day.js +10 -0
- package/lib/manifest.js +0 -10
- package/lib/member-switches.js +0 -11
- package/lib/review-integrity.js +0 -4
- package/lib/scorecard.js +7 -6
- package/lib/wiki.js +4 -1
- package/package.json +1 -1
package/commands/play.js
CHANGED
|
@@ -6,6 +6,7 @@ const fs = require('fs');
|
|
|
6
6
|
const { spawnSync } = require('child_process');
|
|
7
7
|
const { getSessionProfile, loadCredentials } = require('../utils/auth');
|
|
8
8
|
const { hasFlag: hasExactFlag } = require('../lib/arg-parser');
|
|
9
|
+
const { localDay } = require('../lib/local-day');
|
|
9
10
|
|
|
10
11
|
const AGENTXP_LEADERBOARD_URL = 'https://api.atris.ai/api/agentxp/leaderboard';
|
|
11
12
|
const AGENTXP_GLOBAL_SYNC_RULE = 'Run atris login, then sync. Owner-provided sync tokens are guided-demo fallback only.';
|
|
@@ -298,7 +299,7 @@ function ensureStarterMission(taskDb, db, workspaceRoot, player, tasks, args = [
|
|
|
298
299
|
assigned_to: player,
|
|
299
300
|
delegate_via: 'agentxp_play',
|
|
300
301
|
auto_seeded_by: 'atris play',
|
|
301
|
-
created_for_day:
|
|
302
|
+
created_for_day: localDay(),
|
|
302
303
|
},
|
|
303
304
|
});
|
|
304
305
|
taskDb.noteTask(db, {
|
|
@@ -487,4 +488,5 @@ async function playCommand(...args) {
|
|
|
487
488
|
|
|
488
489
|
module.exports = {
|
|
489
490
|
playCommand,
|
|
491
|
+
ensureStarterMission,
|
|
490
492
|
};
|
package/commands/plugin.js
CHANGED
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const os = require('os');
|
|
4
4
|
const { execSync } = require('child_process');
|
|
5
|
-
const { findAllSkills
|
|
5
|
+
const { findAllSkills } = require('./skill');
|
|
6
6
|
|
|
7
7
|
// --- Recursive Copy Helper ---
|
|
8
8
|
|
package/commands/pull.js
CHANGED
|
@@ -7,7 +7,7 @@ const { loadConfig } = require('../utils/config');
|
|
|
7
7
|
const { getLogPath } = require('../lib/file-ops');
|
|
8
8
|
const { parseJournalSections, mergeSections, reconstructJournal } = require('../lib/journal');
|
|
9
9
|
const { loadBusinesses, businessMatchesSlug } = require('./business');
|
|
10
|
-
const { loadManifest, saveManifest,
|
|
10
|
+
const { loadManifest, saveManifest, buildManifest, computeLocalHashes, threeWayCompare, isIgnoredSyncPath } = require('../lib/manifest');
|
|
11
11
|
const { normalizeWikiOnlyPrefix } = require('../lib/wiki');
|
|
12
12
|
const { emitSyncEvent, startTimer } = require('../lib/sync-telemetry');
|
|
13
13
|
const { resolveSafeOutputDir } = require('../lib/workspace-safety');
|
|
@@ -1023,7 +1023,9 @@ async function pullGeneralJournal(token, agentId) {
|
|
|
1023
1023
|
for (let i = 0; i < 3; i++) {
|
|
1024
1024
|
const d = new Date(today);
|
|
1025
1025
|
d.setDate(d.getDate() - i);
|
|
1026
|
-
|
|
1026
|
+
// Local calendar day, the same day log sync files the journal under.
|
|
1027
|
+
// toISOString() is the UTC day, already tomorrow in the evening here.
|
|
1028
|
+
dates.push(`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`);
|
|
1027
1029
|
}
|
|
1028
1030
|
|
|
1029
1031
|
let synced = 0;
|
|
@@ -1118,4 +1120,4 @@ async function pullMemberJournal(token, agentId, memberName, memberDir) {
|
|
|
1118
1120
|
return synced;
|
|
1119
1121
|
}
|
|
1120
1122
|
|
|
1121
|
-
module.exports = { buildPullConflictReviewPacket, mergeSmartPullFiles, normalizePullFilePath, pullAtris };
|
|
1123
|
+
module.exports = { buildPullConflictReviewPacket, mergeSmartPullFiles, normalizePullFilePath, pullAtris, pullGeneralJournal };
|
package/commands/push.js
CHANGED
package/commands/radar.js
CHANGED
|
@@ -685,10 +685,6 @@ function taskBinding(source, scope = null) {
|
|
|
685
685
|
return { task_source: source, task_scope: scope };
|
|
686
686
|
}
|
|
687
687
|
|
|
688
|
-
function taskBindingForProjection(task) {
|
|
689
|
-
return task ? taskBinding('repo_task_projection', 'repo') : taskBinding(null, null);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
688
|
function taskSourceLabel(sources = []) {
|
|
693
689
|
if (sources.includes('member_loop_lock')) return 'member loop lock';
|
|
694
690
|
if (sources.includes('mission_lock')) return 'mission lock';
|
package/commands/recap.js
CHANGED
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
taskCommand,
|
|
14
14
|
} = require('../lib/first-minute');
|
|
15
15
|
const { isRealTestRunnerProof, quoteVerifierCommand } = require('../lib/verifier-quality');
|
|
16
|
+
const { buildAgentToday, renderAgentToday, hasActivity, ranAgent } = require('../lib/agent-today');
|
|
16
17
|
|
|
17
18
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
18
19
|
const DEFAULT_DAYS = 7;
|
|
@@ -38,7 +39,8 @@ function readProjection(root) {
|
|
|
38
39
|
|
|
39
40
|
function loadTasks(root) {
|
|
40
41
|
const taskDb = loadTaskDb();
|
|
41
|
-
|
|
42
|
+
// Reading never creates the db: a first run before any setup writes nothing.
|
|
43
|
+
if (taskDb && fs.existsSync(taskDb.getDbPath())) {
|
|
42
44
|
try {
|
|
43
45
|
const db = taskDb.open();
|
|
44
46
|
const ws = taskDb.workspaceRoot(root);
|
|
@@ -335,11 +337,14 @@ function printRecapHelp() {
|
|
|
335
337
|
atris recap - what got done, in spoken lines
|
|
336
338
|
|
|
337
339
|
atris recap a few spoken lines: waiting for your ok, still being checked
|
|
340
|
+
atris recap today what your ai coding agent did in this folder today
|
|
338
341
|
atris recap --verbose the old report
|
|
339
342
|
atris recap --days 30 widen the window
|
|
340
343
|
atris recap --share paste-ready summary for Slack, email, or a customer
|
|
341
344
|
atris recap --json structured output for agents and dashboards
|
|
342
345
|
|
|
346
|
+
in a folder with no atris setup, recap shows today by default.
|
|
347
|
+
today reads claude code and codex logs on this computer plus git. it sends nothing.
|
|
343
348
|
certified work names atris task accept. uncertified stays still being checked.
|
|
344
349
|
use --verbose or --share for the old report.
|
|
345
350
|
`);
|
|
@@ -351,6 +356,11 @@ function recapAtris(args = []) {
|
|
|
351
356
|
return;
|
|
352
357
|
}
|
|
353
358
|
const cwd = process.cwd();
|
|
359
|
+
if (args[0] === 'today') {
|
|
360
|
+
const today = buildAgentToday({ cwd });
|
|
361
|
+
console.log(args.includes('--json') ? JSON.stringify(today, null, 2) : renderAgentToday(today));
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
354
364
|
const taskDb = loadTaskDb();
|
|
355
365
|
let root = cwd;
|
|
356
366
|
try {
|
|
@@ -370,6 +380,20 @@ function recapAtris(args = []) {
|
|
|
370
380
|
const daysIdx = args.indexOf('--days');
|
|
371
381
|
const days = daysIdx !== -1 ? Number(args[daysIdx + 1]) : DEFAULT_DAYS;
|
|
372
382
|
const data = buildRecapData(root, { days });
|
|
383
|
+
// Before any setup, or when the board has nothing to say, the useful
|
|
384
|
+
// first minute is what your ai agent already did in this folder today.
|
|
385
|
+
const boardQuiet = data.empty
|
|
386
|
+
|| ['shipped', 'waiting', 'checking', 'inProgress'].every((k) => !(data[k] || []).length);
|
|
387
|
+
if (boardQuiet && !args.includes('--verbose') && !args.includes('--full') && !args.includes('--share')) {
|
|
388
|
+
const today = buildAgentToday({ cwd });
|
|
389
|
+
// A brand new folder already names its last commit in the first
|
|
390
|
+
// minute, so commits alone keep that; an ai session here wins.
|
|
391
|
+
const fresh = data.empty && isFreshWorkspace(root) && !inProjectSubdir;
|
|
392
|
+
if (hasActivity(today) && (ranAgent(today) || !fresh)) {
|
|
393
|
+
console.log(args.includes('--json') ? JSON.stringify(today, null, 2) : renderAgentToday(today));
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
373
397
|
if (
|
|
374
398
|
data.empty
|
|
375
399
|
&& isFreshWorkspace(root)
|
package/commands/report.js
CHANGED
|
@@ -110,10 +110,6 @@ function buildDoneTasks(root, cutoff) {
|
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
function buildLandings(root, cutoff) {
|
|
114
|
-
return buildDoneTasks(root, cutoff).filter(task => task.landed);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
113
|
function landingStatusText(task) {
|
|
118
114
|
const status = String(task?.landing_status || 'unchecked').replace(/_/g, ' ');
|
|
119
115
|
const reason = String(task?.landing_reason || '').replace(/_/g, ' ');
|
package/commands/review.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const path = require('path');
|
|
12
|
-
const {
|
|
12
|
+
const { spawnSync } = require('child_process');
|
|
13
13
|
|
|
14
14
|
function findReviewEngine() {
|
|
15
15
|
// Look for review_engine.py in common locations
|
|
@@ -227,7 +227,10 @@ function securityReviewCommand(argv = []) {
|
|
|
227
227
|
// The landing: short, true, decision-ready. What you read after the overnight
|
|
228
228
|
// loop, the opposite of a finding dump.
|
|
229
229
|
function renderLanding(landing, threshold) {
|
|
230
|
-
|
|
230
|
+
// Local calendar day; toISOString is UTC and dates an evening run
|
|
231
|
+
// tomorrow anywhere west of Greenwich.
|
|
232
|
+
const now = new Date();
|
|
233
|
+
const date = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
|
231
234
|
const L = ['', ` ✈ security landing, ${date}`, ''];
|
|
232
235
|
if (landing.cleared) {
|
|
233
236
|
L.push(` CLEARED TO SHIP no unresolved findings at the ${threshold.toUpperCase()} line`);
|
package/commands/setup.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
1
|
const { loadCredentials, promptUser } = require('../utils/auth');
|
|
4
2
|
const { apiRequestJson } = require('../utils/api');
|
|
5
3
|
|
|
@@ -73,6 +71,12 @@ async function setupAtris() {
|
|
|
73
71
|
token: creds.token,
|
|
74
72
|
});
|
|
75
73
|
|
|
74
|
+
if (!result.ok && result.status === 401) {
|
|
75
|
+
console.error('\n Your saved login has expired, so Atris could not list your businesses.');
|
|
76
|
+
console.error(' Run "atris login", then "atris setup" again.');
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
76
80
|
if (!result.ok) {
|
|
77
81
|
console.error(`\n Could not fetch businesses: ${result.error || 'Unknown error'}`);
|
|
78
82
|
console.error(' You can add one later with: atris business add <slug>');
|
package/commands/soul.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
const fs = require('fs');
|
|
14
14
|
const path = require('path');
|
|
15
|
+
const { localDay } = require('../lib/local-day');
|
|
15
16
|
|
|
16
17
|
function findAtrisDir() {
|
|
17
18
|
let dir = process.cwd();
|
|
@@ -272,7 +273,7 @@ function distillSoul(atrisDir) {
|
|
|
272
273
|
|
|
273
274
|
// Append distilled section to persona
|
|
274
275
|
const separator = '\n\n---\n\n';
|
|
275
|
-
const distilledBlock = `<!-- Distilled ${
|
|
276
|
+
const distilledBlock = `<!-- Distilled ${localDay()} | ${journalCount} journal entries, ${lessonItems.length} lessons, ${policyRules.length} policy rules -->\n\n` + distilled.join('\n');
|
|
276
277
|
|
|
277
278
|
if (persona) {
|
|
278
279
|
// Check if already has a distilled section, replace it
|
package/commands/sync.js
CHANGED
|
@@ -43,6 +43,12 @@ function _walkTemplateDir(dir, base = dir) {
|
|
|
43
43
|
return out;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// Local calendar day (YYYY-MM-DD). toISOString() is the UTC day, which is
|
|
47
|
+
// already tomorrow in the evening anywhere west of Greenwich.
|
|
48
|
+
function localDay(date = new Date()) {
|
|
49
|
+
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
46
52
|
/**
|
|
47
53
|
* Substitute workspace metadata in template content.
|
|
48
54
|
*/
|
|
@@ -53,7 +59,7 @@ function _substituteParams(content, params) {
|
|
|
53
59
|
.replace(/\{\{owner_email\}\}/g, params.owner_email || '')
|
|
54
60
|
.replace(/\{\{business_id\}\}/g, params.business_id || '')
|
|
55
61
|
.replace(/\{\{workspace_id\}\}/g, params.workspace_id || '')
|
|
56
|
-
.replace(/\{\{today\}\}/g, params.today ||
|
|
62
|
+
.replace(/\{\{today\}\}/g, params.today || localDay())
|
|
57
63
|
.replace(/\{\{workspace_template\}\}/g, params.workspace_template || 'business');
|
|
58
64
|
}
|
|
59
65
|
|
|
@@ -337,7 +343,7 @@ function syncWorkspaceTemplate(targetRoot, bizMeta, options = {}) {
|
|
|
337
343
|
owner_email: bizMeta.owner_email || '',
|
|
338
344
|
business_id: bizMeta.business_id || '',
|
|
339
345
|
workspace_id: bizMeta.workspace_id || '',
|
|
340
|
-
today:
|
|
346
|
+
today: localDay(),
|
|
341
347
|
workspace_template: template.key,
|
|
342
348
|
};
|
|
343
349
|
const force = options.force != null ? options.force : process.argv.includes('--force');
|