auggy 0.3.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.
Files changed (121) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/LICENSE +201 -0
  3. package/README.md +161 -0
  4. package/package.json +76 -0
  5. package/src/agent-card.ts +39 -0
  6. package/src/agent.ts +283 -0
  7. package/src/agentmail-client.ts +138 -0
  8. package/src/augments/bash/index.ts +463 -0
  9. package/src/augments/bash/skill/SKILL.md +156 -0
  10. package/src/augments/budgets/budget-store.ts +513 -0
  11. package/src/augments/budgets/index.ts +134 -0
  12. package/src/augments/budgets/preamble.ts +93 -0
  13. package/src/augments/budgets/types.ts +89 -0
  14. package/src/augments/file-memory/index.ts +71 -0
  15. package/src/augments/filesystem/index.ts +533 -0
  16. package/src/augments/filesystem/skill/SKILL.md +142 -0
  17. package/src/augments/filesystem/skill/references/mount-permissions.md +81 -0
  18. package/src/augments/layered-memory/extractor/buffer.ts +56 -0
  19. package/src/augments/layered-memory/extractor/frequency.ts +79 -0
  20. package/src/augments/layered-memory/extractor/inject-handler.ts +103 -0
  21. package/src/augments/layered-memory/extractor/parse.ts +75 -0
  22. package/src/augments/layered-memory/extractor/prompt.md +26 -0
  23. package/src/augments/layered-memory/index.ts +757 -0
  24. package/src/augments/layered-memory/skill/SKILL.md +153 -0
  25. package/src/augments/layered-memory/storage/migrations/README.md +16 -0
  26. package/src/augments/layered-memory/storage/migrations/supabase-add-fact-fields.sql +9 -0
  27. package/src/augments/layered-memory/storage/sqlite-store.ts +352 -0
  28. package/src/augments/layered-memory/storage/supabase-store.ts +263 -0
  29. package/src/augments/layered-memory/storage/types.ts +98 -0
  30. package/src/augments/link/index.ts +489 -0
  31. package/src/augments/link/translate.ts +261 -0
  32. package/src/augments/notify/adapters/agentmail.ts +70 -0
  33. package/src/augments/notify/adapters/telegram.ts +60 -0
  34. package/src/augments/notify/adapters/webhook.ts +55 -0
  35. package/src/augments/notify/index.ts +284 -0
  36. package/src/augments/notify/skill/SKILL.md +150 -0
  37. package/src/augments/org-context/index.ts +721 -0
  38. package/src/augments/org-context/skill/SKILL.md +96 -0
  39. package/src/augments/skills/index.ts +103 -0
  40. package/src/augments/supabase-memory/index.ts +151 -0
  41. package/src/augments/telegram-transport/index.ts +312 -0
  42. package/src/augments/telegram-transport/polling.ts +55 -0
  43. package/src/augments/telegram-transport/webhook.ts +56 -0
  44. package/src/augments/turn-control/index.ts +61 -0
  45. package/src/augments/turn-control/skill/SKILL.md +155 -0
  46. package/src/augments/visitor-auth/email-validation.ts +66 -0
  47. package/src/augments/visitor-auth/index.ts +779 -0
  48. package/src/augments/visitor-auth/rate-limiter.ts +90 -0
  49. package/src/augments/visitor-auth/skill/SKILL.md +55 -0
  50. package/src/augments/visitor-auth/storage/sqlite-store.ts +398 -0
  51. package/src/augments/visitor-auth/storage/types.ts +164 -0
  52. package/src/augments/visitor-auth/types.ts +123 -0
  53. package/src/augments/visitor-auth/verify-page.ts +179 -0
  54. package/src/augments/web-fetch/index.ts +331 -0
  55. package/src/augments/web-fetch/skill/SKILL.md +100 -0
  56. package/src/cli/agent-index.ts +289 -0
  57. package/src/cli/augment-catalog.ts +320 -0
  58. package/src/cli/augment-resolver.ts +597 -0
  59. package/src/cli/commands/add-skill.ts +194 -0
  60. package/src/cli/commands/add.ts +87 -0
  61. package/src/cli/commands/chat.ts +207 -0
  62. package/src/cli/commands/create.ts +462 -0
  63. package/src/cli/commands/dev.ts +139 -0
  64. package/src/cli/commands/eval.ts +180 -0
  65. package/src/cli/commands/ls.ts +66 -0
  66. package/src/cli/commands/remove.ts +95 -0
  67. package/src/cli/commands/restart.ts +40 -0
  68. package/src/cli/commands/start.ts +123 -0
  69. package/src/cli/commands/status.ts +104 -0
  70. package/src/cli/commands/stop.ts +84 -0
  71. package/src/cli/commands/visitors-revoke.ts +155 -0
  72. package/src/cli/commands/visitors.ts +101 -0
  73. package/src/cli/config-parser.ts +1034 -0
  74. package/src/cli/engine-resolver.ts +68 -0
  75. package/src/cli/index.ts +178 -0
  76. package/src/cli/model-picker.ts +89 -0
  77. package/src/cli/pid-registry.ts +146 -0
  78. package/src/cli/plist-generator.ts +117 -0
  79. package/src/cli/resolve-config.ts +56 -0
  80. package/src/cli/scaffold-skills.ts +158 -0
  81. package/src/cli/scaffold.ts +291 -0
  82. package/src/cli/skill-frontmatter.ts +51 -0
  83. package/src/cli/skill-validator.ts +151 -0
  84. package/src/cli/types.ts +228 -0
  85. package/src/cli/yaml-helpers.ts +66 -0
  86. package/src/engines/_shared/cost.ts +55 -0
  87. package/src/engines/_shared/schema-normalize.ts +75 -0
  88. package/src/engines/anthropic/pricing.ts +117 -0
  89. package/src/engines/anthropic.ts +483 -0
  90. package/src/engines/openai/pricing.ts +67 -0
  91. package/src/engines/openai.ts +446 -0
  92. package/src/engines/openrouter/pricing.ts +83 -0
  93. package/src/engines/openrouter.ts +185 -0
  94. package/src/helpers.ts +24 -0
  95. package/src/http.ts +387 -0
  96. package/src/index.ts +165 -0
  97. package/src/kernel/capability-table.ts +172 -0
  98. package/src/kernel/context-allocator.ts +161 -0
  99. package/src/kernel/history-manager.ts +198 -0
  100. package/src/kernel/lifecycle-manager.ts +106 -0
  101. package/src/kernel/output-validator.ts +35 -0
  102. package/src/kernel/preamble.ts +23 -0
  103. package/src/kernel/route-collector.ts +97 -0
  104. package/src/kernel/timeout.ts +21 -0
  105. package/src/kernel/tool-selector.ts +47 -0
  106. package/src/kernel/trace-emitter.ts +66 -0
  107. package/src/kernel/transport-queue.ts +147 -0
  108. package/src/kernel/turn-loop.ts +1148 -0
  109. package/src/memory/context-synthesis.ts +83 -0
  110. package/src/memory/memory-bus.ts +61 -0
  111. package/src/memory/registry.ts +80 -0
  112. package/src/memory/tools.ts +320 -0
  113. package/src/memory/types.ts +8 -0
  114. package/src/parts.ts +30 -0
  115. package/src/scaffold-templates/identity.md +31 -0
  116. package/src/telegram-client.ts +145 -0
  117. package/src/tokenizer.ts +14 -0
  118. package/src/transports/ag-ui-events.ts +253 -0
  119. package/src/transports/visitor-token.ts +82 -0
  120. package/src/transports/web-transport.ts +948 -0
  121. package/src/types.ts +1009 -0
