@ia-ccun/code-agent-cli 0.0.52 → 0.0.54-beta.1

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 (141) hide show
  1. package/config/agent/bin/README.md +102 -0
  2. package/config/agent/bin/fd.exe +0 -0
  3. package/config/agent/bin/rg.exe +0 -0
  4. package/config/agent/extensions/aicode-advisor.ts +13 -0
  5. package/config/agent/extensions/aicode-btw.ts +66 -14
  6. package/config/agent/extensions/aicode-cd.ts +834 -0
  7. package/config/agent/extensions/aicode-filter-outputs.ts +131 -0
  8. package/config/agent/extensions/aicode-grillMe.ts +198 -0
  9. package/config/agent/extensions/aicode-pets.ts +362 -0
  10. package/config/agent/extensions/aicode-safety-guard.ts +552 -0
  11. package/config/agent/extensions/aicode-snake.ts +354 -0
  12. package/config/agent/extensions/aicode-tips.ts +70 -16
  13. package/config/agent/extensions/aicode-todo-progress.ts +547 -0
  14. package/config/agent/extensions/custom.ts +93 -95
  15. package/config/agent/extensions/error-monitor.ts +1 -18
  16. package/config/agent/extensions/ponytail.ts +441 -0
  17. package/config/agent/extensions/tps.ts +87 -0
  18. package/config/agent/extensions/working-msg.ts +165 -50
  19. package/config/agent/help.md +0 -7
  20. package/config/agent/models.json +7 -7
  21. package/config/agent/settings.json +16 -16
  22. package/config/agent/skills/chroma/LICENSE +21 -0
  23. package/config/agent/skills/chroma/chroma-local/SKILL.md +165 -0
  24. package/config/agent/skills/chroma/chroma-local/cli.md +48 -0
  25. package/config/agent/skills/chroma/chroma-local/data-model.md +103 -0
  26. package/config/agent/skills/chroma/chroma-local/error-handling/python.md +166 -0
  27. package/config/agent/skills/chroma/chroma-local/error-handling/typescript.md +231 -0
  28. package/config/agent/skills/chroma/chroma-local/local-chroma/python.md +95 -0
  29. package/config/agent/skills/chroma/chroma-local/local-chroma/typescript.md +101 -0
  30. package/config/agent/skills/chroma/chroma-local/metadata/python.md +154 -0
  31. package/config/agent/skills/chroma/chroma-local/metadata/typescript.md +153 -0
  32. package/config/agent/skills/chroma/chroma-local/querying/python.md +147 -0
  33. package/config/agent/skills/chroma/chroma-local/querying/typescript.md +157 -0
  34. package/config/agent/skills/chroma/chroma-local/regex/python.md +69 -0
  35. package/config/agent/skills/chroma/chroma-local/regex/typescript.md +71 -0
  36. package/config/agent/skills/chroma/chroma-local/understanding-a-codebase.md +80 -0
  37. package/config/agent/skills/chroma/chroma-local/updating-deleting/python.md +159 -0
  38. package/config/agent/skills/chroma/chroma-local/updating-deleting/typescript.md +228 -0
  39. package/config/agent/skills/hello/SKILL.md +1 -1
  40. package/config/agent/skills/ponytail/SKILL.md +100 -0
  41. package/config/agent/skills/ponytail-audit/SKILL.md +40 -0
  42. package/config/agent/skills/ponytail-debt/SKILL.md +44 -0
  43. package/config/agent/skills/ponytail-help/SKILL.md +68 -0
  44. package/config/agent/skills/ponytail-review/SKILL.md +56 -0
  45. package/config/agent/skills_bak/milvus-skill/LICENSE +202 -0
  46. package/config/agent/skills_bak/milvus-skill/README.md +37 -0
  47. package/config/agent/skills_bak/milvus-skill/SKILL.md +259 -0
  48. package/config/agent/skills_bak/milvus-skill/references/collection.md +86 -0
  49. package/config/agent/skills_bak/milvus-skill/references/database.md +24 -0
  50. package/config/agent/skills_bak/milvus-skill/references/index.md +69 -0
  51. package/config/agent/skills_bak/milvus-skill/references/partition.md +29 -0
  52. package/config/agent/skills_bak/milvus-skill/references/patterns.md +150 -0
  53. package/config/agent/skills_bak/milvus-skill/references/user-role.md +90 -0
  54. package/config/agent/skills_bak/milvus-skill/references/vector.md +247 -0
  55. package/config/agent/skills_bak/zread/README.md +115 -0
  56. package/config/agent/skills_bak/zread/SKILL.md +103 -0
  57. package/config/agent/skills_bak/zread/references/stdio-protocol.md +312 -0
  58. package/package.json +7 -6
  59. package/scripts/postinstall.js +58 -1
  60. package/config/agent/dangerous-patterns.json +0 -106
  61. package/config/agent/extensions/bash-check.ts +0 -227
  62. package/config/agent/skills/refactor/SKILL.md +0 -40
  63. /package/config/agent/{skills → skills_bak}/csv-data-summarizer/SKILL.md +0 -0
  64. /package/config/agent/{skills → skills_bak}/csv-data-summarizer/analyze.py +0 -0
  65. /package/config/agent/{skills → skills_bak}/csv-data-summarizer/examples/showcase_financial_pl_data.csv +0 -0
  66. /package/config/agent/{skills → skills_bak}/csv-data-summarizer/requirements.txt +0 -0
  67. /package/config/agent/{skills → skills_bak}/csv-data-summarizer/resources/sample.csv +0 -0
  68. /package/config/agent/{skills → skills_bak}/dispatching-parallel-agents/SKILL.md +0 -0
  69. /package/config/agent/{skills → skills_bak}/find-skills/SKILL.md +0 -0
  70. /package/config/agent/{skills → skills_bak}/finishing-a-development-branch/SKILL.md +0 -0
  71. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/LICENSE +0 -0
  72. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/README.md +0 -0
  73. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/README.zh.md +0 -0
  74. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/SKILL.md +0 -0
  75. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/agentloop-core.svg +0 -0
  76. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/agents/openai.yaml +0 -0
  77. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/assets/samples/sample-style1-flat.png +0 -0
  78. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/assets/samples/sample-style2-dark.png +0 -0
  79. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/assets/samples/sample-style3-blueprint.png +0 -0
  80. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/assets/samples/sample-style4-notion.png +0 -0
  81. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/assets/samples/sample-style5-glass.png +0 -0
  82. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/assets/samples/sample-style6-claude.png +0 -0
  83. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/assets/samples/sample-style7-openai.png +0 -0
  84. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/fixtures/agent-memory-types-style4.json +0 -0
  85. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/fixtures/api-flow-style7.json +0 -0
  86. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/fixtures/mem0-style1.json +0 -0
  87. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/fixtures/microservices-style3.json +0 -0
  88. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/fixtures/multi-agent-style5.json +0 -0
  89. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/fixtures/system-architecture-style6.json +0 -0
  90. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/fixtures/tool-call-style2.json +0 -0
  91. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/package.json +0 -0
  92. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/icons.md +0 -0
  93. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-1-flat-icon.md +0 -0
  94. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-2-dark-terminal.md +0 -0
  95. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-3-blueprint.md +0 -0
  96. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-4-notion-clean.md +0 -0
  97. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-5-glassmorphism.md +0 -0
  98. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-6-claude-official.md +0 -0
  99. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-7-openai.md +0 -0
  100. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/style-diagram-matrix.md +0 -0
  101. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/references/svg-layout-best-practices.md +0 -0
  102. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/scripts/README.md +0 -0
  103. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/scripts/generate-diagram.sh +0 -0
  104. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/scripts/generate-from-template.py +0 -0
  105. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/scripts/test-all-styles.sh +0 -0
  106. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/scripts/validate-svg.sh +0 -0
  107. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/agent-architecture.svg +0 -0
  108. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/architecture.svg +0 -0
  109. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/comparison-matrix.svg +0 -0
  110. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/data-flow.svg +0 -0
  111. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/er-diagram.svg +0 -0
  112. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/flowchart.svg +0 -0
  113. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/sequence.svg +0 -0
  114. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/state-machine.svg +0 -0
  115. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/timeline.svg +0 -0
  116. /package/config/agent/{skills → skills_bak}/fireworks-tech-graph/templates/use-case.svg +0 -0
  117. /package/config/agent/{skills → skills_bak}/librarian/SKILL.md +0 -0
  118. /package/config/agent/{skills → skills_bak}/markdown-to-html/SKILL.md +0 -0
  119. /package/config/agent/{skills → skills_bak}/pr/SKILL.md +0 -0
  120. /package/config/agent/{skills → skills_bak}/receiving-code-review/SKILL.md +0 -0
  121. /package/config/agent/{skills → skills_bak}/requesting-code-review/SKILL.md +0 -0
  122. /package/config/agent/{skills → skills_bak}/requesting-code-review/code-reviewer.md +0 -0
  123. /package/config/agent/{skills → skills_bak}/subagent-driven-development/SKILL.md +0 -0
  124. /package/config/agent/{skills → skills_bak}/subagent-driven-development/code-quality-reviewer-prompt.md +0 -0
  125. /package/config/agent/{skills → skills_bak}/subagent-driven-development/implementer-prompt.md +0 -0
  126. /package/config/agent/{skills → skills_bak}/subagent-driven-development/spec-reviewer-prompt.md +0 -0
  127. /package/config/agent/{skills → skills_bak}/systematic-debugging/CREATION-LOG.md +0 -0
  128. /package/config/agent/{skills → skills_bak}/systematic-debugging/SKILL.md +0 -0
  129. /package/config/agent/{skills → skills_bak}/systematic-debugging/condition-based-waiting-example.ts +0 -0
  130. /package/config/agent/{skills → skills_bak}/systematic-debugging/condition-based-waiting.md +0 -0
  131. /package/config/agent/{skills → skills_bak}/systematic-debugging/defense-in-depth.md +0 -0
  132. /package/config/agent/{skills → skills_bak}/systematic-debugging/find-polluter.sh +0 -0
  133. /package/config/agent/{skills → skills_bak}/systematic-debugging/root-cause-tracing.md +0 -0
  134. /package/config/agent/{skills → skills_bak}/systematic-debugging/test-academic.md +0 -0
  135. /package/config/agent/{skills → skills_bak}/systematic-debugging/test-pressure-1.md +0 -0
  136. /package/config/agent/{skills → skills_bak}/systematic-debugging/test-pressure-2.md +0 -0
  137. /package/config/agent/{skills → skills_bak}/systematic-debugging/test-pressure-3.md +0 -0
  138. /package/config/agent/{skills → skills_bak}/test-driven-development/SKILL.md +0 -0
  139. /package/config/agent/{skills → skills_bak}/test-driven-development/testing-anti-patterns.md +0 -0
  140. /package/config/agent/{skills → skills_bak}/unit-test/SKILL.md +0 -0
  141. /package/config/agent/{skills → skills_bak}/using-git-worktrees/SKILL.md +0 -0
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: Chroma Regex Filtering
3
+ description: Learn how to use regex filters in Chroma queries
4
+ ---
5
+
6
+ ## Regex Filtering in Chroma
7
+
8
+ Chroma supports regex filtering on document content. This is useful when you need exact pattern matching that semantic search can't provide.
9
+
10
+ ### When to use regex vs semantic search
11
+
12
+ **Use regex when:**
13
+ - Matching exact patterns like email addresses, URLs, or code identifiers
14
+ - Finding documents containing specific formats (dates, phone numbers, IDs)
15
+ - Filtering by prefixes or suffixes in structured data
16
+ - You need deterministic, repeatable matches
17
+
18
+ **Use semantic search when:**
19
+ - Looking for conceptually similar content regardless of exact wording
20
+ - The user's query is natural language
21
+ - You want to find related content even if it uses different terminology
22
+
23
+ You can combine both: use regex to narrow results, then rank by semantic similarity.
24
+
25
+ ### Imports and boilerplate
26
+
27
+ ```typescript
28
+ import { DefaultEmbeddingFunction } from '@chroma-core/default-embed';
29
+ import { ChromaClient } from 'chromadb';
30
+
31
+ const client = new ChromaClient();
32
+ const embedder = new DefaultEmbeddingFunction();
33
+
34
+ const collection = await client.getOrCreateCollection({
35
+ name: 'example-collection',
36
+ embeddingFunction: embedder,
37
+ });
38
+ ```
39
+
40
+ ### Basic Regex Filter
41
+
42
+ Use the `$regex` operator in `where_document` to match document content against a regular expression. The regex follows standard regex syntax.
43
+
44
+ ```typescript
45
+ await collection.query({
46
+ queryTexts: ['find support tickets with email addresses'],
47
+ whereDocument: {
48
+ $regex: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
49
+ },
50
+ });
51
+ ```
52
+
53
+ ### Combining regex with metadata filters
54
+
55
+ Regex filters can be combined with metadata filters using `$and` and `$or` operators. This is powerful for narrowing results by both content patterns and structured metadata. Note however regex can not be used on metadata string values.
56
+
57
+ ```typescript
58
+ await collection.query({
59
+ queryTexts: ['query1', 'query2'],
60
+ whereDocument: {
61
+ $and: [{ $contains: 'search_string_1' }, { $regex: '[a-z]+' }],
62
+ },
63
+ });
64
+ ```
65
+
66
+ ### Performance considerations
67
+
68
+ Regex filtering happens after the initial vector search retrieves candidates. For best performance:
69
+ - Keep regex patterns simple when possible
70
+ - Use metadata filters to reduce the candidate set before regex matching
71
+ - Consider whether a metadata field with pre-extracted values would be faster than runtime regex
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: Integrating Chroma into an existing system
3
+ description: Guidance for adding Chroma search to an existing application
4
+ ---
5
+
6
+ ## Integrating Chroma into an existing system
7
+
8
+ Adding search to an existing application requires understanding the data flow and planning both the initial import and ongoing synchronization. This guide helps identify the key questions to answer.
9
+
10
+ ### Key questions to ask the user
11
+
12
+ Before writing any code, clarify:
13
+
14
+ 1. **What data should be searchable?** (documents, products, messages, etc.)
15
+ 2. **Where does that data currently live?** (database, S3, API, files)
16
+ 3. **How is the data structured?** (helps determine chunking strategy)
17
+ 4. **How often does the data change?** (informs sync strategy)
18
+ 5. **What latency is acceptable for updates to appear in search?**
19
+
20
+ ## Understanding the source data
21
+
22
+ Before designing the import pipeline, ask the user if you can look at a sample of the data that will be made searchable. Seeing real records is far more useful than a description of the schema.
23
+
24
+ **If the data is in a database:** Write a short script that connects to the database and prints a few records. For example, a script that queries 3-5 rows from the relevant table and prints them to the terminal. This lets you see the actual field names, content lengths, and metadata available.
25
+
26
+ **If the data is on disk:** Read a few of the files directly to understand their structure, format, and size. For example, if indexing markdown files, read 2-3 of them to see how they're organized.
27
+
28
+ What to look for:
29
+ - **Which field(s) contain the searchable text** — this becomes the document content in Chroma
30
+ - **How long the content is** — determines whether chunking is needed
31
+ - **What metadata is available** — fields like category, author, date, or tenant ID that could be useful for filtering
32
+ - **How records are identified** — the primary key or filename that will link Chroma documents back to the source
33
+
34
+ This step prevents guesswork and leads to better chunking and metadata design decisions.
35
+
36
+ ## Initial data import (offline ingest)
37
+
38
+ The first step is getting existing data into Chroma. This typically involves:
39
+
40
+ 1. **Reading from the source** - database queries, S3 listing, API pagination
41
+ 2. **Chunking** - breaking large documents into searchable pieces (see data-model.md)
42
+ 3. **Embedding** - converting text chunks to vectors
43
+ 4. **Writing to Chroma** - batching for efficiency
44
+
45
+ Build this as a reusable pipeline, not a one-off script. The same chunking and embedding logic will be needed for ongoing updates.
46
+
47
+ **Progress tracking:** For large imports, track which records have been processed. This allows resuming after failures and re-running for updates. A simple approach is storing the last processed ID or timestamp.
48
+
49
+ ## Keeping data in sync (online writes)
50
+
51
+ After the initial import, new and updated data must flow to Chroma. There are two main patterns:
52
+
53
+ ### Asynchronous (recommended)
54
+
55
+ Use a message queue (SQS, RabbitMQ, Redis streams, etc.) to decouple the primary write path from Chroma updates:
56
+
57
+ 1. Application writes to primary database
58
+ 2. Application publishes an event with the record ID
59
+ 3. Queue consumer fetches the record, chunks, embeds, and writes to Chroma
60
+
61
+ **Benefits:** Primary writes aren't slowed by embedding latency. Retries are handled by the queue. Search updates can lag slightly without affecting the main application.
62
+
63
+ ### Synchronous
64
+
65
+ If no queue infrastructure exists and slight latency is acceptable, update Chroma in the same request:
66
+
67
+ 1. Application writes to primary database
68
+ 2. Application chunks, embeds, and writes to Chroma
69
+ 3. Request completes
70
+
71
+ **Tradeoffs:** Simpler infrastructure but adds latency to every write. Failures in Chroma can affect the primary write path unless carefully handled.
72
+
73
+ **Ask the user:** Do they have an async queue? If not, is synchronous acceptable, or should we set one up?
74
+
75
+ ## Handling updates and deletes
76
+
77
+ - **Updates:** Re-chunk and re-embed the document, then use `upsert` to replace existing chunks
78
+ - **Deletes:** Delete all chunks for the document by ID prefix or metadata filter
79
+
80
+ Storing the source record ID in chunk metadata makes this straightforward. For example, if a blog post with ID `post-123` has 3 chunks, store `{"source_id": "post-123", "chunk_index": 0}` etc. on each chunk.
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: Updating and Deleting
3
+ description: Update existing documents and delete data from collections
4
+ ---
5
+
6
+ ## Updating and Deleting
7
+
8
+ Chroma provides `update`, `upsert`, and `delete` methods for modifying data after initial insertion. Understanding when to use each is important for building reliable data sync pipelines.
9
+
10
+ ### Method overview
11
+
12
+ | Method | Behavior | Use when |
13
+ |--------|----------|----------|
14
+ | `update` | Modifies existing documents, fails if ID doesn't exist | You know the document exists |
15
+ | `upsert` | Updates if exists, inserts if not | Syncing from external data source |
16
+ | `delete` | Removes documents by ID or filter | Removing stale or unwanted data |
17
+
18
+ ### Imports
19
+
20
+ ```python
21
+ import time
22
+ from typing import TypedDict
23
+
24
+ import chromadb
25
+
26
+ client = chromadb.HttpClient(host="localhost", port=8000)
27
+ ```
28
+
29
+ ## Update
30
+
31
+ Update modifies existing documents. If an ID doesn't exist, the operation fails silently for that ID (no error thrown, but nothing is updated).
32
+
33
+ **Important:** When you update a document's text, Chroma re-computes the embedding automatically using the collection's embedding function.
34
+
35
+ ```python
36
+ collection = client.get_or_create_collection(name="my_collection")
37
+
38
+ collection.add(
39
+ ids=["doc1", "doc2"],
40
+ documents=["Original text for doc1", "Original text for doc2"],
41
+ metadatas=[{"category": "draft"}, {"category": "draft"}],
42
+ )
43
+
44
+ collection.update(
45
+ ids=["doc1"],
46
+ documents=["Updated text for doc1"],
47
+ )
48
+
49
+ collection.update(
50
+ ids=["doc1", "doc2"],
51
+ metadatas=[{"category": "published"}, {"category": "published"}],
52
+ )
53
+
54
+ collection.update(
55
+ ids=["doc2"],
56
+ documents=["Completely revised doc2 content"],
57
+ metadatas=[{"category": "published", "revision": 2}],
58
+ )
59
+ ```
60
+
61
+ ## Upsert
62
+
63
+ Upsert is the preferred method for syncing data from an external source. It inserts new documents and updates existing ones in a single operation.
64
+
65
+ **When to use upsert vs update:**
66
+ - Use `upsert` when syncing from a primary database (you don't know which records are new)
67
+ - Use `update` when you're certain the document already exists
68
+
69
+ ```python
70
+ collection2 = client.get_or_create_collection(name="articles")
71
+
72
+ collection2.upsert(
73
+ ids=["article-123", "article-456", "article-789"],
74
+ documents=[
75
+ "Content of article 123",
76
+ "Content of article 456",
77
+ "Content of article 789",
78
+ ],
79
+ metadatas=[
80
+ {"source_id": "123", "updated_at": int(time.time())},
81
+ {"source_id": "456", "updated_at": int(time.time())},
82
+ {"source_id": "789", "updated_at": int(time.time())},
83
+ ],
84
+ )
85
+
86
+ collection2.upsert(
87
+ ids=["article-123", "article-456"],
88
+ documents=[
89
+ "Updated content of article 123",
90
+ "Updated content of article 456",
91
+ ],
92
+ metadatas=[
93
+ {"source_id": "123", "updated_at": int(time.time())},
94
+ {"source_id": "456", "updated_at": int(time.time())},
95
+ ],
96
+ )
97
+ ```
98
+
99
+ ## Delete by ID
100
+
101
+ The simplest way to delete documents is by their IDs.
102
+
103
+ ```python
104
+ awaiting_cleanup = ["article-789", "article-456"]
105
+ collection2.delete(ids=awaiting_cleanup)
106
+ ```
107
+
108
+ ## Delete by filter
109
+
110
+ Delete documents matching metadata or content filters without knowing specific IDs. Useful for bulk cleanup operations.
111
+
112
+ ```python
113
+ collection2.delete(
114
+ where={"source_id": "123"},
115
+ )
116
+ ```
117
+
118
+ ## Syncing from an external data source
119
+
120
+ A common pattern is keeping Chroma in sync with a primary database. This example shows how to handle creates, updates, and deletes.
121
+
122
+ ```python
123
+ class SourceRecord(TypedDict):
124
+ id: str
125
+ content: str
126
+ deleted: bool
127
+ updated_at: int
128
+
129
+
130
+ def sync_records(records: list[SourceRecord]) -> None:
131
+ active_records = [record for record in records if not record["deleted"]]
132
+ deleted_ids = [record["id"] for record in records if record["deleted"]]
133
+
134
+ if active_records:
135
+ collection2.upsert(
136
+ ids=[record["id"] for record in active_records],
137
+ documents=[record["content"] for record in active_records],
138
+ metadatas=[
139
+ {
140
+ "source_id": record["id"],
141
+ "updated_at": record["updated_at"],
142
+ }
143
+ for record in active_records
144
+ ],
145
+ )
146
+
147
+ if deleted_ids:
148
+ collection2.delete(ids=deleted_ids)
149
+ ```
150
+
151
+ ### Sync strategy tips
152
+
153
+ **Track source IDs:** Always store the primary database ID in metadata so you can find and update documents later.
154
+
155
+ **Batch operations:** Process updates in batches of 100-500 to balance throughput and memory usage.
156
+
157
+ **Handle deletes:** When records are deleted from your primary database, delete them from Chroma too. Use metadata filters if you track `source_id`.
158
+
159
+ **Idempotent syncs:** Use `upsert` so re-running a sync doesn't create duplicates.
@@ -0,0 +1,228 @@
1
+ ---
2
+ name: Updating and Deleting
3
+ description: Update existing documents and delete data from collections
4
+ ---
5
+
6
+ ## Updating and Deleting
7
+
8
+ Chroma provides `update`, `upsert`, and `delete` methods for modifying data after initial insertion. Understanding when to use each is important for building reliable data sync pipelines.
9
+
10
+ ### Method overview
11
+
12
+ | Method | Behavior | Use when |
13
+ |--------|----------|----------|
14
+ | `update` | Modifies existing documents, fails if ID doesn't exist | You know the document exists |
15
+ | `upsert` | Updates if exists, inserts if not | Syncing from external data source |
16
+ | `delete` | Removes documents by ID or filter | Removing stale or unwanted data |
17
+
18
+ ### Imports
19
+
20
+ ```typescript
21
+ import { ChromaClient } from 'chromadb';
22
+ import { DefaultEmbeddingFunction } from '@chroma-core/default-embed';
23
+
24
+ const client = new ChromaClient();
25
+ const embeddingFunction = new DefaultEmbeddingFunction();
26
+ ```
27
+
28
+ ## Update
29
+
30
+ Update modifies existing documents. If an ID doesn't exist, the operation fails silently for that ID (no error thrown, but nothing is updated).
31
+
32
+ **Important:** When you update a document's text, Chroma re-computes the embedding automatically using the collection's embedding function.
33
+
34
+ ```typescript
35
+ const collection = await client.getOrCreateCollection({
36
+ name: 'my_collection',
37
+ embeddingFunction,
38
+ });
39
+
40
+ await collection.add({
41
+ ids: ['doc1', 'doc2'],
42
+ documents: ['Original text for doc1', 'Original text for doc2'],
43
+ metadatas: [{ category: 'draft' }, { category: 'draft' }],
44
+ });
45
+
46
+ await collection.update({
47
+ ids: ['doc1'],
48
+ documents: ['Updated text for doc1'],
49
+ });
50
+
51
+ await collection.update({
52
+ ids: ['doc1', 'doc2'],
53
+ metadatas: [{ category: 'published' }, { category: 'published' }],
54
+ });
55
+
56
+ await collection.update({
57
+ ids: ['doc2'],
58
+ documents: ['Completely revised doc2 content'],
59
+ metadatas: [{ category: 'published', revision: 2 }],
60
+ });
61
+ ```
62
+
63
+ ## Upsert
64
+
65
+ Upsert is the preferred method for syncing data from an external source. It inserts new documents and updates existing ones in a single operation.
66
+
67
+ **When to use upsert vs update:**
68
+ - Use `upsert` when syncing from a primary database (you don't know which records are new)
69
+ - Use `update` when you're certain the document already exists
70
+
71
+ ```typescript
72
+ const collection2 = await client.getOrCreateCollection({
73
+ name: 'articles',
74
+ embeddingFunction,
75
+ });
76
+
77
+ await collection2.upsert({
78
+ ids: ['article-123', 'article-456', 'article-789'],
79
+ documents: [
80
+ 'Content of article 123',
81
+ 'Content of article 456',
82
+ 'Content of article 789',
83
+ ],
84
+ metadatas: [
85
+ { source_id: '123', updated_at: Date.now() },
86
+ { source_id: '456', updated_at: Date.now() },
87
+ { source_id: '789', updated_at: Date.now() },
88
+ ],
89
+ });
90
+
91
+ await collection2.upsert({
92
+ ids: ['article-123', 'article-456'],
93
+ documents: [
94
+ 'Updated content of article 123',
95
+ 'Updated content of article 456',
96
+ ],
97
+ metadatas: [
98
+ { source_id: '123', updated_at: Date.now() },
99
+ { source_id: '456', updated_at: Date.now() },
100
+ ],
101
+ });
102
+ ```
103
+
104
+ ## Delete by ID
105
+
106
+ The simplest way to delete documents is by their IDs.
107
+
108
+ ```typescript
109
+ const collection3 = await client.getOrCreateCollection({
110
+ name: 'my_collection',
111
+ embeddingFunction,
112
+ });
113
+
114
+ await collection3.delete({
115
+ ids: ['doc1', 'doc2'],
116
+ });
117
+
118
+ await collection3.delete({
119
+ ids: ['doc3'],
120
+ });
121
+ ```
122
+
123
+ ## Delete by filter
124
+
125
+ Delete documents matching metadata or content filters without knowing specific IDs. Useful for bulk cleanup operations.
126
+
127
+ ```typescript
128
+ const collection4 = await client.getOrCreateCollection({
129
+ name: 'my_collection',
130
+ embeddingFunction,
131
+ });
132
+
133
+ await collection4.delete({
134
+ where: { status: 'archived' },
135
+ });
136
+
137
+ await collection4.delete({
138
+ where: { source_id: 'old-source-123' },
139
+ });
140
+
141
+ await collection4.delete({
142
+ whereDocument: { $contains: 'DEPRECATED' },
143
+ });
144
+
145
+ await collection4.delete({
146
+ ids: ['doc1', 'doc2', 'doc3', 'doc4'],
147
+ where: { category: 'temp' },
148
+ });
149
+ ```
150
+
151
+ ## Syncing from an external data source
152
+
153
+ A common pattern is keeping Chroma in sync with a primary database. This example shows how to handle creates, updates, and deletes.
154
+
155
+ ```typescript
156
+ interface SourceRecord {
157
+ id: string;
158
+ content: string;
159
+ updated_at: number;
160
+ category: string;
161
+ }
162
+
163
+ async function syncToChroma(
164
+ collectionName: string,
165
+ records: SourceRecord[],
166
+ deletedIds: string[]
167
+ ) {
168
+ const collection = await client.getOrCreateCollection({
169
+ name: collectionName,
170
+ embeddingFunction,
171
+ });
172
+
173
+ if (records.length > 0) {
174
+ const batchSize = 100;
175
+
176
+ for (let i = 0; i < records.length; i += batchSize) {
177
+ const batch = records.slice(i, i + batchSize);
178
+
179
+ await collection.upsert({
180
+ ids: batch.map((record) => `source-${record.id}`),
181
+ documents: batch.map((record) => record.content),
182
+ metadatas: batch.map((record) => ({
183
+ source_id: record.id,
184
+ updated_at: record.updated_at,
185
+ category: record.category,
186
+ })),
187
+ });
188
+ }
189
+ }
190
+
191
+ if (deletedIds.length > 0) {
192
+ await collection.delete({
193
+ ids: deletedIds.map((id) => `source-${id}`),
194
+ });
195
+ }
196
+
197
+ return { synced: records.length, deleted: deletedIds.length };
198
+ }
199
+
200
+ const changedRecords: SourceRecord[] = [
201
+ {
202
+ id: '1',
203
+ content: 'Article about TypeScript',
204
+ updated_at: Date.now(),
205
+ category: 'tech',
206
+ },
207
+ {
208
+ id: '2',
209
+ content: 'Guide to vector databases',
210
+ updated_at: Date.now(),
211
+ category: 'tech',
212
+ },
213
+ ];
214
+
215
+ const deletedRecordIds = ['old-1', 'old-2'];
216
+
217
+ await syncToChroma('articles', changedRecords, deletedRecordIds);
218
+ ```
219
+
220
+ ### Sync strategy tips
221
+
222
+ **Track source IDs:** Always store the primary database ID in metadata so you can find and update documents later.
223
+
224
+ **Batch operations:** Process updates in batches of 100-500 to balance throughput and memory usage.
225
+
226
+ **Handle deletes:** When records are deleted from your primary database, delete them from Chroma too. Use metadata filters if you track `source_id`.
227
+
228
+ **Idempotent syncs:** Use `upsert` so re-running a sync doesn't create duplicates.
@@ -1,4 +1,4 @@
1
- ---
1
+ ---
2
2
  name: hello
3
3
  description: "Custom skill example. Use when testing skill functionality or as a template for creating new skills."
4
4
  disable-model-invocation: true
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: ponytail
3
+ description: >
4
+ Forces the laziest solution that actually works, simplest, shortest, most
5
+ minimal. Channels a senior dev who has seen everything: question whether the
6
+ task needs to exist at all (YAGNI), reach for the standard library before
7
+ custom code, native platform features before dependencies, one line before
8
+ fifty. Supports intensity levels: lite, full (default), ultra. Use whenever
9
+ the user says "ponytail", "be lazy", "lazy mode", "simplest solution",
10
+ "minimal solution", "yagni", "do less", or "shortest path", and whenever
11
+ they complain about over-engineering, bloat, boilerplate, or unnecessary
12
+ dependencies.
13
+ license: MIT
14
+ ---
15
+
16
+ # Ponytail
17
+
18
+ You are a lazy senior developer. Lazy means efficient, not careless. You have
19
+ seen every over-engineered codebase and been paged at 3am for one. The best
20
+ code is the code never written.
21
+
22
+ ## Persistence
23
+
24
+ ACTIVE EVERY RESPONSE. No drift back to over-building. Still active if
25
+ unsure. Off only: "stop ponytail" / "normal mode". Default: **full**.
26
+ Switch: `/ponytail lite|full|ultra`.
27
+
28
+ ## The ladder
29
+
30
+ Stop at the first rung that holds:
31
+
32
+ 1. **Does this need to exist at all?** Speculative need = skip it, say so in one line. (YAGNI)
33
+ 2. **Stdlib does it?** Use it.
34
+ 3. **Native platform feature covers it?** `<input type="date">` over a picker lib, CSS over JS, DB constraint over app code.
35
+ 4. **Already-installed dependency solves it?** Use it. Never add a new one for what a few lines can do.
36
+ 5. **Can it be one line?** One line.
37
+ 6. **Only then:** the minimum code that works.
38
+
39
+ The ladder is a reflex, not a research project. Two rungs work → take the
40
+ higher one and move on. The first lazy solution that works is the right one.
41
+
42
+ ## Rules
43
+
44
+ - No unrequested abstractions: no interface with one implementation, no factory for one product, no config for a value that never changes.
45
+ - No boilerplate, no scaffolding "for later", later can scaffold for itself.
46
+ - Deletion over addition. Boring over clever, clever is what someone decodes at 3am.
47
+ - Fewest files possible. Shortest working diff wins.
48
+ - Complex request? Ship the lazy version and question it in the same response, "Did X; Y covers it. Need full X? Say so." Never stall on an answer you can default.
49
+ - Two stdlib options, same size? Take the one that's correct on edge cases. Lazy means writing less code, not picking the flimsier algorithm.
50
+ - Mark deliberate simplifications with a `ponytail:` comment (`// ponytail: this exists`), simple reads as intent, not ignorance. Shortcut with a known ceiling (global lock, O(n²) scan, naive heuristic)? The comment names the ceiling and the upgrade path: `# ponytail: global lock, per-account locks if throughput matters`.
51
+
52
+ ## Output
53
+
54
+ Code first. Then at most three short lines: what was skipped, when to add it.
55
+ No essays, no feature tours, no design notes. If the explanation is longer
56
+ than the code, delete the explanation, every paragraph defending a
57
+ simplification is complexity smuggled back in as prose. Explanation the user
58
+ explicitly asked for (a report, a walkthrough, per-phase notes) is not debt,
59
+ give it in full, the rule is only against unrequested prose.
60
+
61
+ Pattern: `[code] → skipped: [X], add when [Y].`
62
+
63
+ ## Intensity
64
+
65
+ | Level | What change |
66
+ |-------|------------|
67
+ | **lite** | Build what's asked, but name the lazier alternative in one line. User picks. |
68
+ | **full** | The ladder enforced. Stdlib and native first. Shortest diff, shortest explanation. Default. |
69
+ | **ultra** | YAGNI extremist. Deletion before addition. Ship the one-liner and challenge the rest of the requirement in the same breath. |
70
+
71
+ Example: "Add a cache for these API responses."
72
+ - lite: "Done, cache added. FYI: `functools.lru_cache` covers this in one line if you'd rather not own a cache class."
73
+ - full: "`@lru_cache(maxsize=1000)` on the fetch function. Skipped custom cache class, add when lru_cache measurably falls short."
74
+ - ultra: "No cache until a profiler says so. When it does: `@lru_cache`. A hand-rolled TTL cache class is a bug farm with a hit rate."
75
+
76
+ ## When NOT to be lazy
77
+
78
+ Never simplify away: input validation at trust boundaries, error handling
79
+ that prevents data loss, security measures, accessibility basics, anything
80
+ explicitly requested. User insists on the full version → build it, no
81
+ re-arguing.
82
+
83
+ Hardware is never the ideal on paper: a real clock drifts, a real sensor
84
+ reads off, a PCA9685 runs a few percent fast. Leave the calibration knob, not
85
+ just less code, the physical world needs tuning a minimal model can't see.
86
+
87
+ Lazy code without its check is unfinished. Non-trivial logic (a branch, a
88
+ loop, a parser, a money/security path) leaves ONE runnable check behind, the
89
+ smallest thing that fails if the logic breaks: an `assert`-based
90
+ `demo()`/`__main__` self-check or one small `test_*.py`. No frameworks, no
91
+ fixtures, no per-function suites unless asked. Trivial one-liners need no
92
+ test, YAGNI applies to tests too.
93
+
94
+ ## Boundaries
95
+
96
+ Ponytail governs what you build, not how you talk (pair with Caveman for
97
+ terse prose). "stop ponytail" / "normal mode": revert. Level persists until
98
+ changed or session end.
99
+
100
+ The shortest path to done is the right path.
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: ponytail-audit
3
+ description: >
4
+ Whole-repo audit for over-engineering. Like ponytail-review, but scans the
5
+ entire codebase instead of a diff: a ranked list of what to delete, simplify,
6
+ or replace with stdlib/native equivalents. Use when the user says "audit this
7
+ codebase", "audit for over-engineering", "what can I delete from this repo",
8
+ "find bloat", "ponytail-audit", or "/ponytail-audit". One-shot report, does
9
+ not apply fixes.
10
+ ---
11
+
12
+ ponytail-review, repo-wide. Scan the whole tree instead of a diff. Rank
13
+ findings biggest cut first.
14
+
15
+ ## Tags
16
+
17
+ Same as ponytail-review:
18
+
19
+ - `delete:` dead code, unused flexibility, speculative feature. Replacement: nothing.
20
+ - `stdlib:` hand-rolled thing the standard library ships. Name the function.
21
+ - `native:` dependency or code doing what the platform already does. Name the feature.
22
+ - `yagni:` abstraction with one implementation, config nobody sets, layer with one caller.
23
+ - `shrink:` same logic, fewer lines. Show the shorter form.
24
+
25
+ ## Hunt
26
+
27
+ Deps the stdlib or platform already ships, single-implementation interfaces,
28
+ factories with one product, wrappers that only delegate, files exporting one
29
+ thing, dead flags and config, hand-rolled stdlib.
30
+
31
+ ## Output
32
+
33
+ One line per finding, ranked: `<tag> <what to cut>. <replacement>. [path]`.
34
+ End with `net: -<N> lines, -<M> deps possible.` Nothing to cut: `Lean already. Ship.`
35
+
36
+ ## Boundaries
37
+
38
+ Complexity only, correctness bugs, security holes, and performance go to a
39
+ normal review pass. Lists findings, applies nothing. One-shot.
40
+ "stop ponytail-audit" or "normal mode" to revert.