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,263 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import type {
3
+ MemoryStore,
4
+ OriginValue,
5
+ RetentionClass,
6
+ StoreEntry,
7
+ SupabaseStoreConfig,
8
+ WriteAutoSavedArgs,
9
+ } from "./types";
10
+ import type { TrustLevel } from "../../../types";
11
+
12
+ /**
13
+ * Wider Supabase client interface for layeredMemory.
14
+ *
15
+ * Adds:
16
+ * - delete()/update() for forget and supersede
17
+ * - eq()/is()/gt() chain methods on the search builder so peer_id,
18
+ * superseded_by, and expires_at predicates run in SQL (not app
19
+ * code) — critical for tenant isolation under load.
20
+ *
21
+ * Structurally compatible with @supabase/supabase-js and with the
22
+ * extended mock in tests/fixtures/mock-supabase.ts.
23
+ */
24
+ export interface SearchBuilder {
25
+ eq(column: string, value: unknown): SearchBuilder;
26
+ is(column: string, value: null): SearchBuilder;
27
+ gt(column: string, value: number): SearchBuilder;
28
+ ilike(column: string, value: string): SearchBuilder;
29
+ or(filterExpr: string): SearchBuilder;
30
+ order(column: string, opts?: { ascending?: boolean }): SearchBuilder;
31
+ limit(n: number): PromiseLike<{ data: unknown[]; error: Error | null }>;
32
+ maybeSingle(): PromiseLike<{ data: unknown; error: Error | null }>;
33
+ }
34
+
35
+ export interface LayeredSupabaseClient {
36
+ from(table: string): {
37
+ insert(row: unknown): PromiseLike<{ error: Error | null }>;
38
+ select(columns?: string): SearchBuilder;
39
+ delete(): {
40
+ eq(
41
+ column: string,
42
+ value: unknown,
43
+ ): PromiseLike<{ data: unknown[] | null; error: Error | null }>;
44
+ };
45
+ update(patch: Record<string, unknown>): {
46
+ eq(column: string, value: unknown): PromiseLike<{ error: Error | null }>;
47
+ };
48
+ };
49
+ }
50
+
51
+ interface Row {
52
+ id: string;
53
+ label: string;
54
+ content: string;
55
+ peer_id: string | null;
56
+ trust_level: string | null;
57
+ created_at: number;
58
+ superseded_by: string | null;
59
+ retention_class: string;
60
+ is_verbatim: boolean | number;
61
+ expires_at: number | null;
62
+ // Phase 2 fact-fields (nullable)
63
+ subject: string | null;
64
+ predicate: string | null;
65
+ object: string | null;
66
+ source_turn_id: string | null;
67
+ origin: string | null;
68
+ }
69
+
70
+ function rowToEntry(row: Row): StoreEntry {
71
+ const entry: StoreEntry = {
72
+ id: row.id,
73
+ label: row.label,
74
+ content: row.content,
75
+ peerId: row.peer_id,
76
+ trustLevel: row.trust_level as TrustLevel | null,
77
+ createdAt: row.created_at,
78
+ supersededBy: row.superseded_by,
79
+ retentionClass: row.retention_class as RetentionClass,
80
+ isVerbatim: !!row.is_verbatim,
81
+ expiresAt: row.expires_at,
82
+ };
83
+ // Phase 2 fact-fields: only populate if non-null to keep entries clean
84
+ if (row.subject != null) entry.subject = row.subject;
85
+ if (row.predicate != null) entry.predicate = row.predicate;
86
+ if (row.object != null) entry.object = row.object;
87
+ if (row.source_turn_id != null) entry.sourceTurnId = row.source_turn_id;
88
+ if (row.origin != null) entry.origin = row.origin as OriginValue;
89
+ return entry;
90
+ }
91
+
92
+ export function createSupabaseStore(
93
+ config: Omit<SupabaseStoreConfig, "client"> & { client: LayeredSupabaseClient },
94
+ ): MemoryStore {
95
+ const retentionMs = config.retentionDays * 24 * 60 * 60 * 1000;
96
+
97
+ async function initialize(): Promise<void> {
98
+ // Supabase schema is created via migrations, not at runtime.
99
+ }
100
+
101
+ async function write(input: Omit<StoreEntry, "id"> & { id?: string }): Promise<StoreEntry> {
102
+ const id = input.id ?? randomUUID();
103
+ const expiresAt = input.expiresAt ?? input.createdAt + retentionMs;
104
+
105
+ const row: Row = {
106
+ id,
107
+ label: input.label,
108
+ content: input.content,
109
+ peer_id: input.peerId,
110
+ trust_level: input.trustLevel,
111
+ created_at: input.createdAt,
112
+ superseded_by: input.supersededBy,
113
+ retention_class: input.retentionClass,
114
+ is_verbatim: input.isVerbatim,
115
+ expires_at: expiresAt,
116
+ // Phase 2 fact-fields
117
+ subject: input.subject ?? null,
118
+ predicate: input.predicate ?? null,
119
+ object: input.object ?? null,
120
+ source_turn_id: input.sourceTurnId ?? null,
121
+ origin: input.origin ?? null,
122
+ };
123
+
124
+ const { error } = await config.client.from(config.table).insert(row);
125
+ if (error) throw error;
126
+
127
+ return { ...input, id, expiresAt };
128
+ }
129
+
130
+ async function search(query: string, peerId?: string, limit = 10): Promise<StoreEntry[]> {
131
+ const escaped = query.replace(/[%_\\]/g, (c) => `\\${c}`);
132
+ const pattern = `%${escaped}%`;
133
+ const now = Date.now();
134
+
135
+ // All tenant-isolation and freshness predicates run in SQL BEFORE
136
+ // LIMIT. Without this, a busy tenant could crowd out another peer's
137
+ // hits before app-side filtering, returning empty/partial results
138
+ // even when matching rows exist. Production deployments should ALSO
139
+ // back this with RLS so the database refuses cross-tenant reads
140
+ // independent of application code.
141
+ let builder: SearchBuilder = config.client
142
+ .from(config.table)
143
+ .select(
144
+ "id, label, content, peer_id, trust_level, created_at, superseded_by, retention_class, is_verbatim, expires_at, subject, predicate, object, source_turn_id, origin",
145
+ );
146
+
147
+ if (peerId) {
148
+ builder = builder.eq("peer_id", peerId);
149
+ }
150
+ builder = builder.is("superseded_by", null);
151
+ // Postgres "or" handles "expires_at IS NULL OR expires_at >= now" —
152
+ // we send it as a single predicate so PostgREST builds the right
153
+ // SQL. The mock parses this as a logical OR over its filters.
154
+ builder = builder.or(`expires_at.is.null,expires_at.gte.${now}`);
155
+
156
+ const { data, error } = await builder
157
+ .ilike("content", pattern)
158
+ .order("created_at", { ascending: false })
159
+ .limit(limit);
160
+
161
+ if (error) throw error;
162
+ const rows = (data ?? []) as Row[];
163
+ return rows.map(rowToEntry);
164
+ }
165
+
166
+ async function read(label: string): Promise<StoreEntry | null> {
167
+ const { data, error } = await config.client
168
+ .from(config.table)
169
+ .select(
170
+ "id, label, content, peer_id, trust_level, created_at, superseded_by, retention_class, is_verbatim, expires_at, subject, predicate, object, source_turn_id, origin",
171
+ )
172
+ .eq("label", label)
173
+ .maybeSingle();
174
+
175
+ if (error) throw error;
176
+ if (!data) return null;
177
+ return rowToEntry(data as Row);
178
+ }
179
+
180
+ async function list(_peerId?: string): Promise<string[]> {
181
+ // Phase 1 doesn't expose memory_list to namespace providers.
182
+ return [];
183
+ }
184
+
185
+ async function forget(peerId: string): Promise<number> {
186
+ const { data, error } = await config.client.from(config.table).delete().eq("peer_id", peerId);
187
+ if (error) throw error;
188
+ return Array.isArray(data) ? data.length : 0;
189
+ }
190
+
191
+ async function supersede(entryId: string, newEntryId: string): Promise<void> {
192
+ const { error } = await config.client
193
+ .from(config.table)
194
+ .update({ superseded_by: newEntryId })
195
+ .eq("id", entryId);
196
+ if (error) throw error;
197
+ }
198
+
199
+ async function cleanup(): Promise<number> {
200
+ // No-op for Supabase; assume a Postgres cron or trigger handles expiry.
201
+ return 0;
202
+ }
203
+
204
+ // Internal-to-layered-memory write path used by the extractor. See
205
+ // sqlite-store's writeAutoSavedEntry for the full contract; the
206
+ // Supabase implementation mirrors it: enforce namespace prefix,
207
+ // hardcode origin='agent-derived', persist the structured-fact +
208
+ // provenance fields. NOT exposed on any augment-public surface.
209
+ async function writeAutoSavedEntry(args: WriteAutoSavedArgs): Promise<void> {
210
+ if (!config.namespace) {
211
+ throw new Error(
212
+ "writeAutoSavedEntry: store has no namespace configured; auto-save requires namespace-prefix discipline",
213
+ );
214
+ }
215
+ const prefix = config.namespace.endsWith(":") ? config.namespace : `${config.namespace}:`;
216
+ if (!args.label.startsWith(prefix)) {
217
+ throw new Error(
218
+ `writeAutoSavedEntry: label "${args.label}" does not start with namespace prefix "${prefix}"`,
219
+ );
220
+ }
221
+ const id = randomUUID();
222
+ const createdAt = Date.now();
223
+ const expiresAt = createdAt + retentionMs;
224
+ const row: Row & { provenance_model: string | null; confidence: number | null } = {
225
+ id,
226
+ label: args.label,
227
+ content: args.content,
228
+ peer_id: args.peerId,
229
+ trust_level: null,
230
+ created_at: createdAt,
231
+ superseded_by: null,
232
+ retention_class: args.retentionClass,
233
+ is_verbatim: args.isVerbatim,
234
+ expires_at: expiresAt,
235
+ subject: args.subject ?? null,
236
+ predicate: args.predicate ?? null,
237
+ object: args.object ?? null,
238
+ source_turn_id: args.sourceTurnId,
239
+ origin: "agent-derived",
240
+ provenance_model: args.model,
241
+ confidence: args.confidence,
242
+ };
243
+ const { error } = await config.client.from(config.table).insert(row);
244
+ if (error) throw error;
245
+ }
246
+
247
+ async function close(): Promise<void> {
248
+ // No-op for Supabase.
249
+ }
250
+
251
+ return {
252
+ initialize,
253
+ write,
254
+ writeAutoSavedEntry,
255
+ search,
256
+ read,
257
+ list,
258
+ forget,
259
+ supersede,
260
+ cleanup,
261
+ close,
262
+ };
263
+ }
@@ -0,0 +1,98 @@
1
+ import type { MemoryOrigin, TrustLevel } from "../../../types";
2
+ import type { SupabaseLikeClient } from "../../supabase-memory";
3
+
4
+ export type RetentionClass = "operational" | "lesson";
5
+
6
+ /**
7
+ * Re-export of the canonical MemoryOrigin from `src/types.ts`. The storage
8
+ * layer's `origin` column matches the runtime MemoryEntry contract one-for-one;
9
+ * having a single canonical type prevents drift.
10
+ */
11
+ export type OriginValue = MemoryOrigin;
12
+
13
+ export interface StoreEntry {
14
+ id: string;
15
+ label: string;
16
+ content: string;
17
+ peerId: string | null;
18
+ trustLevel: TrustLevel | null;
19
+ createdAt: number;
20
+ supersededBy: string | null;
21
+ retentionClass: RetentionClass;
22
+ isVerbatim: boolean;
23
+ expiresAt: number | null;
24
+ // Phase 2 — structured-fact + provenance fields (all optional; nullable in storage)
25
+ subject?: string;
26
+ predicate?: string;
27
+ object?: string;
28
+ sourceTurnId?: string;
29
+ origin?: OriginValue;
30
+ }
31
+
32
+ /**
33
+ * Arguments for the internal `writeAutoSavedEntry` path used by
34
+ * layered-memory's extractor (Phase 2 of ADR-018, Decision 4 of the
35
+ * memorist design). Distinct from the model-callable `memory_write`
36
+ * tool: carries structured-fact + provenance fields the tool's input
37
+ * schema doesn't expose, and `origin` is hardcoded to `"agent-derived"`
38
+ * inside the implementation — there is no `origin` argument here, so
39
+ * extraction prompts cannot forge `operator` or `peer-derived`.
40
+ *
41
+ * Namespace-prefix enforcement: implementations must reject any `label`
42
+ * that doesn't start with the store's configured namespace. This
43
+ * mirrors the discipline applied by the model-facing memory tools.
44
+ */
45
+ export interface WriteAutoSavedArgs {
46
+ peerId: string;
47
+ label: string;
48
+ content: string;
49
+ subject?: string;
50
+ predicate?: string;
51
+ object?: string;
52
+ confidence: number;
53
+ retentionClass: RetentionClass;
54
+ isVerbatim: boolean;
55
+ sourceTurnId: string;
56
+ model: string;
57
+ }
58
+
59
+ export interface MemoryStore {
60
+ initialize(): Promise<void>;
61
+ write(entry: Omit<StoreEntry, "id"> & { id?: string }): Promise<StoreEntry>;
62
+ /**
63
+ * Internal-to-layered-memory write path for the extractor (Phase 2).
64
+ * Implementations enforce namespace-prefix discipline and hardcode
65
+ * `origin: "agent-derived"`. Not exposed on any augment-public surface.
66
+ */
67
+ writeAutoSavedEntry(args: WriteAutoSavedArgs): Promise<void>;
68
+ search(query: string, peerId?: string, limit?: number): Promise<StoreEntry[]>;
69
+ read(label: string): Promise<StoreEntry | null>;
70
+ list(peerId?: string): Promise<string[]>;
71
+ forget(peerId: string): Promise<number>;
72
+ supersede(entryId: string, newEntryId: string): Promise<void>;
73
+ cleanup(): Promise<number>;
74
+ close(): Promise<void>;
75
+ }
76
+
77
+ export interface SqliteStoreConfig {
78
+ dbPath: string;
79
+ retentionDays: number;
80
+ /**
81
+ * Namespace prefix the store enforces on `writeAutoSavedEntry`. When
82
+ * absent, the auto-save path throws — namespace-prefix discipline is
83
+ * a hard requirement for the extractor write path. The augment factory
84
+ * (`layered-memory/index.ts`) wires this through.
85
+ */
86
+ namespace?: string;
87
+ }
88
+
89
+ export interface SupabaseStoreConfig {
90
+ client: SupabaseLikeClient;
91
+ table: string;
92
+ retentionDays: number;
93
+ /**
94
+ * Namespace prefix the store enforces on `writeAutoSavedEntry`. See
95
+ * `SqliteStoreConfig.namespace`.
96
+ */
97
+ namespace?: string;
98
+ }