@@ -0,0 +1,155 @@
1
+ /**
2
+ * `auggy visitors <agent> --revoke <email>` — hard-revoke + memory cascade.
3
+ *
4
+ * Operates on SQLite files directly (visitor-auth.db, memory.db). Safe with
5
+ * a running agent thanks to WAL mode.
6
+ *
7
+ * Cascade order:
8
+ * 1. visitor-auth.db: revokeByEmail returns visitorId
9
+ * 2. memory.db: DELETE FROM entries WHERE peer_id = visitorId
10
+ */
11
+
12
+ import { existsSync } from "node:fs";
13
+ import { Database } from "bun:sqlite";
14
+ import { join, resolve } from "node:path";
15
+ import { getAgent } from "../agent-index";
16
+ import { createSqliteVisitorAuthStore } from "../../augments/visitor-auth/storage/sqlite-store";
17
+ import { parseAugmentConfigOnly } from "../yaml-helpers";
18
+
19
+ export interface VisitorsRevokeOptions {
20
+ auggyDir?: string;
21
+ /** When true, prompt the user. When false (or --yes), skip the prompt. */
22
+ confirm?: boolean;
23
+ log?: (line: string) => void;
24
+ /** Test seam — production reads from stdin (currently always returns false in non-interactive contexts). */
25
+ _confirmAnswer?: (prompt: string) => boolean;
26
+ }
27
+
28
+ interface ResolvedPaths {
29
+ agentDir: string;
30
+ visitorAuthDb: string;
31
+ memoryDb: string | null;
32
+ }
33
+
34
+ function resolvePaths(agentName: string, opts: VisitorsRevokeOptions): ResolvedPaths {
35
+ const entry = getAgent(agentName, { auggyDir: opts.auggyDir });
36
+ if (!entry) {
37
+ throw new Error(
38
+ `Agent "${agentName}" is not registered. Run \`auggy ls\` to see registered agents.`,
39
+ );
40
+ }
41
+ const agentDir = entry.localDir;
42
+ const yamlPath = join(agentDir, "agent.yaml");
43
+ // parseAugmentConfigOnly handles env-var interpolation (F15) so that
44
+ // `dbPath: ${MY_DB_PATH}` / `layeredMemoryDbPath: ${MEMORY_DB}` in
45
+ // agent.yaml resolves correctly here.
46
+ const vaOptions = parseAugmentConfigOnly(yamlPath, "visitorAuth");
47
+ if (!vaOptions) {
48
+ throw new Error(`Agent "${agentName}": visitorAuth is not configured.`);
49
+ }
50
+ const dbPath = (vaOptions.dbPath as string | undefined) ?? "./visitor-auth.db";
51
+ // null = explicit opt-out from peer-id migration; undefined = default.
52
+ const memPathRaw =
53
+ vaOptions.layeredMemoryDbPath === null
54
+ ? null
55
+ : ((vaOptions.layeredMemoryDbPath as string | undefined) ?? "./memory.db");
56
+ return {
57
+ agentDir,
58
+ visitorAuthDb: resolve(agentDir, dbPath),
59
+ memoryDb: memPathRaw === null ? null : resolve(agentDir, memPathRaw),
60
+ };
61
+ }
62
+
63
+ function defaultConfirm(prompt: string): boolean {
64
+ process.stdout.write(prompt);
65
+ // Synchronous stdin read in Bun is non-trivial. For v1 we assume "no" in
66
+ // non-interactive contexts. Operators must pass `--yes` for non-interactive
67
+ // revocation. Tests inject _confirmAnswer.
68
+ return false;
69
+ }
70
+
71
+ export async function runVisitorsRevoke(
72
+ agentName: string,
73
+ email: string,
74
+ opts: VisitorsRevokeOptions = {},
75
+ ): Promise<void> {
76
+ const log = opts.log ?? ((l: string) => console.log(l));
77
+ const paths = resolvePaths(agentName, opts);
78
+
79
+ if (!existsSync(paths.visitorAuthDb)) {
80
+ throw new Error(`No verified visitors yet — visitor-auth.db not found.`);
81
+ }
82
+
83
+ const store = createSqliteVisitorAuthStore({ dbPath: paths.visitorAuthDb });
84
+ store.initialize();
85
+ const existing = store.findVerifiedByEmail(email);
86
+ if (!existing) {
87
+ store.close();
88
+ throw new Error(`No verified visitor found for "${email}".`);
89
+ }
90
+
91
+ // Already-revoked branch: re-run the memory cascade to recover from a
92
+ // previously-interrupted revoke (e.g. operator hit Ctrl-C between the
93
+ // visitor-auth UPDATE and the memory.db DELETE). DELETE is idempotent —
94
+ // a no-op when there are no orphan rows.
95
+ if (existing.revoked) {
96
+ store.close();
97
+ const memDeleted = cascadeMemoryDelete(paths.memoryDb, existing.visitorId, log);
98
+ log(
99
+ `Visitor "${email}" was already revoked (${existing.revokedReason ?? "unspecified"}). ${memDeleted} stale memory row(s) cleaned up.`,
100
+ );
101
+ return;
102
+ }
103
+
104
+ if (opts.confirm) {
105
+ const ok = (opts._confirmAnswer ?? defaultConfirm)(
106
+ `Revoke verified visitor "${email}" (${existing.visitorId})? This deletes peer-scoped memory rows. [y/N] `,
107
+ );
108
+ if (!ok) {
109
+ log("Cancelled. No changes made.");
110
+ store.close();
111
+ return;
112
+ }
113
+ }
114
+
115
+ const visitorId = store.revokeByEmail(email, "operator", Date.now())!;
116
+ store.close();
117
+
118
+ const memDeleted = cascadeMemoryDelete(paths.memoryDb, visitorId, log);
119
+ log(`Revoked "${email}" (${visitorId}). ${memDeleted} memory row(s) removed.`);
120
+ }
121
+
122
+ /**
123
+ * DELETE memory rows for a peer-id from the layeredMemory SQLite file.
124
+ * Best-effort — exceptions are logged and swallowed; the visitor-auth row
125
+ * has already been revoked at the call site, so partial-success state is
126
+ * acceptable. Returns the row count (0 if missing-file/null-path).
127
+ */
128
+ function cascadeMemoryDelete(
129
+ memoryDb: string | null,
130
+ visitorId: string,
131
+ log: (line: string) => void,
132
+ ): number {
133
+ if (!memoryDb) return 0;
134
+ if (!existsSync(memoryDb)) {
135
+ log(`memory.db not found at ${memoryDb} — skipping memory cascade.`);
136
+ return 0;
137
+ }
138
+ let db: Database | null = null;
139
+ try {
140
+ db = new Database(memoryDb, { readwrite: true });
141
+ const r = db.prepare(`DELETE FROM entries WHERE peer_id = ?`).run(visitorId);
142
+ return r.changes;
143
+ } catch (err) {
144
+ log(`Memory cascade failed: ${(err as Error).message}. Operator should retry manually.`);
145
+ return 0;
146
+ } finally {
147
+ if (db) {
148
+ try {
149
+ db.close();
150
+ } catch {
151
+ // ignore close errors
152
+ }
153
+ }
154
+ }
155
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * `auggy visitors <agent>` — list verified visitors for a single agent.
3
+ *
4
+ * Operates on the agent's SQLite files directly (visitor-auth.db). The agent
5
+ * does NOT need to be running — SQLite WAL mode keeps reads safe alongside
6
+ * a running agent.
7
+ */
8
+
9
+ import { existsSync } from "node:fs";
10
+ import { join, resolve } from "node:path";
11
+ import { getAgent } from "../agent-index";
12
+ import { createSqliteVisitorAuthStore } from "../../augments/visitor-auth/storage/sqlite-store";
13
+ import { parseAugmentConfigOnly } from "../yaml-helpers";
14
+
15
+ export interface VisitorsCommandOptions {
16
+ auggyDir?: string;
17
+ log?: (line: string) => void;
18
+ }
19
+
20
+ interface ResolvedAgentPaths {
21
+ agentDir: string;
22
+ visitorAuthDb: string;
23
+ }
24
+
25
+ function resolveAgentPaths(agentName: string, opts: VisitorsCommandOptions): ResolvedAgentPaths {
26
+ const entry = getAgent(agentName, { auggyDir: opts.auggyDir });
27
+ if (!entry) {
28
+ throw new Error(
29
+ `Agent "${agentName}" is not registered. Run \`auggy ls\` to see registered agents.`,
30
+ );
31
+ }
32
+ const agentDir = entry.localDir;
33
+ const yamlPath = join(agentDir, "agent.yaml");
34
+ // parseAugmentConfigOnly handles env-var interpolation (F15) so that
35
+ // `dbPath: ${MY_DB_PATH}` in agent.yaml resolves correctly here.
36
+ const vaOptions = parseAugmentConfigOnly(yamlPath, "visitorAuth");
37
+ if (!vaOptions) {
38
+ throw new Error(`Agent "${agentName}": visitorAuth augment is not configured.`);
39
+ }
40
+ const dbPath = (vaOptions.dbPath as string | undefined) ?? "./visitor-auth.db";
41
+ return {
42
+ agentDir,
43
+ visitorAuthDb: resolve(agentDir, dbPath),
44
+ };
45
+ }
46
+
47
+ function pad(s: string, w: number): string {
48
+ return s + " ".repeat(Math.max(0, w - s.length));
49
+ }
50
+
51
+ function formatTs(ms: number | null): string {
52
+ if (!ms) return "—";
53
+ return `${new Date(ms).toISOString().replace("T", " ").slice(0, 19)} UTC`;
54
+ }
55
+
56
+ function statusLabel(row: {
57
+ revoked: boolean;
58
+ reverifyDueAt: number;
59
+ revokedReason: string | null;
60
+ }): string {
61
+ if (row.revoked) {
62
+ const reason = row.revokedReason ?? "unspecified";
63
+ return `revoked (${reason})`;
64
+ }
65
+ if (row.reverifyDueAt <= Date.now()) return "reverify due";
66
+ return "active";
67
+ }
68
+
69
+ export async function runVisitorsList(
70
+ agentName: string,
71
+ opts: VisitorsCommandOptions = {},
72
+ ): Promise<void> {
73
+ const log = opts.log ?? ((l: string) => console.log(l));
74
+ const paths = resolveAgentPaths(agentName, opts);
75
+
76
+ if (!existsSync(paths.visitorAuthDb)) {
77
+ log(`(none) — visitor-auth.db has not been created yet for "${agentName}".`);
78
+ return;
79
+ }
80
+ const store = createSqliteVisitorAuthStore({ dbPath: paths.visitorAuthDb });
81
+ store.initialize();
82
+ const rows = store.listVerifiedVisitors();
83
+ store.close();
84
+
85
+ if (rows.length === 0) {
86
+ log(`(none) — no verified visitors recorded for "${agentName}".`);
87
+ return;
88
+ }
89
+
90
+ const headers = ["EMAIL", "VISITOR_ID", "VERIFIED_AT", "LAST_SEEN", "STATUS"];
91
+ const data = rows.map((r) => [
92
+ r.email,
93
+ r.visitorId,
94
+ formatTs(r.verifiedAt),
95
+ formatTs(r.lastSeenAt),
96
+ statusLabel(r),
97
+ ]);
98
+ const widths = headers.map((h, i) => Math.max(h.length, ...data.map((row) => row[i]!.length)));
99
+ log(headers.map((h, i) => pad(h, widths[i]!)).join(" "));
100
+ for (const row of data) log(row.map((c, i) => pad(c, widths[i]!)).join(" "));
101
+ }