@agent-native/core 0.122.2 → 0.122.4
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/run-loop-with-resume.ts +12 -0
- package/corpus/core/src/cli/index.ts +2 -1
- package/corpus/core/src/cli/mcp.ts +13 -3
- package/corpus/core/src/cli/skills-content/rewind-skill.ts +36 -4
- package/corpus/core/src/cli/skills.ts +250 -37
- package/corpus/core/src/cli/telemetry-routing.ts +57 -0
- package/corpus/core/src/cli/telemetry.ts +3 -3
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +182 -0
- package/corpus/core/src/integrations/a2a-continuations-store.ts +122 -12
- package/corpus/core/src/integrations/integration-campaign-recovery.ts +127 -0
- package/corpus/core/src/integrations/integration-campaigns-store.ts +1039 -0
- package/corpus/core/src/integrations/integration-durable-dispatch.ts +28 -3
- package/corpus/core/src/integrations/pending-tasks-retry-job.ts +8 -0
- package/corpus/core/src/integrations/plugin.ts +453 -35
- package/corpus/core/src/integrations/webhook-handler.ts +469 -11
- package/corpus/core/src/mcp/screen-memory-stdio.ts +21 -2
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +7 -3
- package/corpus/templates/content/app/components/editor/body-hydration.ts +10 -0
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -0
- package/corpus/templates/content/app/root.tsx +12 -1
- package/corpus/templates/content/changelog/2026-07-23-new-pages-open-immediately-while-slow-network-work-continues.md +6 -0
- package/corpus/templates/content/changelog/2026-07-25-database-preview-actions-open-reliably.md +6 -0
- package/corpus/templates/content/e2e/playwright.config.ts +1 -1
- package/dist/agent/run-loop-with-resume.d.ts +7 -1
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +7 -0
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +12 -3
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/skills-content/rewind-skill.d.ts +1 -1
- package/dist/cli/skills-content/rewind-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/rewind-skill.js +36 -4
- package/dist/cli/skills-content/rewind-skill.js.map +1 -1
- package/dist/cli/skills.d.ts +2 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +191 -40
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/telemetry-routing.d.ts +2 -0
- package/dist/cli/telemetry-routing.d.ts.map +1 -0
- package/dist/cli/telemetry-routing.js +54 -0
- package/dist/cli/telemetry-routing.js.map +1 -0
- package/dist/cli/telemetry.js +3 -3
- package/dist/cli/telemetry.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +3 -3
- package/dist/integrations/a2a-continuation-processor.d.ts +14 -0
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +134 -1
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts +23 -0
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +99 -13
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/integration-campaign-recovery.d.ts +16 -0
- package/dist/integrations/integration-campaign-recovery.d.ts.map +1 -0
- package/dist/integrations/integration-campaign-recovery.js +94 -0
- package/dist/integrations/integration-campaign-recovery.js.map +1 -0
- package/dist/integrations/integration-campaigns-store.d.ts +121 -0
- package/dist/integrations/integration-campaigns-store.d.ts.map +1 -0
- package/dist/integrations/integration-campaigns-store.js +784 -0
- package/dist/integrations/integration-campaigns-store.js.map +1 -0
- package/dist/integrations/integration-durable-dispatch.d.ts +3 -0
- package/dist/integrations/integration-durable-dispatch.d.ts.map +1 -1
- package/dist/integrations/integration-durable-dispatch.js +22 -3
- package/dist/integrations/integration-durable-dispatch.js.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +6 -0
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +325 -18
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +16 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +368 -13
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +2 -0
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
- package/dist/mcp/screen-memory-stdio.js +12 -2
- package/dist/mcp/screen-memory-stdio.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
- package/src/agent/run-loop-with-resume.ts +12 -0
- package/src/cli/index.ts +2 -1
- package/src/cli/mcp.ts +13 -3
- package/src/cli/skills-content/rewind-skill.ts +36 -4
- package/src/cli/skills.ts +250 -37
- package/src/cli/telemetry-routing.ts +57 -0
- package/src/cli/telemetry.ts +3 -3
- package/src/integrations/a2a-continuation-processor.ts +182 -0
- package/src/integrations/a2a-continuations-store.ts +122 -12
- package/src/integrations/integration-campaign-recovery.ts +127 -0
- package/src/integrations/integration-campaigns-store.ts +1039 -0
- package/src/integrations/integration-durable-dispatch.ts +28 -3
- package/src/integrations/pending-tasks-retry-job.ts +8 -0
- package/src/integrations/plugin.ts +453 -35
- package/src/integrations/webhook-handler.ts +469 -11
- package/src/mcp/screen-memory-stdio.ts +21 -2
package/src/cli/skills.ts
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
CONTEXT_XRAY_SKILL_MD,
|
|
33
33
|
installLocalContextXray,
|
|
34
34
|
} from "./context-xray-local.js";
|
|
35
|
-
import { CLIENTS, type ClientId } from "./mcp-config-writers.js";
|
|
35
|
+
import { CLIENTS, configPathFor, type ClientId } from "./mcp-config-writers.js";
|
|
36
36
|
import {
|
|
37
37
|
installScreenMemoryForClient,
|
|
38
38
|
resolveScreenMemoryStoreDir,
|
|
@@ -800,6 +800,7 @@ export interface RunSkillsOptions {
|
|
|
800
800
|
* browser/device OAuth round-trip.
|
|
801
801
|
*/
|
|
802
802
|
runConnect?: (args: string[]) => Promise<void>;
|
|
803
|
+
installScreenMemory?: typeof installScreenMemoryForClient;
|
|
803
804
|
/**
|
|
804
805
|
* Best-effort install-funnel telemetry. Created once per `runSkills` run and
|
|
805
806
|
* threaded through resolution/install/connect so each `track` is fire-and-
|
|
@@ -850,6 +851,50 @@ function isKnownSkill(value: string | undefined): boolean {
|
|
|
850
851
|
return Boolean(normalizeKnownSkillTarget(value));
|
|
851
852
|
}
|
|
852
853
|
|
|
854
|
+
function explicitlyTargetsRewind(parsed: ParsedSkillsArgs): boolean {
|
|
855
|
+
return (
|
|
856
|
+
normalizeKnownSkillTarget(parsed.target ?? "assets") === "rewind" ||
|
|
857
|
+
Boolean(
|
|
858
|
+
parsed.plainSkillNames?.some(
|
|
859
|
+
(skillName) => normalizeKnownSkillTarget(skillName) === "rewind",
|
|
860
|
+
),
|
|
861
|
+
)
|
|
862
|
+
);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const REWIND_MISSING_STORE_ERROR =
|
|
866
|
+
"No local Clips Screen Memory store was found. Clips Desktop is required for Rewind. Download and launch the signed app from https://clips.agent-native.com/download, turn Rewind on, then run the setup again. Clips Desktop was not installed or enabled automatically.";
|
|
867
|
+
|
|
868
|
+
function preflightRewindStore(parsed: ParsedSkillsArgs): string | undefined {
|
|
869
|
+
if (parsed.command !== "add" || !explicitlyTargetsRewind(parsed))
|
|
870
|
+
return undefined;
|
|
871
|
+
if (!parsed.mcp) {
|
|
872
|
+
throw new Error(
|
|
873
|
+
"Rewind requires the local Clips Screen Memory MCP and cannot be installed with --no-mcp.",
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
if (parsed.mcpUrl) {
|
|
877
|
+
throw new Error(
|
|
878
|
+
"Rewind uses the local Clips Screen Memory MCP and does not accept --mcp-url.",
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
if (parsed.dryRun) return undefined;
|
|
882
|
+
const screenMemoryDir = resolveScreenMemoryStoreDir();
|
|
883
|
+
if (!screenMemoryDir) throw new Error(REWIND_MISSING_STORE_ERROR);
|
|
884
|
+
return screenMemoryDir;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
function preflightResolvedRewindTargets(
|
|
888
|
+
parsed: ParsedSkillsArgs,
|
|
889
|
+
targets: string[],
|
|
890
|
+
): void {
|
|
891
|
+
preflightRewindStore({
|
|
892
|
+
...parsed,
|
|
893
|
+
target: undefined,
|
|
894
|
+
plainSkillNames: [...(parsed.plainSkillNames ?? []), ...targets],
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
|
|
853
898
|
function isLocalOnlyBuiltInSkill(
|
|
854
899
|
entry: (typeof BUILT_IN_APP_SKILLS)[BuiltInAppSkillId] | null | undefined,
|
|
855
900
|
): boolean {
|
|
@@ -1382,7 +1427,7 @@ $ARGUMENTS
|
|
|
1382
1427
|
* there is no need to shell out to the separate @agent-native/skills installer
|
|
1383
1428
|
* (which would have to be published to npm first). Returns the written folders.
|
|
1384
1429
|
*/
|
|
1385
|
-
|
|
1430
|
+
type BuiltInInstructionInstallInput = {
|
|
1386
1431
|
appSkillId: BuiltInAppSkillId;
|
|
1387
1432
|
onlySkillNames?: string[];
|
|
1388
1433
|
skillsAgents: string[];
|
|
@@ -1391,7 +1436,11 @@ function installBuiltInInstructions(input: {
|
|
|
1391
1436
|
dryRun?: boolean;
|
|
1392
1437
|
planMode?: PlanInstallMode;
|
|
1393
1438
|
mcpUrl?: string;
|
|
1394
|
-
}
|
|
1439
|
+
};
|
|
1440
|
+
|
|
1441
|
+
function builtInInstructionPaths(
|
|
1442
|
+
input: BuiltInInstructionInstallInput,
|
|
1443
|
+
): string[] {
|
|
1395
1444
|
const bundles = Object.values(
|
|
1396
1445
|
skillFilesForBuiltIn(input.appSkillId, {
|
|
1397
1446
|
planMode: input.planMode,
|
|
@@ -1411,15 +1460,10 @@ function installBuiltInInstructions(input: {
|
|
|
1411
1460
|
);
|
|
1412
1461
|
for (const bundle of bundles) {
|
|
1413
1462
|
const dir = path.join(root, bundle.skillName);
|
|
1414
|
-
if (!input.dryRun) writeSkillFolder(dir, bundle);
|
|
1415
1463
|
written.push(dir);
|
|
1416
1464
|
const command = slashCommandForBuiltInSkill(bundle.skillName);
|
|
1417
1465
|
if (command) {
|
|
1418
1466
|
const commandPath = path.join(commandsRoot, `${bundle.skillName}.md`);
|
|
1419
|
-
if (!input.dryRun) {
|
|
1420
|
-
fs.mkdirSync(path.dirname(commandPath), { recursive: true });
|
|
1421
|
-
fs.writeFileSync(commandPath, command, "utf-8");
|
|
1422
|
-
}
|
|
1423
1467
|
written.push(commandPath);
|
|
1424
1468
|
}
|
|
1425
1469
|
}
|
|
@@ -1427,6 +1471,87 @@ function installBuiltInInstructions(input: {
|
|
|
1427
1471
|
return written;
|
|
1428
1472
|
}
|
|
1429
1473
|
|
|
1474
|
+
function installBuiltInInstructions(
|
|
1475
|
+
input: BuiltInInstructionInstallInput,
|
|
1476
|
+
): string[] {
|
|
1477
|
+
const bundles = Object.values(
|
|
1478
|
+
skillFilesForBuiltIn(input.appSkillId, {
|
|
1479
|
+
planMode: input.planMode,
|
|
1480
|
+
mcpUrl: input.mcpUrl,
|
|
1481
|
+
}),
|
|
1482
|
+
).filter(
|
|
1483
|
+
(bundle) =>
|
|
1484
|
+
!input.onlySkillNames || input.onlySkillNames.includes(bundle.skillName),
|
|
1485
|
+
);
|
|
1486
|
+
const written = builtInInstructionPaths(input);
|
|
1487
|
+
if (input.dryRun) return written;
|
|
1488
|
+
|
|
1489
|
+
for (const agent of input.skillsAgents) {
|
|
1490
|
+
const root = builtInSkillsRootForAgent(agent, input.scope, input.baseDir);
|
|
1491
|
+
const commandsRoot = builtInCommandsRootForAgent(
|
|
1492
|
+
agent,
|
|
1493
|
+
input.scope,
|
|
1494
|
+
input.baseDir,
|
|
1495
|
+
);
|
|
1496
|
+
for (const bundle of bundles) {
|
|
1497
|
+
writeSkillFolder(path.join(root, bundle.skillName), bundle);
|
|
1498
|
+
const command = slashCommandForBuiltInSkill(bundle.skillName);
|
|
1499
|
+
if (command) {
|
|
1500
|
+
const commandPath = path.join(commandsRoot, `${bundle.skillName}.md`);
|
|
1501
|
+
fs.mkdirSync(path.dirname(commandPath), { recursive: true });
|
|
1502
|
+
fs.writeFileSync(commandPath, command, "utf-8");
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
return written;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
interface InstallPathSnapshot {
|
|
1510
|
+
target: string;
|
|
1511
|
+
backup: string;
|
|
1512
|
+
existed: boolean;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
function snapshotInstallPaths(
|
|
1516
|
+
targets: string[],
|
|
1517
|
+
backupRoot: string,
|
|
1518
|
+
): InstallPathSnapshot[] {
|
|
1519
|
+
return [...new Set(targets)].map((target, index) => {
|
|
1520
|
+
const backup = path.join(backupRoot, `snapshot-${index}`);
|
|
1521
|
+
const existed = fs.existsSync(target);
|
|
1522
|
+
if (existed) fs.cpSync(target, backup, { recursive: true });
|
|
1523
|
+
return { target, backup, existed };
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
function removeEmptyParents(start: string, boundary: string): void {
|
|
1528
|
+
let current = path.resolve(start);
|
|
1529
|
+
const stop = path.resolve(boundary);
|
|
1530
|
+
while (current !== stop && current.startsWith(`${stop}${path.sep}`)) {
|
|
1531
|
+
if (!fs.existsSync(current) || fs.readdirSync(current).length > 0) return;
|
|
1532
|
+
fs.rmdirSync(current);
|
|
1533
|
+
current = path.dirname(current);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
function restoreInstallPaths(
|
|
1538
|
+
snapshots: InstallPathSnapshot[],
|
|
1539
|
+
boundary: string,
|
|
1540
|
+
): void {
|
|
1541
|
+
for (const snapshot of snapshots.toReversed()) {
|
|
1542
|
+
fs.rmSync(snapshot.target, { recursive: true, force: true });
|
|
1543
|
+
if (snapshot.existed) {
|
|
1544
|
+
fs.mkdirSync(path.dirname(snapshot.target), { recursive: true });
|
|
1545
|
+
fs.cpSync(snapshot.backup, snapshot.target, { recursive: true });
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
for (const snapshot of snapshots) {
|
|
1549
|
+
if (!snapshot.existed) {
|
|
1550
|
+
removeEmptyParents(path.dirname(snapshot.target), boundary);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1430
1555
|
function listSkillFolderFiles(dir: string): Record<string, string> {
|
|
1431
1556
|
const out: Record<string, string> = {};
|
|
1432
1557
|
const walk = (current: string, prefix = "") => {
|
|
@@ -3376,6 +3501,11 @@ export async function addAgentNativeSkill(
|
|
|
3376
3501
|
const knownBuiltIn = knownTarget ? BUILT_IN_APP_SKILLS[knownTarget] : null;
|
|
3377
3502
|
const installsScreenMemoryMcp = isScreenMemoryMcpBuiltInSkill(knownBuiltIn);
|
|
3378
3503
|
const baseDir = options.baseDir ?? process.cwd();
|
|
3504
|
+
if (installsScreenMemoryMcp && !parsed.mcp) {
|
|
3505
|
+
throw new Error(
|
|
3506
|
+
"Rewind requires the local Clips Screen Memory MCP and cannot be installed with --no-mcp.",
|
|
3507
|
+
);
|
|
3508
|
+
}
|
|
3379
3509
|
if (installsScreenMemoryMcp && parsed.mcpUrl) {
|
|
3380
3510
|
throw new Error(
|
|
3381
3511
|
"Rewind uses the local Clips Screen Memory MCP and does not accept --mcp-url.",
|
|
@@ -3487,7 +3617,7 @@ export async function addAgentNativeSkill(
|
|
|
3487
3617
|
}
|
|
3488
3618
|
installTarget = preserveMcpUrlAppPathOverride(installTarget, parsed.mcpUrl);
|
|
3489
3619
|
const skillsAgents = installsScreenMemoryMcp
|
|
3490
|
-
? clients
|
|
3620
|
+
? clients.filter((client) => client !== "cowork")
|
|
3491
3621
|
: skillsAgentsForClients(clients);
|
|
3492
3622
|
if (parsed.dryRun) {
|
|
3493
3623
|
try {
|
|
@@ -3537,6 +3667,7 @@ export async function addAgentNativeSkill(
|
|
|
3537
3667
|
}
|
|
3538
3668
|
}
|
|
3539
3669
|
const commands: string[] = [];
|
|
3670
|
+
const screenMemoryDir = preflightRewindStore(parsed);
|
|
3540
3671
|
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "an-skills-add-"));
|
|
3541
3672
|
let instructionSource: string | undefined;
|
|
3542
3673
|
let instructionsWritten: string[] | undefined;
|
|
@@ -3544,6 +3675,36 @@ export async function addAgentNativeSkill(
|
|
|
3544
3675
|
let connectCommand: string | undefined;
|
|
3545
3676
|
let registeredMcpClients: ClientId[] = shouldRegisterMcp ? mcpClients : [];
|
|
3546
3677
|
let localManifestPath: string | undefined;
|
|
3678
|
+
const builtInInstructionInput: BuiltInInstructionInstallInput | undefined =
|
|
3679
|
+
knownTarget
|
|
3680
|
+
? {
|
|
3681
|
+
appSkillId: knownTarget,
|
|
3682
|
+
onlySkillNames,
|
|
3683
|
+
skillsAgents,
|
|
3684
|
+
scope: parsed.scope as "project" | "user",
|
|
3685
|
+
baseDir,
|
|
3686
|
+
dryRun: parsed.dryRun,
|
|
3687
|
+
planMode,
|
|
3688
|
+
mcpUrl: installTarget.loaded.manifest.hosted.mcpUrl,
|
|
3689
|
+
}
|
|
3690
|
+
: undefined;
|
|
3691
|
+
const rewindSnapshots = installsScreenMemoryMcp
|
|
3692
|
+
? snapshotInstallPaths(
|
|
3693
|
+
[
|
|
3694
|
+
...(parsed.instructions && builtInInstructionInput
|
|
3695
|
+
? builtInInstructionPaths(builtInInstructionInput)
|
|
3696
|
+
: []),
|
|
3697
|
+
...(shouldRegisterMcp
|
|
3698
|
+
? mcpClients.map((client) =>
|
|
3699
|
+
configPathFor(client, baseDir, parsed.scope),
|
|
3700
|
+
)
|
|
3701
|
+
: []),
|
|
3702
|
+
],
|
|
3703
|
+
tmpRoot,
|
|
3704
|
+
)
|
|
3705
|
+
: undefined;
|
|
3706
|
+
const rollbackBoundary =
|
|
3707
|
+
parsed.scope === "user" ? os.homedir() : path.resolve(baseDir);
|
|
3547
3708
|
|
|
3548
3709
|
try {
|
|
3549
3710
|
if (parsed.instructions) {
|
|
@@ -3553,21 +3714,14 @@ export async function addAgentNativeSkill(
|
|
|
3553
3714
|
"Skill instructions use shared .agents for Codex, Pi, Cursor, OpenCode, Copilot, and similar agents, or Claude Code's native files. Use an MCP-capable client or omit --instructions-only.",
|
|
3554
3715
|
);
|
|
3555
3716
|
}
|
|
3556
|
-
} else if (knownTarget) {
|
|
3717
|
+
} else if (knownTarget && builtInInstructionInput) {
|
|
3557
3718
|
// Built-in skills ship their instructions inside this package, so copy
|
|
3558
3719
|
// the skill folders straight into each client's skills directory. This
|
|
3559
3720
|
// avoids shelling out to the separate @agent-native/skills installer
|
|
3560
3721
|
// (which would need to be published to npm to run via npx).
|
|
3561
|
-
instructionsWritten = installBuiltInInstructions(
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
skillsAgents,
|
|
3565
|
-
scope: parsed.scope as "project" | "user",
|
|
3566
|
-
baseDir,
|
|
3567
|
-
dryRun: parsed.dryRun,
|
|
3568
|
-
planMode,
|
|
3569
|
-
mcpUrl: installTarget.loaded.manifest.hosted.mcpUrl,
|
|
3570
|
-
});
|
|
3722
|
+
instructionsWritten = installBuiltInInstructions(
|
|
3723
|
+
builtInInstructionInput,
|
|
3724
|
+
);
|
|
3571
3725
|
instructionSource = instructionsWritten[0];
|
|
3572
3726
|
commands.push(...instructionsWritten.map((dir) => `write ${dir}`));
|
|
3573
3727
|
} else {
|
|
@@ -3611,29 +3765,24 @@ export async function addAgentNativeSkill(
|
|
|
3611
3765
|
commands.push(`write ${localManifestPath}`);
|
|
3612
3766
|
}
|
|
3613
3767
|
|
|
3614
|
-
//
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3768
|
+
// Rewind reports completion only after both local writes succeed.
|
|
3769
|
+
if (!installsScreenMemoryMcp) {
|
|
3770
|
+
options.telemetry?.track("skills_cli install completed", {
|
|
3771
|
+
skills: installTarget.skillNames.join(","),
|
|
3772
|
+
clients: clients.join(","),
|
|
3773
|
+
scope: parsed.scope,
|
|
3774
|
+
dryRun: Boolean(parsed.dryRun),
|
|
3775
|
+
});
|
|
3776
|
+
}
|
|
3622
3777
|
|
|
3623
3778
|
if (shouldRegisterMcp && installsScreenMemoryMcp) {
|
|
3624
|
-
const screenMemoryDir = resolveScreenMemoryStoreDir();
|
|
3625
|
-
if (!screenMemoryDir) {
|
|
3626
|
-
throw new Error(
|
|
3627
|
-
"No local Clips Screen Memory store was found. Turn Rewind on in Clips, then run the setup again.",
|
|
3628
|
-
);
|
|
3629
|
-
}
|
|
3630
3779
|
registeredMcpClients = mcpClients.map((client) => {
|
|
3631
3780
|
commands.push(
|
|
3632
3781
|
`npx @agent-native/core@latest mcp install-screen-memory --client ${client} --scope ${parsed.scope}`,
|
|
3633
3782
|
);
|
|
3634
|
-
installScreenMemoryForClient(
|
|
3783
|
+
(options.installScreenMemory ?? installScreenMemoryForClient)(
|
|
3635
3784
|
client,
|
|
3636
|
-
screenMemoryDir
|
|
3785
|
+
screenMemoryDir!,
|
|
3637
3786
|
baseDir,
|
|
3638
3787
|
parsed.scope,
|
|
3639
3788
|
);
|
|
@@ -3642,6 +3791,12 @@ export async function addAgentNativeSkill(
|
|
|
3642
3791
|
options.telemetry?.track("skills_cli mcp registered", {
|
|
3643
3792
|
skills: installTarget.skillNames.join(","),
|
|
3644
3793
|
});
|
|
3794
|
+
options.telemetry?.track("skills_cli install completed", {
|
|
3795
|
+
skills: installTarget.skillNames.join(","),
|
|
3796
|
+
clients: clients.join(","),
|
|
3797
|
+
scope: parsed.scope,
|
|
3798
|
+
dryRun: false,
|
|
3799
|
+
});
|
|
3645
3800
|
} else if (shouldRegisterMcp) {
|
|
3646
3801
|
commands.push(
|
|
3647
3802
|
`npx @agent-native/core@latest app-skill ensure --manifest ${installTarget.loaded.file} --client ${parsed.client} --scope ${parsed.scope} --yes`,
|
|
@@ -3769,6 +3924,18 @@ export async function addAgentNativeSkill(
|
|
|
3769
3924
|
githubActionExisted,
|
|
3770
3925
|
githubActionSuggestedCommand,
|
|
3771
3926
|
};
|
|
3927
|
+
} catch (error) {
|
|
3928
|
+
if (rewindSnapshots) {
|
|
3929
|
+
try {
|
|
3930
|
+
restoreInstallPaths(rewindSnapshots, rollbackBoundary);
|
|
3931
|
+
} catch (rollbackError) {
|
|
3932
|
+
throw new AggregateError(
|
|
3933
|
+
[error, rollbackError],
|
|
3934
|
+
"Rewind setup failed and its partial installation could not be fully rolled back.",
|
|
3935
|
+
);
|
|
3936
|
+
}
|
|
3937
|
+
}
|
|
3938
|
+
throw error;
|
|
3772
3939
|
} finally {
|
|
3773
3940
|
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
3774
3941
|
installTarget.cleanup?.();
|
|
@@ -4046,6 +4213,41 @@ function readCliVersion(): string {
|
|
|
4046
4213
|
}
|
|
4047
4214
|
}
|
|
4048
4215
|
|
|
4216
|
+
function deferCliTelemetry(target: CliTelemetry): {
|
|
4217
|
+
telemetry: CliTelemetry;
|
|
4218
|
+
commit: () => void;
|
|
4219
|
+
} {
|
|
4220
|
+
type TrackCall = Parameters<CliTelemetry["track"]>;
|
|
4221
|
+
type ExceptionCall = Parameters<CliTelemetry["captureException"]>;
|
|
4222
|
+
const trackCalls: TrackCall[] = [];
|
|
4223
|
+
const exceptionCalls: ExceptionCall[] = [];
|
|
4224
|
+
let committed = false;
|
|
4225
|
+
|
|
4226
|
+
return {
|
|
4227
|
+
telemetry: {
|
|
4228
|
+
track(...args) {
|
|
4229
|
+
if (committed) target.track(...args);
|
|
4230
|
+
else trackCalls.push(args);
|
|
4231
|
+
},
|
|
4232
|
+
captureException(...args) {
|
|
4233
|
+
if (committed) target.captureException(...args);
|
|
4234
|
+
else exceptionCalls.push(args);
|
|
4235
|
+
},
|
|
4236
|
+
async flush() {
|
|
4237
|
+
if (committed) await target.flush();
|
|
4238
|
+
},
|
|
4239
|
+
},
|
|
4240
|
+
commit() {
|
|
4241
|
+
if (committed) return;
|
|
4242
|
+
committed = true;
|
|
4243
|
+
for (const args of trackCalls) target.track(...args);
|
|
4244
|
+
for (const args of exceptionCalls) target.captureException(...args);
|
|
4245
|
+
trackCalls.length = 0;
|
|
4246
|
+
exceptionCalls.length = 0;
|
|
4247
|
+
},
|
|
4248
|
+
};
|
|
4249
|
+
}
|
|
4250
|
+
|
|
4049
4251
|
export async function runSkills(
|
|
4050
4252
|
argv: string[],
|
|
4051
4253
|
options: RunSkillsOptions = {},
|
|
@@ -4054,6 +4256,7 @@ export async function runSkills(
|
|
|
4054
4256
|
if (parsed.baseDir) {
|
|
4055
4257
|
options = { ...options, baseDir: path.resolve(parsed.baseDir) };
|
|
4056
4258
|
}
|
|
4259
|
+
preflightRewindStore(parsed);
|
|
4057
4260
|
const clackForLog = parsed.printJson
|
|
4058
4261
|
? undefined
|
|
4059
4262
|
: await import("@clack/prompts");
|
|
@@ -4089,7 +4292,7 @@ export async function runSkills(
|
|
|
4089
4292
|
// finally so events send on success, error, and cancellation — the CLI is
|
|
4090
4293
|
// short-lived, so flushing before exit is essential or the events never send.
|
|
4091
4294
|
const startedAt = Date.now();
|
|
4092
|
-
const
|
|
4295
|
+
const telemetryTarget =
|
|
4093
4296
|
options.telemetry ??
|
|
4094
4297
|
createCliTelemetry({
|
|
4095
4298
|
cli: "core",
|
|
@@ -4097,6 +4300,13 @@ export async function runSkills(
|
|
|
4097
4300
|
command: parsed.command,
|
|
4098
4301
|
interactive: shouldPrompt(parsed, options),
|
|
4099
4302
|
});
|
|
4303
|
+
const deferredTelemetry = deferCliTelemetry(telemetryTarget);
|
|
4304
|
+
const telemetry = deferredTelemetry.telemetry;
|
|
4305
|
+
const deferUntilSkillSelection =
|
|
4306
|
+
parsed.command === "add" &&
|
|
4307
|
+
!parsed.target &&
|
|
4308
|
+
!(parsed.plainSkillNames?.length ?? 0);
|
|
4309
|
+
if (!deferUntilSkillSelection) deferredTelemetry.commit();
|
|
4100
4310
|
const optionsWithTelemetry: RunSkillsOptions = {
|
|
4101
4311
|
...options,
|
|
4102
4312
|
telemetry,
|
|
@@ -4137,9 +4347,12 @@ export async function runSkills(
|
|
|
4137
4347
|
|
|
4138
4348
|
const targets = await resolveSkillTargets(parsed, optionsWithTelemetry);
|
|
4139
4349
|
if (!targets) {
|
|
4350
|
+
deferredTelemetry.commit();
|
|
4140
4351
|
telemetry.track("skills_cli cancelled", { step: "skills" });
|
|
4141
4352
|
return;
|
|
4142
4353
|
}
|
|
4354
|
+
preflightResolvedRewindTargets(parsed, targets);
|
|
4355
|
+
deferredTelemetry.commit();
|
|
4143
4356
|
const preselected = Boolean(parsed.target);
|
|
4144
4357
|
telemetry.track("skills_cli skills selected", {
|
|
4145
4358
|
selected: targets.join(","),
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const REWIND_SKILL_TARGETS = new Set([
|
|
2
|
+
"rewind",
|
|
3
|
+
"screen-memory",
|
|
4
|
+
"clips-rewind",
|
|
5
|
+
"agent-native-rewind",
|
|
6
|
+
]);
|
|
7
|
+
|
|
8
|
+
function isRewindSkillTarget(value: string | undefined): boolean {
|
|
9
|
+
return REWIND_SKILL_TARGETS.has(value?.trim().toLowerCase() ?? "");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const SKILLS_VALUE_FLAGS = new Set([
|
|
13
|
+
"--client",
|
|
14
|
+
"--agent",
|
|
15
|
+
"-a",
|
|
16
|
+
"--scope",
|
|
17
|
+
"--cwd",
|
|
18
|
+
"--mcp-url",
|
|
19
|
+
"--mode",
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
function explicitSkillTargets(args: string[]): string[] {
|
|
23
|
+
const targets: string[] = [];
|
|
24
|
+
const start = args[0] === "add" ? 1 : 0;
|
|
25
|
+
for (let index = start; index < args.length; index++) {
|
|
26
|
+
const arg = args[index];
|
|
27
|
+
if (arg === "--skill" || arg === "-s") {
|
|
28
|
+
if (args[index + 1]) targets.push(args[++index]);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (arg.startsWith("--skill=")) {
|
|
32
|
+
targets.push(arg.slice("--skill=".length));
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (SKILLS_VALUE_FLAGS.has(arg)) {
|
|
36
|
+
index++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (arg.startsWith("-")) continue;
|
|
40
|
+
targets.push(arg);
|
|
41
|
+
}
|
|
42
|
+
return targets;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function shouldTrackCliRun(command: string | undefined, args: string[]) {
|
|
46
|
+
if (command !== "skills") return true;
|
|
47
|
+
if (
|
|
48
|
+
["list", "status", "update", "help", "--help", "-h"].includes(args[0] ?? "")
|
|
49
|
+
)
|
|
50
|
+
return true;
|
|
51
|
+
|
|
52
|
+
const targets = explicitSkillTargets(args);
|
|
53
|
+
if (targets.length === 0) return false;
|
|
54
|
+
|
|
55
|
+
const explicitlyTargetsRewind = targets.some(isRewindSkillTarget);
|
|
56
|
+
return !explicitlyTargetsRewind;
|
|
57
|
+
}
|
package/src/cli/telemetry.ts
CHANGED
|
@@ -198,7 +198,7 @@ export function createCliTelemetry(options: CliTelemetryOptions): CliTelemetry {
|
|
|
198
198
|
const publicKey = resolvePublicKey();
|
|
199
199
|
const disabled = telemetryDisabled() || !publicKey;
|
|
200
200
|
const endpoint = resolveEndpoint();
|
|
201
|
-
|
|
201
|
+
let installId: string | undefined = disabled ? "" : undefined;
|
|
202
202
|
const runId = crypto.randomUUID();
|
|
203
203
|
const inFlight = new Set<Promise<void>>();
|
|
204
204
|
|
|
@@ -211,18 +211,18 @@ export function createCliTelemetry(options: CliTelemetryOptions): CliTelemetry {
|
|
|
211
211
|
ci: process.env.CI === "true",
|
|
212
212
|
interactive: options.interactive,
|
|
213
213
|
runId,
|
|
214
|
-
installId,
|
|
215
214
|
};
|
|
216
215
|
|
|
217
216
|
function track(event: string, properties?: Record<string, unknown>): void {
|
|
218
217
|
if (disabled) return;
|
|
218
|
+
installId ??= resolveInstallId();
|
|
219
219
|
const body = JSON.stringify({
|
|
220
220
|
publicKey,
|
|
221
221
|
event,
|
|
222
222
|
anonymousId: installId,
|
|
223
223
|
sessionId: runId,
|
|
224
224
|
timestamp: new Date().toISOString(),
|
|
225
|
-
properties: { ...base, ...properties },
|
|
225
|
+
properties: { ...base, installId, ...properties },
|
|
226
226
|
});
|
|
227
227
|
const promise = fetch(endpoint, {
|
|
228
228
|
method: "POST",
|